政策更新 | 開發者如何處理軟件包可見性

咱們正在 Android 平臺上進行多項變動來加強用戶隱私和平臺安全性,旨在爲用戶提供更安全的體驗。以 Android 11 (API 級別 30) 或更高版本爲目標的應用默認將只能獲取 過濾後的已安裝應用列表。如需訪問過濾後列表之外的應用,則須要在應用內的 Android manifest 中使用 <queries> 元素聲明須要與之交互的應用。本文將介紹適應此特性的最佳實踐。android

查詢應用並與之交互

您能夠經過如下幾種方式查詢應用並與之交互:chrome

  • 若是您知道想要查詢或與之交互的特定應用集,請將其 軟件包 名稱包含在 <queries> 元素內的一組 <package> 元素中。
<manifest package="com.example.game">
    <queries>
        <package android:name="com.example.store" />
        <package android:name="com.example.services" />
    </queries>
    ...
</manifest>
  • 若是您的應用須要查詢或與一組具備特定用途的應用交互,但您可能不知道要添加的具體軟件包名稱,您能夠將 intent 過濾器簽名 列在您的 <queries> 元素中。而後,您的應用即可發現具備匹配的 <intent-filter> 元素的應用。
<manifest package="com.example.game">
    <queries>
        <intent>
            <action android:name="android.intent.action.SEND" />
            <data android:mimeType="image/jpeg" />
        </intent>
    </queries>
    ...
</manifest>
  • 若是您須要查詢 Content Provider,但不知道具體的軟件包名稱,則能夠在 <provider> 元素中聲明該提供程序受權。
<manifest package="com.example.suite.enterprise">
    <queries>
        <provider android:authorities="com.example.settings.files" />
    </queries>
    ...
</manifest>

咱們建議經過僅查詢您須要與之交互的軟件包來儘量減小數據。QUERY_ALL_PACKAGES 或同等普遍的 <intent> 元素應當僅由須要此級別信息的應用使用。咱們新增的軟件包可見性政策爲新推出的 QUERY_ALL_PACKAGES 權限引入了一個審批流程,用於控制對設備上已安裝應用清單的訪問。您能夠觀看如下視頻或閱讀更多 政策更新shell

https://www.bilibili.com/vide...瀏覽器

Activity 標記

大多數常見用例都不須要您的應用具備普遍的軟件包可見性。對於許多場景,您可使用 startActivity(),並在沒有應用能夠打開此 intent 時捕獲異常。安全

try {
    val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
        addCategory(CATEGORY_BROWSABLE)
    }
    startActivity(intent)
} catch (e:ActivityNotFoundException) {
    Snackbar.make(it,"Activity Not Found",Snackbar.LENGTH_LONG).show()
}

儘管您能夠啓動沒有目標可見性的任何 Activity,但因爲它是一個 隱式 intent,您在啓動以前沒法查詢它的可用性,也沒法瞭解將啓動哪一個特定的應用。若是您在它不解析的狀況下啓動,將收到通知。爲了解決這一問題,您可使用 intent 標記。app

使用標記的常見示例是 自定義標籤頁,自定義標籤頁讓應用能夠自定義瀏覽器的外觀。連接將在非瀏覽器應用 (若是有) 中正確打開,而標記則能夠在開發者但願可以自由選擇 "自定義標籤頁" 瀏覽器的高級用例中提供幫助。ide

FLAG_ACTIVITY_REQUIRE_NON_BROWSERui

只有 intent 解析爲非瀏覽器結果時,此標記纔會啓動它。若是此類結果不存在,將拋出 ActivityNotFoundException,而後,您的應用能夠在自定義標籤頁中打開該網址。google

val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
        // The URL should either launch directly in a non-browser app (if it's
        // the default), or in the disambiguation dialog.
        addCategory(CATEGORY_BROWSABLE)
        flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER
}

若是一個 intent 包含此標記,則在調用直接啓動瀏覽器應用或者向用戶顯示一個消歧對話框 (惟一選項是瀏覽器應用) 時,調用 startActivity() 會致使拋出 ActivityNotFoundException。要詳細瞭解標記,請參閱 基於用例配置軟件包可見性編碼

自定義共享表單

建議使用系統提供的共享表單代替自定義表單。無需應用可見性,您也能夠自定義系統共享表單。請參閱 文檔 瞭解更多信息。

調試軟件包可見性

您能夠輕鬆檢查 manifest,瞭解是否包括了全部 queries。爲此,請訪問 manifest 文件並選擇 Merged Manifest。

您也能夠啓用軟件包過濾的日誌消息,瞭解默承認見性對您的應用有何影響:

$ adb shell pm log-visibility --enable YOUR_PACKAGE_NAME

後續步驟

有關軟件包可見性的詳細信息,您能夠參閱如下資源:

樂享編碼!

相關文章
相關標籤/搜索