Android13中BroadcastReceiver无法校验SYSTEM_ALERT_WINDOW权限求助
解决方案
1. 修正权限校验的上下文
BroadcastReceiver持有的context是ReceiverRestrictedContext,在Android 13及三星等定制系统中,用它校验悬浮窗权限会返回错误结果。改用Application Context进行权限校验:
boolean hasOverlayPermission = Settings.canDrawOverlays(context.getApplicationContext());
2. 替换为Android 12+标准窗口类型
Android 12及以上,TYPE_SYSTEM_ALERT(类型值2038)已被废弃且权限限制极严,统一使用TYPE_APPLICATION_OVERLAY,同时配置正确的窗口标记:
WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, PixelFormat.TRANSLUCENT );
3. 来电场景改用前台Service执行悬浮窗操作
Android 13对后台Worker的窗口操作限制严苛,来电触发时系统处于通话/锁屏状态,三星One UI会进一步收紧后台权限。建议:
- 在
PhoneCallReceiver中启动前台Service(Android 12+要求前台Service必须绑定通知) - 在前台Service中完成来电信息获取和悬浮窗添加
前台Service核心代码示例
// PhoneCallReceiver中启动Service Intent serviceIntent = new Intent(context, CallOverlayService.class); serviceIntent.putExtra("phone_number", incomingNumber); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(serviceIntent); } else { context.startService(serviceIntent); } // CallOverlayService内部实现 @Override public void onCreate() { super.onCreate(); // 创建前台通知(Android 12+强制要求) Notification notification = new NotificationCompat.Builder(this, "overlay_channel") .setContentTitle("来电提示") .setContentText("正在显示来电信息") .setSmallIcon(R.drawable.ic_notification) .build(); startForeground(1, notification); } public void showOverlay(String phoneNumber) { if (!Settings.canDrawOverlays(getApplicationContext())) { // 引导用户重新授权 return; } WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); wm.addView(mOverlayView, params); }
4. 确认Release包权限配置完整
在AndroidManifest中补充必要权限声明:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- Android 13+前台Service需要 --> <uses-permission android:name="android.permission.BROADCAST_PHONE_STATE" /> <!-- Android 13+接收电话广播需要 -->
注:Android 13上READ_PHONE_STATE是危险权限,需动态申请;SYSTEM_ALERT_WINDOW需引导用户跳转到设置页授权:
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); startActivity(intent);
5. 适配三星One UI的特殊管控
针对三星Galaxy S21:
- 进入「设置 -> 通知 -> 悬浮通知」,确保应用已开启悬浮通知权限
- 进入「设置 -> 应用 -> 你的应用 -> 权限 -> 特殊权限」,确认「显示在其他应用上层」权限已开启
- 来电触发悬浮窗时可延迟500ms执行(通话状态下系统资源紧张,延迟可提高添加成功率)
内容的提问来源于stack exchange,提问作者sun
相关产品推荐
相关产品推荐

