You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android O系统锁屏界面显示Dialog的实现方案

在Android Oreo及以上版本锁屏显示Dialog的解决方案

好问题!从Android Oreo(API 26)开始,Google确实限制了TYPE_SYSTEM_ERROR这类高权限系统窗口类型的使用,目的是收紧系统窗口权限、避免应用滥用影响用户体验。不过我们完全可以通过官方推荐的替代方案实现锁屏显示Dialog的需求,具体如下:

核心修改:替换窗口类型

Android O引入了TYPE_APPLICATION_OVERLAY这个专门用于应用悬浮窗场景的窗口类型,这是替代TYPE_SYSTEM_ERROR的官方方案。你之前用到的控制锁屏、屏幕唤醒的关键Flags依然有效,需要完整保留。

修改后的代码示例

// 保留原有的锁屏控制、屏幕唤醒等关键Flags
int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 
        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 
        | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON 
        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 
        | WindowManager.LayoutParams.FLAG_DIM_BEHIND;

// 根据API版本适配窗口类型
int type;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
    type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
}

WindowManager.LayoutParams windowLayoutParams = new WindowManager.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT, 
        ViewGroup.LayoutParams.MATCH_PARENT, 
        0, 0, 
        type, 
        flags, 
        PixelFormat.RGBA_8888);

必要的权限申请

使用TYPE_APPLICATION_OVERLAY必须先获取SYSTEM_ALERT_WINDOW权限,这个权限无法通过常规动态权限申请流程获取,需要引导用户到系统设置页面手动授权:

权限声明(AndroidManifest.xml)

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

动态引导授权代码

private static final int REQUEST_OVERLAY_PERMISSION = 1001;

// 检查并引导用户授权
public void checkOverlayPermission(Context context) {
    if (!Settings.canDrawOverlays(context)) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + context.getPackageName()));
        startActivityForResult(intent, REQUEST_OVERLAY_PERMISSION);
    }
}

// 处理授权结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_OVERLAY_PERMISSION) {
        if (Settings.canDrawOverlays(this)) {
            // 权限已授权,可创建锁屏Dialog
            showLockScreenDialog();
        } else {
            Toast.makeText(this, "需要开启悬浮窗权限才能在锁屏显示提示", Toast.LENGTH_SHORT).show();
        }
    }
}

额外适配提示

  • 部分厂商的定制系统可能对锁屏悬浮窗有额外限制,建议在主流设备上做适配测试;
  • 如果需要更深度的锁屏交互(比如直接解锁),可以配合KeyguardManagerrequestDismissKeyguard方法,同时需要声明DISMISS_KEYGUARD权限。

内容的提问来源于stack exchange,提问作者Augusto Carmo

火山引擎 最新活动