共计 3781 个字符,预计需要花费 10 分钟才能阅读完成。
Android 12 一个重要的变更是进步利用和零碎的安全性,这个变更影响了 所有指标版本为 Android 12 的利用。
在 AndroidManifest.xml 文件中注册的 Activity、service 和 broadcast receiver 组件如果有 intent-filter 申明都必须显式申明是否须要对外披露服务 (android:exported)。
❗️如果您的利用呈现了以下错误信息,很有可能和这个变更无关。
Installation did not succeed.
The application could not be installed: INSTALL_FAILED_VERIFICATION_FAILURE
List of apks:
[0]‘…/build/outputs/apk/debug/app-debug.apk’
Installation failed due to:‘null’
或
NSTALL_PARSE_FAILED_MANIFEST_MALFORMED: Failed parse during installPackageLI:
/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 首个开发者预览版到来。