Android 12 一个重要的变动是提升应用和系统的安全性,这个变动影响了全部目标版本为 Android 12 的应用。android
在 AndroidManifest.xml 文件中注册的 Activity、service 和 broadcast receiver 组件若是有 intent-filter 声明都必须显式申明是否须要对外披露服务 (android:exported)。安全
❗️若是您的应用出现了如下错误信息,颇有可能和这个变动有关。app
Installation did not succeed.ide
The application could not be installed: INSTALL_FAILED_VERIFICATION_FAILUREui
List of apks:google
[0] ‘…/build/outputs/apk/debug/app-debug.apk’debug
Installation failed due to: ‘null’设计
或code
NSTALL_PARSE_FAILED_MANIFEST_MALFORMED: Failed parse during installPackageLI:component
/data/app/vmdl538800143.tmp/base.apk (at Binary XML file line #…):
com.example.package.ActivityName: Targeting S+ (version 10000 and above) requires that an explicit
value for android:exported be defined when intent filters are present”
要解决上述问题,您须要在 AndroidManifest.xml
文件中,为使用了 <intent-filter>
的 <activity>
、<activity-alias>
、<service>
或 <receiver>
组件声明 android:exported
属性。
咱们很是期待收到您对这项关于本要求的反馈,若是有任何建议和想法,请填写这份 简短的调查问卷 向咱们反馈,告诉咱们您的应用中的哪些用例受到此变动的影响。
⚠️ 请不要 "简单粗暴" 地给这些组件直接添加 android:exported="true"
,您须要检查并斟酌那些加入了 intent-filter 属性的组件: 用户设备上的任何其余应用都能启动这个组件,这是不是您须要的?
判断组件可否与其余应用的组件或服务相互调用或交互,这取决于应用自己的功能、其余应用如何与本应用交互,以及可能存在的特定应用场景。这里有一些常见例子,例子中包含了 intent-filter 的建议配置以及为何要这样设置。
为包含 <category android:name="android.intent.category.LAUNCHER" />
的 Activity 设定 android:exported="true"
这个 Activity 多是您应用的 MainActivity
,因为 Android 上的 Launcher (桌面/启动器) 是一个很常规的应用,这个 Activity 必须设定 exported="true"
,不然 Launcher 应用就没法启动它。
为包含 <action android:name="android.intent.action.VIEW" />
的 Activity 设定 android:exported="true"
这个 Activity 负责处理来自其余应用的 "open with" 操做。
为包含 <action android:name="android.intent.action.SEND" />
或 <action android:name="android.intent.action.SEND_MULTIPLE"/>
的 Activity 设定 android:exported="true"
这个 Activity 负责处理来自其余应用分享的内容。如需了解更多,请参阅: 从其余应用接收简单的数据
。
为包含 <action android:name="android.media.browse.MediaBrowserService" />
的 Service 设定 android:exported="true"
若是这是一个将应用的媒体库公开给其余应用的 Service,则须要设定为 android:exported="true",以便于其余应用链接和浏览。这个 Service 通常是经过直接或者间接继承 MediaBrowserServiceCompat 来实现的,若是不是,就没有必要设置这个。
为包含 <action android:name="com.google.firebase.MESSAGING_EVENT" />
Service 设定 android:exported="false"
这个 Service 会被 Firebase Cloud Messaging 调用,Service 须要继承 FirebaseMessagingService
。这个 Service 不该该设定 android:exported="true",由于不管它的属性值是什么,Firebase 均可以启动这个 Service。如须要了解更多,请参阅: 在 Android 上开发一个基于 Firebase Cloud 的消息应用。
为包含 <action android:name="android.intent.action.BOOT_COMPLETED" />
的 Receiver 设定 android:exported="false"
由于不管是否设定 exported,系统都会向 receiver 发送对应的广播。
在 Android 12 以前,有 intent-filter 属性的组件 (只有 Activity、Service 和 BroadcastReceiver) 自动被默认设定为 exported。
下面的 Activity 默认会 exported:
<activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
下面的 Activity 不会 exported:
<activity android:name=".MainActivity" />
这个默认的设置看起来可能合理,但这个错误可能会让应用容易受到攻击。举个例子,假设咱们的应用有一个播放视频的 Activity:
<activity android:name=”.PlayVideoActivity” />
后来咱们发现不少地方都须要显式地调用或启动这个 Activity,为了下降应用的耦合,咱们给 Activity 添加了 intent-filter 属性,容许系统选择这个 Activity:
<activity android:name=”.PlayVideoActivity”> <intent-filter> <action android:name=”android.intent.action.VIEW” /> <data android:mimeType=”video/*” android:scheme=”content” /> </intent-filter> </activity>
到这里问题就出现了,这个 Activity 设计的目的仅仅是在应用内部使用,可如今却被公开了!
若是咱们的应用目标版本是 Android 12,系统会阻止这样的设置,并强制要求咱们去设置 android:exported 属性。因为咱们不想将 Activity 对外公开,咱们能够设置 android:export=false,以确保应用的安全性。
<activity android:name=”.PlayVideoActivity” android:exported=”false”> <intent-filter> <action android:name=”android.intent.action.VIEW” /> <data android:mimeType=”video/*” android:scheme=”content” /> </intent-filter> </activity>
Android 12 一个重要的变化是提升了安全性。以 Android 12 为目标版本的应用,若是 AndroidManifest.xml
注册的 activity
、activity-alias
、service
或者 broadcast receiver 组件有 intent-filter
属性,必须显式设置 android:exported
的值,不然应用将没法安装。
须要仔细考虑 android:exported 属性须要设置什么值,若是不肯定,建议设置 android:exported="false"
。
了解更多关于 intent 和 intent-filter 的信息,请参阅: 接收一个隐式的 intent。
了解更多安全和隐私上的更新,请参阅: 行为变动: 以 Android 12 为目标平台的应用->安全性。
了解 Android 12 全部的更新,请参阅: Android 12 首个开发者预览版到来。