1、安卓6到安卓15適配主要內(nèi)容:①②③④⑤⑥⑦⑧⑨
Android 6:
新增運(yùn)行時(shí)權(quán)限,區(qū)分普通權(quán)限和危險(xiǎn)權(quán)限,危險(xiǎn)權(quán)限除了在清單文件即AndroidManifest.xml文件中注冊(cè),還需要在需要權(quán)限的代碼位置動(dòng)態(tài)申請(qǐng),比如相機(jī)、電話、定位、存儲(chǔ)。android6.0 之前,我們把a(bǔ)pp需要用到的權(quán)限全部羅列在Manifest清單文件中。
Android 7:
禁止在您的應(yīng)用外部公開 file:// URI。
要在應(yīng)用間共享文件,您應(yīng)發(fā)送一項(xiàng) content:// URI,并授予 URI 臨時(shí)訪問權(quán)限。進(jìn)行此授權(quán)的最簡(jiǎn)單方式是使用 FileProvider 類。
Android 8:
①、通知渠道id
Android 8.0 引入了通知渠道,其允許您為要顯示的每種通知類型創(chuàng)建用戶可自定義的渠道。用戶界面將通知渠道稱之為通知類別。targeSdk升級(jí)到26之后,所有的通知的實(shí)現(xiàn)都需要提供通知渠道,如果不提供通知渠道的話,所有通知在8.0系統(tǒng)上面都不能正常展示。 需要有渠道id 、渠道name
②、后臺(tái)執(zhí)行限制
應(yīng)用在后臺(tái)運(yùn)行,需要調(diào)用 Context.startForegroundService()啟動(dòng)服務(wù)。且應(yīng)用必須在創(chuàng)建服務(wù)后的五秒內(nèi)調(diào)用該服務(wù)的 startForeground() 函數(shù)。
③、允許安裝未知來源應(yīng)用
8.0 的應(yīng)用需要在 AndroidManifest.xml 中聲明 REQUEST_INSTALL_PACKAGES 權(quán)限,否則將無法進(jìn)行應(yīng)用內(nèi)升級(jí)。
④、 取消隱式廣播
移除掉了所有的隱式廣播(即清單文件中注冊(cè)的廣播),所以請(qǐng)使用顯示廣播進(jìn)行注冊(cè)(即代碼注冊(cè))。
⑤、權(quán)限
之前對(duì)于隱私權(quán)限只要申請(qǐng)一個(gè)就會(huì)將其在的權(quán)限組全部通過,android 8.0以后申請(qǐng)單個(gè)只給單個(gè);
Android 9:
①、限制非 Activity 環(huán)境中啟動(dòng) Activity
不能從非 Activity 環(huán)境中啟動(dòng) Activity,除非您傳遞 Intent 標(biāo)志 FLAG_ACTIVITY_NEW_TASK。
②、HTTP接口請(qǐng)求限制
Android 9.0 限制了明文流量(即HTTP接口)的網(wǎng)絡(luò)請(qǐng)求,非加密的流量請(qǐng)求都會(huì)被系統(tǒng)禁止,或者直接使用HTTPS接口。解決辦法在 res 目錄下新建xml文件夾,添加network_security_config.xml文件或者在Application屬性中添加如下配置 android:usesCleartextTraffic="true"
③、對(duì)非 SDK 接口的限制
現(xiàn)已禁止訪問特定的非 SDK 接口,無論是直接訪問,還是通過 JNI 或反射進(jìn)行間接訪問。嘗試訪問受限制的接口時(shí),會(huì)生成 NoSuchFieldException 和 NoSuchMethodException 之類的錯(cuò)誤。
④、限制后臺(tái)對(duì)傳感器的訪問
App后臺(tái)運(yùn)行時(shí),以下行為受限: 麥克風(fēng)、攝像頭、陀螺儀、加速度計(jì)等傳感器。
⑤、前臺(tái)服務(wù)
Android 8.0 增加startForegroundService()來創(chuàng)建一個(gè)前臺(tái)服務(wù),在Android 9.0 調(diào)用該函數(shù)時(shí),還需要額外添加FOREGROUND_SERVICE權(quán)限,這是普通權(quán)限,否則會(huì)發(fā)生 SecurityException 異常。
⑥、 硬件序列號(hào)
在 Android 9 中,Build.SERIAL 始終設(shè)置為 “UNKNOWN” 以保護(hù)用戶的隱私。
如果您的應(yīng)用需要訪問設(shè)備的硬件序列號(hào),您應(yīng)改為請(qǐng)求 READ_PHONE_STATE 權(quán)限,然后調(diào)用 getSerial()。
Android 10:
①、后臺(tái)運(yùn)行時(shí)訪問設(shè)備位置信息需要權(quán)限
Android 10 引入了 ACCESS_BACKGROUND_LOCATION 權(quán)限(危險(xiǎn)權(quán)限)。該權(quán)限允許應(yīng)用程序在后臺(tái)訪問位置。如果請(qǐng)求此權(quán)限,則還必須請(qǐng)求ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION權(quán)限。只請(qǐng)求此權(quán)限無效果。
②、限制了對(duì)剪貼板數(shù)據(jù)的訪問權(quán)限
除非您的應(yīng)用是默認(rèn)輸入法 (IME) 或是目前處于焦點(diǎn)的應(yīng)用,否則它無法訪問 Android 10 或更高版本平臺(tái)上的剪貼板數(shù)據(jù)。
③、分區(qū)存儲(chǔ)
分區(qū)存儲(chǔ)將外部存儲(chǔ)分成兩部分:
(1)App-specific directory (沙盒目錄)
APP只能在Context.getExternalFilesDir()目錄下通過File的方式創(chuàng)建文件,APP卸載的時(shí)候,這個(gè)目錄下的文件會(huì)被刪除;無法通過File的方式在其他路徑創(chuàng)建文件。getExternalFilesDir
(2)Public Directory 公共目錄
公共目錄包括:多媒體公共目錄(Photos, Images, Videos, Audio)和下載文件目錄(Downloads)。
APP可以通過MediaStore 或者 SAF(System Access Framework)的方式訪問其中的文件。APP卸載后,文件不會(huì)被刪除。
Android Q以上移除了WRITE_EXTERNAL_STORAGE權(quán)限,應(yīng)用不需要這個(gè)權(quán)限就可以向沙盒內(nèi)存儲(chǔ)文件,也可以通過媒體數(shù)據(jù)庫的方式保存媒體數(shù)據(jù)至特定位置。
requestLegacyExternalStorage的作用是允許應(yīng)用訪問外部存儲(chǔ)的所有文件,而不需要遵循Android 10及以上版本對(duì)外部存儲(chǔ)訪問的限制。
App卸載后,對(duì)應(yīng)的沙盒目錄也會(huì)被刪除,如果APP想要在卸載時(shí)保留沙盒目錄下的數(shù)據(jù),要在 AndroidManifest.xml 中聲明 android:hasFragileUserData=“true”,這樣在 APP卸載時(shí)就會(huì)有彈出框提示用戶是否保留應(yīng)用數(shù)據(jù)。
④、標(biāo)識(shí)符和數(shù)據(jù)
Build.getSerial()
TelephonyManager.getImei()
getDeviceId()、getMeid()、getSimSerialNumber()、getSubscriberId()
序列號(hào)、國(guó)際移動(dòng)設(shè)備身份碼、移動(dòng)設(shè)備標(biāo)識(shí)號(hào)、設(shè)備的唯一標(biāo)識(shí)符
從 Android 10 開始,應(yīng)用必須具有 READ_PRIVILEGED_PHONE_STATE 特許權(quán)限才能正常使用以上這些方法。
Android11:
①、強(qiáng)制執(zhí)行分區(qū)存儲(chǔ)
將應(yīng)用更新為以 Android 11 為目標(biāo)平臺(tái)后,您將無法使用requestLegacyExternalStorage,而且也沒有其他標(biāo)記可以提供停用分區(qū)存儲(chǔ)。所有文件訪問權(quán)限 MANAGE_EXTERNAL_STORAGE,用來獲取所有文件的管理權(quán)限。
②、電話號(hào)碼相關(guān)權(quán)限
Android 11.0 更改了應(yīng)用在讀取電話號(hào)碼時(shí)使用的與電話相關(guān)的權(quán)限。則必須請(qǐng)求 READ_PHONE_NUMBERS 權(quán)限,而不是 READ_PHONE_STATE 權(quán)限。
③、前臺(tái)位置信息訪問權(quán)限
如果應(yīng)用的功能在下列某種情況下訪問設(shè)備的當(dāng)前位置信息,系統(tǒng)就會(huì)認(rèn)為應(yīng)用需要使用前臺(tái)位置信息:
屬于應(yīng)用的某個(gè) Activity 可見。
應(yīng)用的某個(gè)前臺(tái)服務(wù)正在運(yùn)行中。當(dāng)有前臺(tái)服務(wù)在運(yùn)行時(shí),系統(tǒng)會(huì)顯示一條常駐通知來提醒用戶注意。當(dāng)應(yīng)用被置于后臺(tái)時(shí)(例如當(dāng)用戶按設(shè)備上的主屏幕按鈕或關(guān)閉設(shè)備的顯示屏?xí)r),其位置信息訪問權(quán)限會(huì)得到保留。
建議你聲明 location 的前臺(tái)服務(wù)類型,如以下代碼段所示。在 Android 10(API 級(jí)別 29)及更高版本中,你必須聲明此前臺(tái)服務(wù)類型。
android:foregroundServiceType="location"
④、后臺(tái)位置信息訪問權(quán)限
除了前臺(tái)位置信息部分所述的兩種情況之外,如果應(yīng)用在任何其他情況下訪問設(shè)備的當(dāng)前位置信息,系統(tǒng)就會(huì)認(rèn)為應(yīng)用需要使用后臺(tái)位置信息。后臺(tái)位置信息精確度與前臺(tái)位置信息精確度相同,具體取決于應(yīng)用聲明的位置信息權(quán)限。
在 Android 10.0(API 級(jí)別 29)及更高版本中,你必須在應(yīng)用的清單中聲明 ACCESS_BACKGROUND_LOCATION 權(quán)限,以便請(qǐng)求在運(yùn)行時(shí)于后臺(tái)訪問位置信息。
⑤、單次授權(quán)
從 Android 11.0(API 級(jí)別 30)開始,每當(dāng)你的應(yīng)用請(qǐng)求與位置、麥克風(fēng)或相機(jī)相關(guān)的權(quán)限時(shí),面向用戶的權(quán)限對(duì)話框都會(huì)包含僅限這一次選項(xiàng),如果用戶在對(duì)話框中選擇此選項(xiàng),系統(tǒng)會(huì)向應(yīng)用授予臨時(shí)的單次授權(quán)。
⑥、自定義消息框視圖(Toast)被屏蔽
Android 11.0上不允許后臺(tái)顯示自定義視圖的Toast,如果想要從后臺(tái)顯示Toast,可以使用普通Toast。
Android 12:
①、定位權(quán)限:大概位置
在搭載 Android 12.0 或更高版本的設(shè)備上,用戶可以要求你的應(yīng)用只能訪問大致位置信息。
如果你的應(yīng)用請(qǐng)求 ACCESS_COARSE_LOCATION 但未請(qǐng)求 ACCESS_FINE_LOCATION,則此變更不會(huì)影響你的應(yīng)用。
如果你的應(yīng)用請(qǐng)求 ACCESS_FINE_LOCATION 運(yùn)行時(shí)權(quán)限,你還應(yīng)請(qǐng)求 ACCESS_COARSE_LOCATION 權(quán)限,以便處理用戶授予應(yīng)用大致位置訪問權(quán)限的情形。你應(yīng)該在單個(gè)運(yùn)行時(shí)請(qǐng)求中包含這兩項(xiàng)權(quán)限。
粗略位置: 精確到2平方公里的位置值,請(qǐng)求 ACCESS_COARSE_LOCATION 權(quán)限可以獲得。
精確位置: 精確到50米以內(nèi)的位置值,請(qǐng)求 ACCESS_FINE_LOCATION 權(quán)限可以獲得。
②、PendingIntent可變性
適配的具體就是在創(chuàng)建 PendingIntent時(shí),使用 PendingIntent.FLAG_MUTABLE (可變的) 或 PendingIntent.FLAG_IMMUTABLE(不可變的) 標(biāo)志。否則運(yùn)行時(shí)會(huì)報(bào) IllegalArgumentException。
③、藍(lán)牙權(quán)限
如果您的應(yīng)用程序面向Android 12或更高版本,使用藍(lán)牙功能時(shí)請(qǐng)?jiān)趹?yīng)用程序的清單文件中聲明以下權(quán)限:
BLUETOOTH_SCAN:允許藍(lán)牙設(shè)備掃描。
BLUETOOTH_CONNECT:允許藍(lán)牙設(shè)備連接。
BLUETOOTH_ADVERTISE:允許當(dāng)前藍(lán)牙設(shè)備可以被其他藍(lán)牙設(shè)備發(fā)現(xiàn)。
④、更安全的組件導(dǎo)出
以Android 12.0 為目標(biāo)平臺(tái)的App,如果其包含的四大組件中使用到了 intent 過濾器(intent-filter),則必須顯示聲明 android:exported 屬性,否則App將無法在 Android 12.0 及更高系統(tǒng)版本的設(shè)備上安裝。
⑤、 應(yīng)用啟動(dòng)畫面
從Android 12.0 開始,所有的App在每次啟動(dòng)時(shí)(特指冷啟動(dòng)與溫啟動(dòng)),系統(tǒng)都會(huì)為我們加上一個(gè)默認(rèn)的啟動(dòng)畫面。
Android 13:
①、細(xì)化的媒體權(quán)限
需要訪問其他應(yīng)用已經(jīng)創(chuàng)建的媒體文件,必須請(qǐng)求以下一項(xiàng)或多項(xiàng)細(xì)化的媒體權(quán)限,而不是 READ_EXTERNAL_STORAGE 或者 WRITE_EXTERNAL_STORAGE 權(quán)限。
圖片和照片:READ_MEDIA_IAMGES
視頻:READ_MEDIA_VIDEO
音頻:READ_MEDIA_AUDIO
如果用戶之前向您的應(yīng)用授予了 READ_EXTERNAL_STORAGE 權(quán)限,系統(tǒng)會(huì)自動(dòng)向您的應(yīng)用授予細(xì)化的媒體權(quán)限。否則,當(dāng)應(yīng)用請(qǐng)求上表中顯示的任何權(quán)限時(shí),系統(tǒng)會(huì)顯示面向用戶的對(duì)話框。
②、通知運(yùn)行時(shí)權(quán)限
Android13則引入了新的運(yùn)行時(shí)通知權(quán)限:android.permission.POST_NOTIFICATIONS。
③、廣告 ID 需要權(quán)限
使用 Google Play 服務(wù)廣告 ID 且以 Android 13(API 級(jí)別 33)及更高版本為目標(biāo)平臺(tái)的應(yīng)用必須在其清單文件中聲明常規(guī) AD_ID權(quán)限。如果你的應(yīng)用以 Android 13.0 或更高版本為目標(biāo)平臺(tái)且未聲明此權(quán)限,系統(tǒng)會(huì)自動(dòng)移除廣告 ID 并將其替換為一串零。
④、BroadcastReceiver變更
從Android 13開始,以Android13(API 33+)為目標(biāo)平臺(tái)的應(yīng)用,注冊(cè)靜態(tài)廣播時(shí),需設(shè)置對(duì)其他應(yīng)用的可見性:
若對(duì)其他應(yīng)用可見,廣播注冊(cè)時(shí)設(shè)置:Context.RECEIVER_EXPORTED
若僅應(yīng)用內(nèi)使用,廣播注冊(cè)時(shí)設(shè)置:Context.RECEIVER_NOT_EXPORTED
⑤、 在后臺(tái)使用身體傳感器需要新的權(quán)限
Android 13 中引入了“在使用時(shí)”訪問身體傳感器(例如心率、體溫和血氧飽和度)的概念。
如果您的應(yīng)用以 Android 13 為目標(biāo)平臺(tái),并且在后臺(tái)運(yùn)行時(shí)需要訪問身體傳感器信息,那么除了現(xiàn)有的 BODY_SENSORS 權(quán)限外,您還必須聲明新的 BODY_SENSORS_BACKGROUND 權(quán)限。
Android 14:
①、 應(yīng)用只能終止自己的后臺(tái)進(jìn)程
從 Android 14 開始,當(dāng)您的應(yīng)用調(diào)用 killBackgroundProcesses() 時(shí),該 API 只能終止您自己應(yīng)用的后臺(tái)進(jìn)程。
②、最低可安裝的目標(biāo) API 級(jí)別
從 Android 14 開始,targetSdkVersion 低于 23 (Android 6.0)的應(yīng)用無法安裝。
③、對(duì)于以 Android 14 為目標(biāo)平臺(tái)的應(yīng)用,Android 會(huì)通過以下方式限制應(yīng)用向內(nèi)部應(yīng)用組件發(fā)送隱式 intent:
隱式 intent 只能傳送到android:exported="true"組件。
應(yīng)用必須使用顯式 intent 傳送到android:exported="false"的組件,或?qū)⒃摻M件標(biāo)記為android:exported="true"。
如果應(yīng)用通過未指定組件或軟件包的 intent 創(chuàng)建可變待處理 intent,系統(tǒng)現(xiàn)在會(huì)拋出異常。
這些變更可防止惡意應(yīng)用攔截意在供應(yīng)用內(nèi)部組件使用的隱式 intent。
④、支持JDK17
Gradle版本最低需要升級(jí)至7.4.2,建議升級(jí)到8.0.1,如果Gradle升級(jí)到8.0以上,jdk需要升級(jí)至17以上
⑤、 前臺(tái)服務(wù)類型
targetSdkVersion 34 的情況下,必須為應(yīng)用內(nèi)的每個(gè)前臺(tái)服務(wù)(foreground-services) 指定至少一種[前臺(tái)服務(wù)]
前臺(tái)服務(wù)類型是在 Android 10 引入的,通過 android:foregroundServiceType 可以指定 <service> 的服務(wù)類型,可供選擇的前臺(tái)服務(wù)類型有:
camera、location、health、mediaplayback、phoncall
⑥、授予對(duì)照片和視頻的部分訪問權(quán)限
Android 14 引入了“所選照片訪問權(quán)限”,可讓用戶授權(quán)應(yīng)用訪問其媒體庫中的特定圖片和視頻,而不是授予對(duì)給定類型的所有媒體內(nèi)容的訪問權(quán)限。
⑦、檢測(cè)用戶何時(shí)截取設(shè)備屏幕截圖
為了打造更加標(biāo)準(zhǔn)化的屏幕截圖檢測(cè)體驗(yàn),Android 14 引入了可保護(hù)隱私的屏幕截圖檢測(cè) API。借助此 API,應(yīng)用可以按 activity 注冊(cè)回調(diào)。如果用戶在該 activity 可見時(shí)截取屏幕截圖,系統(tǒng)會(huì)調(diào)用這些回調(diào)并通知用戶。
注意:該回調(diào)未提供實(shí)際屏幕截圖的圖片。用戶截取屏幕截圖后,屏幕上的內(nèi)容將由您的應(yīng)用決定。
Android 15:①②③④⑤⑥⑦⑧⑨
①、 處理最低sdk適配
最低可安裝TargetSDK級(jí)別為24(Android 7.0)
②、 支持 16 KB 頁面大小
Linux 內(nèi)核限制: Android 基于 Linux 內(nèi)核,而 Linux 不支持混合頁面大小。
CPU 運(yùn)行模式: CPU 運(yùn)行時(shí)頁面大小是全局設(shè)置,要么是 4K,要么是 16K,無法混用。
影響:
正面影響: 提升系統(tǒng)內(nèi)存性能,縮短應(yīng)用啟動(dòng)時(shí)間,降低功耗,加快相機(jī)啟動(dòng)速度等。
負(fù)面影響: 使用了 .so 動(dòng)態(tài)庫的應(yīng)用需重新編譯才能兼容,否則大概率崩潰。
③、 私人空間
私人空間允許用戶在其設(shè)備上創(chuàng)建一個(gè)單獨(dú)的空間,在額外的身份驗(yàn)證層下,可以讓敏感應(yīng)用得到隔離。
私人空間使用單獨(dú)的用戶配置文件,當(dāng)用戶鎖定私人空間時(shí),配置文件將處于暫停,同時(shí) App 耶不再活動(dòng),用戶可以選擇使用設(shè)備鎖或單獨(dú)的鎖定來保護(hù)私人空間。
私人空間應(yīng)用顯示在啟動(dòng)器的單獨(dú)容器中,并且在私人空間鎖定時(shí)從最近的視圖、通知、設(shè)置和其他應(yīng)用中隱藏。
用戶生成和下載的內(nèi)容(媒體、文件)和帳戶在私人空間和主空間之間分開,當(dāng)私人空間解鎖時(shí),系統(tǒng)共享表和照片選擇器可用于讓應(yīng)用訪問跨空間的內(nèi)容。
④、將無法安裝和使用32位應(yīng)用
⑤、 新的前臺(tái)服務(wù)類型mediaProcessing
變更內(nèi)容:引入mediaProcessing前臺(tái)服務(wù)類型,適用于像轉(zhuǎn)碼媒體文件這樣的操作。
適配須知:系統(tǒng)允許一個(gè)應(yīng)用的媒體處理服務(wù)在24小時(shí)內(nèi)運(yùn)行總共6個(gè)小時(shí),之后系統(tǒng)會(huì)調(diào)用正在運(yùn)行的服務(wù)的Service.onTimeout(int, int)方法。