Qt for Android(十六) —— Android 10 适配之开机自启动

1,885 阅读1分钟

这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战

背景

  项目以前基于android7.0以下运行,静态监听系统的开机广播,然后拉起自己的activity。但是在Android 10 之后,发现方法失效了。

经过查阅资料发现:Android 10 (API 级别 29) 及更高版本对后台应用的启动做了限制。Android10中, 当App的Activity不在前台时,其启动Activity会被系统拦截,导致无法启动。

详见:google:从后台启动 Activity 的限制

这里摘一些概要:

Android 10 (API 级别 29) 及更高版本对后台应用可启动 Activity 的时间施加限制。这些限制有助于最大限度地减少对用户造成的中断,并且可以让用户更好地控制其屏幕上显示的内容。
注意:为启动 Activity,系统仍会将运行前台服务的应用视为“后台”应用。

方案一

要解决这个问题有两个方案: 其一是使用NotificationManager + 全屏Intent,并添加权限:

//AndroidManifest中
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />

Intent fullScreenIntent = new Intent(this, CallActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0,
        fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
 
NotificationCompat.Builder notificationBuilder =
        new NotificationCompat.Builder(this, CHANNEL_ID)
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle("Incoming call")
    .setContentText("(919) 555-1234")
    //以下为关键的3行
    .setPriority(NotificationCompat.PRIORITY_HIGH)
    .setCategory(NotificationCompat.CATEGORY_CALL)
    .setFullScreenIntent(fullScreenPendingIntent, true);
    
NotificationManager notifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notifyManager.notify(notifyId, builder.build());

方案二

方案二是动态注册广播,并增加ACTION_MANAGE_OVERLAY_PERMISSION权限:

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

 if (!Settings.canDrawOverlays(this)) {
            //开机自启动权限
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, 0);
            }
        m_adbReceiver = new AdbBootBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.intent.action.BROADCAST_FORM_ADB");
        registerReceiver(m_bootReceiver, intentFilter2);

其中,canDrawOverlays方法是在Android M(23)新加入的用于检查当前是否拥有“出现在其他应用上”权限的方法。在6.0以前的系统版本,悬浮窗权限是默认开启的,直接使用即可。