屏幕关闭时从 BroadcastReceiver 打开 Activity

Posted

技术标签:

【中文标题】屏幕关闭时从 BroadcastReceiver 打开 Activity【英文标题】:Open Activity from BroadcastReceiver when screen off 【发布时间】:2020-04-12 16:48:20 【问题描述】:

当应用程序正在运行并且设备被锁定时,我可以开始活动。但是,当应用程序处于后台并且设备被锁定时,即使我在 BroadcastReceiver 类中获得了控制权,也无法启动活动。这是我的意图调用。

context.startActivity(new Intent(context, ReceiveCallActivity.class)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .setAction(Intent.ACTION_ANSWER)
                    .putExtra("title", intent.getStringExtra("title"))
                    .putExtra("action", intent.getStringExtra("action")));

活动清单

<activity
            android:name=".ReceiveCallActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:excludeFromRecents="true"
            android:launchMode="singleTop"
            android:showOnLockScreen="true"
            android:showWhenLocked="true"
            android:turnScreenOn="true"
            android:windowSoftInputMode="adjustPan|stateHidden" />

ReceiveCallActivity.class

 @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) 
            setShowWhenLocked(true);
            setTurnScreenOn(true);
         else 
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
        
        setContentView(R.layout.receive_call_activity);
        ...
        ...

setShowWhenLocked(true) &amp;&amp; setTurnScreenOn(true) 有助于打开应用程序,即使设备被锁定,但应用程序必须在前台。

PS:我在所有情况下都在 BroadcastReceiver 中获得控制权。

TIA

【问题讨论】:

不,你不能那样做。您可以在 ReceiveCallActivity 中运行的代码做一件事,您可以在 BroadcastReceiver 中调用它。 ReceiveCallActivity 是一个带有 UI 的呼叫应答拒绝屏幕。顺便说一句,Skype 应用程序在所有情况下收到呼叫时都会打开。 @Shahal, 1. 您正在尝试哪个版本 2. Android 10 Restricted background activity 我正在检查从设置中授予 Skype 的不同权限,并注意到“在锁定屏幕上显示”已启用,而我的应用程序已禁用相同权限。启用后,BroadcastReceiver 能够在所有场景中打开 Activity。我读到这是 Xiamoi 设备的问题(我使用的是 Note 5 Pro)。 在 Android 10 上,当应用程序处于后台时,我使用 RemoteViews 显示通知。 【参考方案1】:

我正在检查从设置中授予 Skype 的不同权限,并注意到“在锁定屏幕上显示”已启用,而我的应用程序已禁用相同权限。启用后,BroadcastReceiver 能够在所有场景中打开 Activity。我读到这是 Xiamoi 设备的问题(我使用的是 Note 5 Pro)。

编辑

对于 Android 10 需要在 manifest 中添加 USE_FULL_SCREEN_INTENT 权限。 那么当屏幕被锁定时,在NotificationCompat.Builder上设置为FullScreenIntent的PendingIntent会被调用。

我的通知代码:

private void showCallNotification(Map<String, String> dataMap) 

//CREATING pendingIntent
...
...
...

        PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 2, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent cancelPendingIntent = PendingIntent.getBroadcast(this, 1, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        RemoteViews notificationLayout = new RemoteViews(getPackageName(), R.layout.notification_small);
        notificationLayout.setTextViewText(R.id.tvTitle, dataMap.get("sender"));
        notificationLayout.setTextViewText(R.id.tvContent, getString(R.string.incoming_call));
        notificationLayout.setOnClickPendingIntent(R.id.tvAccept, pendingIntent);
        notificationLayout.setOnClickPendingIntent(R.id.tvDecline, cancelPendingIntent);

        RemoteViews notificationLayoutExpanded = new RemoteViews(getPackageName(), R.layout.notification_large);
        notificationLayoutExpanded.setTextViewText(R.id.tvTitle, dataMap.get("sender"));
        notificationLayoutExpanded.setTextViewText(R.id.tvContent, getString(R.string.incoming_call));
        notificationLayoutExpanded.setOnClickPendingIntent(R.id.btAccept, pendingIntent);
        notificationLayoutExpanded.setOnClickPendingIntent(R.id.btDecline, cancelPendingIntent);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, AppConstants.CALL_CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentTitle(dataMap.get("sender"))
                .setContentText(getString(R.string.incoming_call))
                .setAutoCancel(true)
                .setTimeoutAfter(CALL_DISMISS_TIME)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .setCustomBigContentView(notificationLayout)
                .setCustomContentView(notificationLayoutExpanded)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setContentIntent(fullScreenPendingIntent)
                .setFullScreenIntent(fullScreenPendingIntent, true);

        if (Build.VERSION.SDK_INT < 26) 
            builder.setPriority(NotificationCompat.PRIORITY_MAX);
        

        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 
            createCallNotificationChannel();
        

        notificationManager.notify(notificationId, builder.build());

我这样称呼它

onMessageReceived()

if (Build.VERSION.SDK_INT > 28) 
   if (isAppOnForeground(getApplicationContext())) 
       sendBroadcast(remoteMessage);
    else 
       showCallNotification(dataMap);
   
 else 
   sendBroadcast(remoteMessage);

【讨论】:

应该是评论 这不是答案 @RakeshKumar 真的很抱歉。你是对的,这在 Android 10 中没有帮助,但在这之后它可以工作。

以上是关于屏幕关闭时从 BroadcastReceiver 打开 Activity的主要内容,如果未能解决你的问题,请参考以下文章

主屏幕小部件 BroadcastReceiver 可以监听电话事件吗?

设备屏幕关闭时如何打开手电筒?

屏幕关闭时 Android 通知不起作用

在Android中锁定屏幕时未调用BroadcastReceiver

当视频从所有屏幕完成时自动关闭 AVPlayer

可以在 iPhone 设备屏幕关闭模式下录制视频吗?