我使用android 10[android Q,Galaxy10],
我使用android studio 3.3,
使用AVD,并制作了一个API29[Android10]虚拟手机。
在虚拟机上,我执行我的应用程序,之后,我启动其他应用程序,如日历,计算器。所以我的应用程序activity进入后台模式。
当我在BroadcastReceiver收到消息时。我叫StartActivity。
在这里,代码-->;公共类myReceiver扩展了
public void onReceive(Context context, Intent intent)
{
Intent intentRun = new Intent(context, LoginSuccess.class);
intentRun.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intentRun);
}
但LoginSuccess activity不出现。“当我的app处于后台模式时”
使用相同的代码,当我的应用程序处于前台模式时,LoginSuccess activity显示得非常好。
调用堆栈捕获映像
上图显示了在我在广播接收器中调用startActivity之前的调用堆栈。
我已经阅读了android 10后台activity问题的指导线。“developer.android.com/~~一些位置”
在引导线上,
我开始知道,如果activity存在于调用堆栈中,它甚至可以在后台模式下启动。
上面的代码,它试图启动最近调用堆栈中存在的activity。
为什么startActivity调用在后台模式下失败?“也许没失败,但反正没激活到前台”
使用Android Q,如果你的应用程序不包括下面链接中列出的那些例外情况,就不可能自动从后台启动activity。
https://developer.android.com/guide/components/activities/background-启动
可能的解决方案:
1-您可以选择“只显示服务通知”,然后单击“开始挂起意图”
2-你可以使用全屏意图,立即显示你的意图,如另一个答案所示,谷歌建议。
对于全屏意图解决方案,正如官方文档中所描述的“当用户正在使用设备时,系统UI可能选择显示抬头通知,而不是启动此意图。”
3-要在后台自动启动activity,我认为最可能的解决方案是在清单文件中添加“system_alert_window”。并在应用程序第一次打开时征求用户许可一次。(用户可以手动授予此权限-(设置-应用程序-您的应用程序-高级-绘制其他应用程序))
请求权限的示例代码:
清单中:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
应用程序中的某个地方:
public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE= 2323;
private void RequestPermission() {
// Check if Android M or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Show alert dialog to the user saying a separate permission is needed
// Launch the settings activity if the user prefers
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getActivity().getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(getContext())) {
PermissionDenied();
}
else
{
// Permission Granted-System will work
}
}
}
}
我用下面的逻辑打开activity。就像谷歌一样,博客说如果你想在android 10或更高版本的后台服务中打开activity的使用通知。
清单中:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
示例:
private void startActivity() {
Uri sound = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.siren);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
AudioAttributes attributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ALARM)
.build();
String CHANNEL_ID = BuildConfig.APPLICATION_ID.concat("_notification_id");
String CHANNEL_NAME = BuildConfig.APPLICATION_ID.concat("_notification_name");
assert notificationManager != null;
NotificationChannel mChannel = notificationManager.getNotificationChannel(CHANNEL_ID);
if (mChannel == null) {
mChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
mChannel.setSound(sound, attributes);
notificationManager.createNotificationChannel(mChannel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setSmallIcon(R.drawable.logo)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.login))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setFullScreenIntent(openScreen(Constants.NOTIFICATION_ID), true)
.setAutoCancel(true)
.setOngoing(true);
Notification notification = builder.build();
notificationManager.notify(Constants.NOTIFICATION_ID, notification);
} else {
startActivity(new Intent(BackgroundService.this, LoginActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
}
private PendingIntent openScreen(int notificationId) {
Intent fullScreenIntent = new Intent(this, LoginActivity.class);
fullScreenIntent.putExtra(Constants.NOTIFICATION_IDS, notificationId);
return PendingIntent.getActivity(this, 0, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}