在之前的[《Android 17 有什麼需要適配的?》](https://juejin.cn/post/7610233341305389099)我們已經聊過了部分更新場景,而最近 Android 又進一步增加了權限部分的調整。
目前 Android 17 已經進入 Beta 後期階段,而官方這波更新也進一步收緊權限,甚至可以說是系統級控制模型重構階段。

從 Android 17 開始,Android 引入了單次授權與動態粗略定位演算法,新增了 「位置按鈕」(system‑provided location button),用於單次精確位置授權,也就是,對於許多常見場景,例如在社交 App 中發帖時加入位置標籤,App 並不需要永久或持續在背景存取使用者的精確定位。

也就是以後的位置權限,使用者可以只在「這一刻」提供精準位置,會需要用到 USE_LOCATION_BUTTON 權限:
當然,這裡有個特殊在於,「位置按鈕」這次 Android 提供相對豐富的自訂選項,支援開發者在保持系統級可識別性的前提下,自訂對應風格:

也就是開發者可以修改按鈕的背景與圖示配色方案、輪廓樣式以及尺寸形狀,不過為了確保安全與信任,位置圖示本身為強制顯示且無法自訂,同時字體大小則由系統管理。
而在適配實現上,「位置按鈕」會透過 Jetpack 套件的形式提供,從而簡化位置權限的請求流程,使用對應 Jetpack 套件實作位置按鈕,系統會自動處理向後相容性。比如使用者在 Android 16 或更低版本上點按按鈕,會預設回退至現有的位置權限提示,

這個功能會在 Android 17 Beta 3 開放測試,從 Android 17 開始,位置存取透明度就基本與麥克風/相機在同一等級,系統會新增一個狀態指示器,每當非系統應用存取位置時,指示器將持續顯示,而使用者可以透過指示器,查看近期存取過位置的具體應用,並透過「最近應用程式使用」對話框即時管理相關權限。
同時這次 Android 還強化了粗略定位演算法(Approximate Location)的精準度,不過「大致位置」功能場景對於很多 App 的常見使用情況已經非常有效。
Android 17 開始增加了全新的 ACTION_PICK_CONTACTS,用來收緊目前應用過度讀取通訊錄的隱私問題,因為 ACTION_PICK_CONTACTS API 類似現有的系統圖片選擇器,不再全面授權 READ_CONTACTS 權限,而是採用 Intent.ACTION_PICK_CONTACTS 機制:

透過 picker,app 只能看到使用者勾選的具體聯絡人,而應用只能請求所需的特定資料欄位,最重要的是,這個功能可能支持打破系統個人資料(profile)限制,支援從裝置上其他 profile 讀取聯絡人。
官方說的是支援 profile switching,也就是選擇器支援在不同 profile 間切換。
Android 17 正式加入了一種新的系統級安全模式 Advanced Protection Mode(進階保護模式,APM),使用者開啟後會啟用一組更激進的安全策略,在 APM 模式下,會限制側載、限制 USB 傳輸資料、強制進行 Google Play Protect 掃描、同時限制高風險權限行為並強化日誌與偵測。
這個情境下,首當其衝的就是 AccessibilityService(輔助功能服務),APM 模式在 Android 16 已有介紹,Android 的 APM 模式會針對使用輔助功能服務 API,但沒有被歸類為輔助功能工具的應用(Google Play 上的 isAccessibilityTool 屬性),會禁用它們對輔助功能服務 API 的使用。

開啟進階保護模式後,Android 系統不僅會阻止使用者向非輔助功能工具授予輔助功能服務權限,還會收回已授予的權限,而開發者可以透過 AdvancedProtectionManager 和 QUERY_ADVANCED_PROTECTION_MODE 去感知其狀態。
Android 17 開始 BAL(Background Activity Launcher)限制擴展到了 IntentSender,舊的 MODE_BACKGROUND_ACTIVITY_START_ALLOWED 需要遷移,建議改用更細粒度的模式,例如 MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE。
Android 17 開始,對 targetSdk 37 ACCESS_LOCAL_NETWORK 開始強制化,新增權限宣告:
<uses-permission android:name="android.permission.ACCESS_LOCAL_NETWORK" />
也就是沒有宣告該權限會無法存取區域網路,內網存取從「預設開放」變為「權限保護」機制,這在物聯網和智慧家庭場景可能變化較大。
存取 LAN(如裝置發現)需要:
ACCESS_LOCAL_NETWORK它屬於
NEARBY_DEVICES權限群組(鄰近裝置),如果你的應用牽涉投屏、列印或智慧家庭,就需要額外檢查NEARBY_DEVICES權限群組的整合,因為ACCESS_LOCAL_NETWORK在該群組下。
Android 17 開始 App 無法立即讀取 OTP 簡訊,預設會延遲 3 小時後才允許存取,官方建議使用:
Android 17 開始 所有 native 函式庫透過 System.load() 載入時必須為唯讀(read‑only),否則直接崩潰,這對於熱更新的影響會比較大:
所以透過
System.load()載入的 native 檔案必須是唯讀,否則會拋出UnsatisfiedLinkError。
範例(Kotlin):
val libraryFile = File(context.filesDir, "my_native_lib.so")
// 在載入前將檔案標記為唯讀,以符合 Android 17+ 的安全要求
libraryFile.setReadOnly()
System.load(libraryFile.absolutePath)
對於有熱更新需求的應用,必須在 System.load() 之前顯式呼叫 file.setReadOnly()。
Android 17 開始,對於 targetSdk 37 的應用會自動啟用 CT(Certificate Transparency),也就是 HTTPS 憑證必須在 CT 日誌中可驗證。
在 targetSdk 37+ 並且執行於 Android 17+ 時,不能再透過反射修改 static final 欄位,如果使用反射會出現 IllegalAccessException。
也就是 Android 17 進一步收緊了執行時竄改能力,這也會影響部分依賴執行時 hook、變更常數或底層注入的框架與工具鏈。
密碼可見策略在 Android 17 被拆成觸控與實體鍵盤兩套設定,實體鍵盤預設直接隱藏字元。
也就是 Android 17 調整了密碼回顯策略,將「顯示密碼」拆分成觸控輸入與實體鍵盤輸入兩套設定,對實體鍵盤預設不再短暫回顯最後一個字元。
範例(Kotlin):
val isPhysical = event.source and InputDevice.SOURCE_KEYBOARD == InputDevice.SOURCE_KEYBOARD
val shouldShow = android.text.ShowSecretsSetting.shouldShowPassword(context, isPhysical)
developer.android.com/about/versi…
developer.android.com/about/versi…
developer.android.com/about/versi…
developer.android.com/privacy-and…
android-developers.googleblog.com/2026/03/loc…
support.google.com/googleplay/…
www.androidauthority.com/android-adv…
android-developers.googleblog.com/2026/03/the…