全屏意图不显示在锁定屏幕上

Full screen intent doesn't display on lock screen

所以在我的应用程序中,当时间到了时,我想启动一个 activity 来通知用户,然后让他们关闭闹钟。

我尝试通过安排一个确切的警报,然后从我的 AlarmReceiver onReceive() 启动一个具有全屏意图的高优先级通知来实现它。问题是 activity 在屏幕锁定时不会启动,我收到的只是一个提示通知,它甚至没有打开屏幕,也没有振动。它没有在我的 phone(带有 Android 7.1.2 的小米 X4)上启动,但它在我试过的另一个 phone 上启动(带有 Android 6 的三星 Galaxy A5)。我知道这可以在我的 phone 上实现,因为我观察到时钟、phone、whatsapp 等其他应用程序也可以做到这一点。

Androidmanifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app">

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.App">
        <activity
            android:taskAffinity=""
            android:launchMode="singleInstance"
            android:showForAllUsers="true"
            android:excludeFromRecents="true"
            android:name=".TimeIsUpActivity" />


        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:showOnLockScreen="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".AlarmReceiver"
            android:enabled="true" />
    </application>

</manifest>

我是这样设置闹钟的:

        val alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
            PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        }

        val seconds = 5

        alarmMgr.setExactAndAllowWhileIdle(
            AlarmManager.ELAPSED_REALTIME_WAKEUP,
            SystemClock.elapsedRealtime() + seconds*1000,
            alarmIntent
        )

我的闹钟接收者:

class AlarmReceiver: BroadcastReceiver(){
    override fun onReceive(context: Context?, intent: Intent?) {
        context?.apply {
            val fullScreenIntent = Intent(this, TimeIsUpActivity::class.java)
            fullScreenIntent.flags =
                Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK or
                    Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS or Intent.FLAG_ACTIVITY_NO_USER_ACTION

            val fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
                fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT)

            val builder = NotificationCompat.Builder(this, getString(R.string.channel_id))
                .setContentTitle("Time is up")
                .setContentText("Tap to dismiss")
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .setContentIntent(fullScreenPendingIntent)
                .setSmallIcon(R.drawable.ic_add)
                .setVibrate(longArrayOf(1000, 1000, 1000, 1000, 1000))
                .setOngoing(true)
                .setLights(0xFFFFFF, 1000, 1000)
                .setCategory(NotificationCompat.CATEGORY_ALARM)
                .setPriority(NotificationCompat.PRIORITY_MAX)
                .setFullScreenIntent(fullScreenPendingIntent, true)


            val notificationId = Random().nextInt()
            val notification = builder.build()

            with(NotificationManagerCompat.from(this)) {
                notify(notificationId, notification)
            }
        }
    }
}

我正在尝试启动的activity:

class TimeIsUpActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        turnScreenOnAndKeyguardOff()
        setContentView(R.layout.activity_time_is_up)
    }

    private fun turnScreenOnAndKeyguardOff() {
        if (Build.VERSION.SDK_INT >= 27) {
            setShowWhenLocked(true)
            setTurnScreenOn(true)
            (getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager).also {
                it.requestDismissKeyguard(this, null)
            }
        }

        window.addFlags(
            WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
                    WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON or
                    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
                    WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
    }
}

请帮帮我

我认为你是因为 Appear on top。如果您的应用程序无权显示在顶部,则您必须向用户询问。所以你必须添加这样的东西:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val requestIntent = Intent(
            Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
            Uri.parse("package:${activity.packageName}")
        )
        startActivityForResult(requestIntent, REQUEST_APPEAR_ON_TOP)
        
    }

我发现这是因为小米设备默认不允许应用程序在锁屏上显示。要允许它,必须转到设置 -> 权限 -> 其他权限 -> 找到你的应用程序 -> 检查“在锁定屏幕上显示”。在较新的设备上可能会有所不同。