Android SDK≥33锁屏长按快捷设置Tile免解锁启动覆盖Activity问题
解决方案
1. 修复锁屏显示Activity免解锁问题
仅在Manifest中设置android:showOnLockScreen="true"不足以绕过锁屏验证,需补充以下配置:
- 在Manifest的
PopupActivity中添加额外属性:<activity android:name=".PopupActivity" android:excludeFromRecents="true" android:launchMode="singleInstance" android:taskAffinity="" android:theme="@style/TransparentDialogTheme" android:exported="true" android:showOnLockScreen="true" android:showWhenLocked="true" <!-- 新增 --> android:turnScreenOn="true"> <!-- 可选,需唤醒屏幕时添加 --> <!-- 移除QS_TILE_PREFERENCES的intent-filter,改用自定义Tile长按逻辑 --> </activity> - 在
PopupActivity的onCreate方法中添加WindowFlags:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 添加锁屏显示相关Flags getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); setContentView(R.layout.activity_popup); }
2. 自定义QS Tile长按行为,避免系统默认解锁要求
系统默认的QS_TILE_PREFERENCES意图会触发锁屏验证,改用自定义TileService控制长按逻辑:
- 创建自定义TileService:
public class CustomQSTileService extends TileService { @Override public void onLongClick() { // 直接启动PopupActivity Intent intent = new Intent(this, PopupActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 启动后收起快捷设置面板 startActivityAndCollapse(intent); } // 可选:实现点击Tile启动覆盖层的逻辑 @Override public void onClick() { super.onClick(); showOverlayWindow(); // 调用你的覆盖层显示方法 collapsePanels(); } } - 在Manifest中注册该TileService:
<service android:name=".CustomQSTileService" android:exported="true" android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"> <intent-filter> <action android:name="android.service.quicksettings.action.QS_TILE" /> </intent-filter> <meta-data android:name="android.service.quicksettings.ACTIVE_TILE" android:value="true" /> </service>
3. 修复覆盖层无法通过Tile启动的问题
如果使用WindowManager悬浮窗作为覆盖层,需确保:
- 已申请
SYSTEM_ALERT_WINDOW权限(API 23+需引导用户到设置开启); - 悬浮窗的LayoutParams添加锁屏显示Flags:
private void showOverlayWindow() { WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); View overlayView = LayoutInflater.from(this).inflate(R.layout.overlay_layout, null); 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_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD, PixelFormat.TRANSLUCENT); wm.addView(overlayView, params); }
4. SDK33兼容方案
上述方案均支持SDK33及以上版本,无需依赖SDK34的锁屏底部按钮组件。若后续需要适配SDK34,可通过版本判断实现双逻辑:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { // SDK34+:使用锁屏底部按钮组件逻辑 } else { // SDK33及以下:使用上述自定义Tile+悬浮窗/锁屏Activity方案 }
内容的提问来源于stack exchange,提问作者Jchx
相关产品推荐
相关产品推荐

