行爲變動 | 瞭解 Android 12 中的 intent-filter

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 註冊的 activityactivity-aliasservice 或者 broadcast receiver 組件有 intent-filter 屬性,必須顯式設置 android:exported 的值,不然應用將沒法安裝。

須要仔細考慮 android:exported 屬性須要設置什麼值,若是不肯定,建議設置 android:exported="false"

瞭解更多關於 intent 和 intent-filter 的信息,請參閱: 接收一個隱式的 intent

瞭解更多安全和隱私上的更新,請參閱: 行爲變動: 以 Android 12 爲目標平臺的應用->安全性

瞭解 Android 12 全部的更新,請參閱: Android 12 首個開發者預覽版到來

相關文章
相關標籤/搜索