无法从 Android 10 上的 BroadcastReceiver 开始活动
Posted
技术标签:
【中文标题】无法从 Android 10 上的 BroadcastReceiver 开始活动【英文标题】:Can't start activity from BroadcastReceiver on android 10 【发布时间】:2020-01-09 23:49:29 【问题描述】:我昨晚将我的操作系统版本更新为 android 10,从那时起广播接收器内的 startActivity 函数什么也没做。这就是我尝试根据 CommonsWare 的回答开始活动的方式:
Intent i = new Intent(context, AlarmNotificationActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) // This is at least android 10...
Log.d("Debug", "This is android 10");
// Start the alert via full-screen intent.
PendingIntent startAlarmPendingIntent = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
String CHANNEL_ID = "my_channel_02";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
context.getString(R.string.notification_channel_name_second),
NotificationManager.IMPORTANCE_HIGH);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setContentTitle("Um, hi!")
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setFullScreenIntent(startAlarmPendingIntent, true);
Log.d("Debug", "Try to load screen");
notificationManager.notify(0, builder.build());
日志显示我正在执行通知命令,但没有任何反应。我要求清单上的 USE_FULL_SCREEN_INTENT 权限,所以我应该能够使用全屏意图。 由于这个问题,我的应用程序现在没用了。有谁知道如何解决它?
【问题讨论】:
【参考方案1】:Android 10 对后台活动启动的限制大约在六个月前宣布。您可以在the documentation 阅读更多相关信息。
改为使用高优先级通知,并带有关联的全屏Intent
。见the documentation。 This sample app 演示了这一点,通过使用 WorkManager
触发需要提醒用户的后台事件。在那里,我使用高优先级通知而不是直接启动活动:
val pi = PendingIntent.getActivity(
appContext,
0,
Intent(appContext, MainActivity::class.java),
PendingIntent.FLAG_UPDATE_CURRENT
)
val builder = NotificationCompat.Builder(appContext, CHANNEL_WHATEVER)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("Um, hi!")
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setFullScreenIntent(pi, true)
val mgr = appContext.getSystemService(NotificationManager::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
&& mgr.getNotificationChannel(CHANNEL_WHATEVER) == null
)
mgr.createNotificationChannel(
NotificationChannel(
CHANNEL_WHATEVER,
"Whatever",
NotificationManager.IMPORTANCE_HIGH
)
)
mgr.notify(NOTIF_ID, builder.build())
【讨论】:
@SimpleUXApps:如果您尝试启动活动,请不要使用PendingIntent.getBroadcast()
。使用PendingIntent.getActivity()
。
@steller:“我正在制作一个闹钟应用程序,我需要显示一个闹钟屏幕”——闹钟应用程序多年来一直使用具有全屏意图的高优先级通知。这在the documentation 中有介绍。 如果用户的设备被锁定,您的活动将立即显示,因为 Android 知道此时显示活动是安全的。而且,在其他情况下,它不会接管用户正在使用它的屏幕,因为这可能会对用户造成伤害。
@steller:“我对此有点困惑,因为我的 android 10 像素 2 处于锁定状态并且意图没有触发”——我的猜测是你没有实现高优先级通知全屏意图。这就是我所指的。 “你有一个适当的链接来显示你所说的例子吗?” -- 这在答案和the documentation中都有介绍。
@steller:是的。为此,您可以使用一对带有关联图标的操作。例如,this activity 引发具有全屏意图和操作的通知。这个特定的例子不是很实用,但它展示了 API 的工作原理。
@amp:至少在三星 Galaxy S9 上,我需要点击锁屏上的通知,然后滑动,才能显示活动。设备制造商可能正在修补机制。但是,我对如何改进流程没有任何建议。【参考方案2】:
android 10可以使用SYSTEM_ALERT_WINDOW强制启动activity窗口,参考这个设置superposition setting:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<activity
android:name=".MainActivity"
android:label="@string/app_name"
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".OnBootReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
在启动的应用中检查权限:
private void RequestPermission()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if (!Settings.canDrawOverlays(this))
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + this.getPackageName()));
startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
else
//Permission Granted-System will work
您可以将用户意图作为 android 旧版本
public class OnBootReceiver extends BroadcastReceiver
private static final String TAG = OnBootReceiver.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent)
try
Intent activity = new Intent(context, MainActivity.class);
activity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(activity);
catch (Exception e)
Log.d(TAG,e.getMessage()+"");
【讨论】:
即使应用程序被杀死并且屏幕被锁定,这也会打开活动。谢谢。【参考方案3】:Android 10 对后台活动启动的限制大约在六个月前宣布。您可以在documentation 中了解更多信息。
所以你需要有一个高级别的通知,当用户点击通知时你的活动将被打开通知
public class UIExampleReceiver extends BroadcastReceiver
public static final String TAG_NOTIFICATION = "NOTIFICATION_MESSAGE";
public static final String CHANNEL_ID = "channel_1111";
public static final int NOTIFICATION_ID = 111111;
private static final String TAG = "Receiver";
@Override
public void onReceive(Context context, Intent intent)
try
// If android 10 or higher
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P)
startActivityNotification(context,NOTIFICATION_ID,context.getResources().getString(R.string.open_app), context.getResources().getString(R.string.click_app));
else
// If lower than Android 10, we use the normal method ever.
Intent activity = new Intent(context, ExampleActivity.class);
activity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(activity);
catch (Exception e)
Log.d(TAG,e.getMessage()+"");
// notification method to support opening activities on Android 10
public static void startActivityNotification(Context context, int notificationID,
String title, String message)
NotificationManager mNotificationManager =
(NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
//Create GPSNotification builder
NotificationCompat.Builder mBuilder;
//Initialise ContentIntent
Intent ContentIntent = new Intent(context, ExampleActivity.class);
ContentIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent ContentPendingIntent = PendingIntent.getActivity(context,
0,
ContentIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(title)
.setContentText(message)
.setColor(context.getResources().getColor(R.color.colorPrimaryDark))
.setAutoCancel(true)
.setContentIntent(ContentPendingIntent)
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID,
"Activity Opening Notification",
NotificationManager.IMPORTANCE_HIGH);
mChannel.enableLights(true);
mChannel.enableVibration(true);
mChannel.setDescription("Activity opening notification");
mBuilder.setChannelId(CHANNEL_ID);
Objects.requireNonNull(mNotificationManager).createNotificationChannel(mChannel);
Objects.requireNonNull(mNotificationManager).notify(TAG_NOTIFICATION,notificationID,
mBuilder.build());
【讨论】:
以上是关于无法从 Android 10 上的 BroadcastReceiver 开始活动的主要内容,如果未能解决你的问题,请参考以下文章
无法将图像文件从 Android 应用程序发布到托管在 Tomcat 上的 Java servlet
无法使用 android 模拟器上的 Firestore 模拟器访问云 Firestore 后端