Android的简单闹钟应用 10. 如何通过服务点亮屏幕

Simple alarm app for Android 10. How to turn on screen by service

我正在尝试为 Android 10 创建一个简单的闹钟应用程序。

我使用警报管理器并启动前台服务,并通过未决意图通知。它工作正常,但是 Android 10 不可能从后台服务启动 activity。

我知道如何通过 activity 唤醒和打开屏幕,但不知道如何通过服务和通知(屏幕保持关闭)执行此操作。

有没有办法以编程方式打开屏幕?

我的设备是华为 HRY-LX1T (Android 10).

if( Build.VERSION.SDK_INT >= 26) {
    NotificationChannel channel = new NotificationChannel( CHANNEL_ID, "Alarm", NotificationManager.IMPORTANCE_HIGH);
    ((NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
    Notification notification = new Notification.Builder(this, CHANNEL_ID)
            .setSmallIcon( R.drawable.ic_launcher_foreground )
            .setContentIntent( PendingIntent.getActivity( this, 0, new Intent( this, Main.class).addFlags( Intent.FLAG_ACTIVITY_NEW_TASK ), 0) )
            .setContentTitle( getString(R.string.alarm))
            .setContentText("Test").build();
    startForeground(1, notification);
}

如果应用程序具有 SYSTEM_ALERT_WINDOW window 权限,您可以从前台服务启动 activity,除非您正在为 Android Go.[=17= 开发]

声明 SYSTEM_ALERT_WINDOW 权限并将 showWhenLockedturnScreenOn 标记添加到 Activity =46=].

showWhenLocked 允许 Activity 在锁定屏幕上显示,并且 turnScreenOn 在 Activity 恢复。

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

...

<activity 
   android:name=".YourActivity" 
   android:showWhenLocked="true" 
   android:turnScreenOn="true" />

然后,像往常一样启动 Activity,即:

val intent = ...
startActivity(intent)

如果您还想保持屏幕打开,您可以在 Activity 的布局中声明一个 wake lock

<ContraintLayout 
...
   android:keepScreenOn="true" >
...
</ConstraintLayout>

请注意,用户需要授予应用程序'Display over other apps'特殊权限。,否则Activity将无法启动。

作为 Android Go 的替代方案,您可以从您的服务中获取唤醒锁,但 API 已被 弃用 一段时间。

val pm = (getSystemService(Context.POWER_SERVICE) as PowerManager)
val levelAndFlags = PowerManager.FULL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP
val wakeLock = pm.newWakeLock(levelAndFlags, "MyApp::MyWakelockTag")

wakeLock.acquire()
//... do stuff
wakeLock.release()

为此,您需要在清单中请求 WAKE_LOCK 权限。

<uses-permission android:name="android.permission.WAKE_LOCK"/>