You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 11实现Chrome添加到桌面快捷方式功能布局显示异常问题

问题原因

  1. Android 11(API 30)对外部组件调用的权限校验更严格,你调整后的代码中PinShortcutConfirm的android:exported属性设为false,首次触发时系统拦截了Chrome发起的外部Intent,仅创建了Activity实例但不给UI渲染权限,仅在Layout Inspector可见;第二次触发时应用进程已被唤起,系统临时放宽校验所以能正常显示。
  2. 弹窗Activity和主启动器Activity共用任务栈,主启动器的launchMode设为singleTask且在后台运行时,系统会抑制该任务栈中新Activity的UI展示,避免打断前台应用(Chrome)的用户操作。
  3. 主题不兼容:Application使用AppCompat主题,弹窗Activity使用系统原生Material主题,首次Inflate布局时出现渲染异常,系统跳过UI绘制,第二次触发时布局已缓存所以正常显示。
  4. ShortcutInfo强制解包可能导致空异常,首次触发时数据未完全加载就尝试渲染,触发异常后系统不展示界面。

修复方案

1. 修改AndroidManifest.xml配置

调整PinShortcutConfirm的属性如下:

<activity
    android:name="PinShortcutConfirm"
    android:theme="@style/Theme.AppCompat.Dialog"
    android:noHistory="true"
    android:excludeFromRecents="true"
    android:exported="true"
    android:launchMode="singleInstance"
    android:taskAffinity="">
    <intent-filter>
        <action android:name="android.content.pm.action.CONFIRM_PIN_SHORTCUT" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

修改点说明:

  • exported改为true,允许接收外部应用发起的Intent
  • 增加DEFAULT分类,匹配系统Intent的匹配规则
  • 新增launchMode="singleInstance"和空taskAffinity,让弹窗运行在独立任务栈,不受后台主启动器任务栈影响
  • 主题改为AppCompat系列的Dialog主题,和Application主题兼容

2. 修改PinShortcutConfirm.kt代码

  • 新增窗口标志,强制弹窗获得前台UI焦点
  • 替换ShortcutInfo的强制解包为安全调用,避免空异常
    修改后的onCreate代码如下:
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // 新增窗口标志,强制获得前台焦点
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
        setShowWhenLocked(true)
        setTurnScreenOn(true)
    } else {
        window.addFlags(
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                    or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
        )
    }
    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

    setContentView(R.layout.pin_shortcut_confirm)
    mLauncherApps = getSystemService(LauncherApps::class.java)
    findViewById<View>(R.id.ok).setOnClickListener(this)
    findViewById<View>(R.id.cancel).setOnClickListener(this)

    mRequest = getSystemService(LauncherApps::class.java).getPinItemRequest(intent)
    mShortcutInfo = mRequest.shortcutInfo

    // 安全调用,避免空异常
    mShortcutInfo?.let { info ->
        val description = findViewById<TextView>(R.id.shortcut_description)
        description.text = """
            ID: ${info.id}
            Label: ${info.shortLabel}
        """.trimIndent()
        val icon = mLauncherApps.getShortcutIconDrawable(info, resources.displayMetrics.densityDpi)
        icon?.let {
            findViewById<ImageView>(R.id.image).setImageDrawable(it)
        }
    } ?: run {
        finish()
        return
    }
}

3. 补充必要权限

在AndroidManifest.xml中添加启动器必要权限:

<uses-permission android:name="android.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="android.permission.CREATE_SHORTCUT" />
<!-- Android 11+包可见性权限,可正常获取Chrome发起的快捷方式信息 -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
    android:ignore="QueryAllPackagesPermission" />

内容的提问来源于stack exchange,提问作者El Nuru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:15:05