android - 屏幕关闭时从 BroadcastReceiver 打开 Activity
问题描述
当应用程序正在运行并且设备被锁定时,我可以开始活动。但是,当应用程序处于后台并且设备被锁定时,即使我在 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) && setTurnScreenOn(true)
即使设备被锁定,也有助于打开应用程序,但应用程序必须在前台。
PS:我在所有情况下都在 BroadcastReceiver 中获得控制权。
TIA
解决方案
我正在检查从设置中授予 Skype 的不同权限,并注意到“在锁定屏幕上显示”已启用,而我的应用程序已禁用相同权限。启用后,BroadcastReceiver 能够在所有场景中打开 Activity。我读到这是 Xiamoi 设备的问题(我使用的是 Note 5 Pro)。
编辑
对于 Android 10 需要USE_FULL_SCREEN_INTENT
在清单中添加权限。然后当屏幕被锁定时,设置为FullScreenIntent
on的 PendingIntentNotificationCompat.Builder
将被调用。
我的通知代码:
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);
}
推荐阅读
- javascript - 我如何确定我点击了哪个框?
- c# - 我需要阅读 pdf 内容,因为它在 pdf 中作为 c# 表
- spring-boot - 不正确的 HTML 呈现
- django - 在 django 模板中为变量嵌套 for 循环
- sql-server-2012 - 如何从数据库中选择 3 种流行的销售产品?
- c++ - 无法使用带有 const 引用的 lambda 对 std::vector 进行排序
- arrays - 如何将字节数组拆分为 4 个字节并将结果转换为浮点数?
- visual-studio-code - TS-开玩笑;如何删除 linter 错误?
- ruby-on-rails - 从 Mac/Windows 移动更新文件的最佳方法是什么
- optimization - 如何避免 SFTP 上的重复文件处理