设置应用如何启动应用的非导出Activity?

How Can the Settings App Start an App's Non-Exported Activity?

Android N 让您 link 一个 activity 进入您的应用页面 设置。只需为 android.intent.action.APPLICATION_PREFERENCES 添加一个 <intent-filter>。 Android N 的“设置”应用会在您的应用中查找 activity 有 <intent-filter>。如果设置找到一个,它会添加一个齿轮 图标到您应用程序的设置页面,如果用户点击齿轮,他们 将被带到您指定的activity.

我担心安全问题,所以我提交了 an issue,寻找我们可以与 android:permission 一起使用的权限,以允许设置启动我们的 activity,但不允许其他启动我们的 activity 的应用程序(例如 WRITE_SECURE_SETTINGS)。

cketti 然后指出 you could just mark the activity as not exported, via android:exported="false"。令我惊讶的是,这有效。

“设置”应用如何启动标记为未导出的 activity?

我当然可以看到有一个控制这个的权限。然而,快速阅读设置应用程序的清单(master branch, n-developer-preview-5 分支)并没有发现任何明显的东西。

所以:

我猜清单中没有任何内容允许应用程序调用导出的活动。我相信它实现此目的的方法是在“设置”应用程序的 Android.mk 文件中设置 LOCAL_PRIVILEGED_MODULE := true。此标志将授予应用程序系统级权限,并在 OS 编译期间将其放置在 system/priv-app/ 目录中。

如果您查看 frameworks/base/core/java/android/app/ActivityManager.java 方法 checkComponentPermission,您会发现如果 UID 是 SYSTEM 的 UID,则无论导出的设置如何,都会授予组件权限。

虽然@Bobbake4 的回答是基于 UID 的检查是正确的,

If you look at frameworks/base/core/java/android/app/ActivityManager.java for the method checkComponentPermission you can see that if the UID is that of the SYSTEM, component permission is granted regardless of the exported setting.

我认为关于 LOCAL_PRIVILEGED_MODULE 的第一部分无关紧要。目录位置不控制获取哪个 UID 设置,而是由 sharedUserId in the manifest. As noted in the documentation 设置,这仅在应用程序使用与平台相同的证书签名时有效。