Android 6
1、運(yùn)行時權(quán)限
android6.0以前考榨,我們把a(bǔ)pp需要用到的權(quán)限全部羅列在Manifest清單文件中。安裝app時android系統(tǒng)會詢問用戶是否授予這些權(quán)限松捉,拒絕后則無法安裝app隘世。如果授予鸠踪,則安裝app营密,之后無法修改授予狀態(tài)。
android6.0將權(quán)限分為普通權(quán)限(不涉及用戶隱私和安全)和危險權(quán)限(設(shè)計用戶隱私和安全)纷捞。普通權(quán)限和andorid6.0之前一樣,在Manifest清單文件中申請即可奖唯。危險權(quán)限需要在使用時動態(tài)申請缀辩,由用戶決定是否授予。
危險權(quán)限分組:
2臀玄、HttpClient的移除
自Android6.0起瓢阴,HttpClient系列代碼從SDK中剔除,推薦使用HttpURLConnection健无。
Android 7
1荣恐、應(yīng)用間共享文件
對于面向 Android 7.0 的應(yīng)用,Android 框架執(zhí)行的 StrictMode API 政策禁止在您的應(yīng)用外部公開 file:// URI累贤。如果一項包含文件 URI 的 intent 離開您的應(yīng)用叠穆,則應(yīng)用出現(xiàn)故障,并出現(xiàn) FileUriExposedException 異常臼膏。
要在應(yīng)用間共享文件硼被,您應(yīng)發(fā)送一項 content:// URI,并授予 URI 臨時訪問權(quán)限渗磅。進(jìn)行此授權(quán)的最簡單方式是使用 FileProvider 類嚷硫。
(1)在AndroidManifest.xml清單文件中注冊provider
<manifest>
...
<application>
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.demo.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/paths" />
</provider>
...
</application>
</manifest>
(2)res/xml中定義對外暴露的文件夾路徑:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_storage_root"
path="." />
<files-path
name="files-path"
path="." />
<cache-path
name="cache-path"
path="." />
<external-files-path
name="external_file_path"
path="." />
<external-cache-path
name="external_cache_path"
path="." />
<root-path
name="root-path"
path="" />
</paths>
name:一個引用字符串。
path:文件夾“相對路徑”始鱼,完整路徑取決于當(dāng)前的標(biāo)簽類型仔掸。
<external-path/> 代表Environment.getExternalStorageDirectory()
<files-path/> 代表context.getFilesDir()
<cache-path/> 代表context.getCacheDir()
<external-files-path>代表context.getExternalFilesDirs()
<external-cache-path>代表getExternalCacheDirs()
<root-path/> 代表設(shè)備的根目錄new File("/");
7.0之前跳轉(zhuǎn)到系統(tǒng)相機(jī)拍照的代碼,需要提前設(shè)定好保存圖片的uri医清,跳轉(zhuǎn)到相機(jī)應(yīng)用
String cachePath = getApplicationContext().getExternalCacheDir().getPath();
File picFile = new File(cachePath, "test.jpg");
Uri picUri = Uri.fromFile(picFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, picUri);
startActivityForResult(intent, 100);
7.0之后:
String cachePath = getApplicationContext().getExternalCacheDir().getPath();
File picFile = new File(cachePath, "test.jpg");
Uri uriForFile = null;
if (Build.VERSION.SDK_INT >= 24) {
uriForFile = FileProvider.getUriForFile(MainActivity.this, "com.demo.fileprovider", picFile);
} else {
uriForFile = Uri.fromFile(picFile);
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uriForFile);
startActivityForResult(intent, 100);
將Uri.fromFile(file)換成了FileProvider.getUriForFile,這里getUriForFile方法的第二個參數(shù),就是第一步的provider的authorities
2起暮、廣播
Android 7.0 移除了三項隱式廣播。
面向 Android 7.0 開發(fā)的應(yīng)用不會收到 CONNECTIVITY_ACTION 廣播会烙,即使它們已有清單條目來請求接受這些事件的通知负懦。在主線程中通過Context.registerReceiver()動態(tài)注冊了CONNECTIVITY_ACTION廣播柏腻,該應(yīng)用程序仍然可以接收到該廣播。
應(yīng)用無法發(fā)送或接收 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO 廣播贫导。此項優(yōu)化會影響所有應(yīng)用闺金,而不僅僅是面向 Android 7.0 的應(yīng)用败匹。
Android 8
1、通知渠道id
Android 8.0 引入了通知渠道槽棍,其允許您為要顯示的每種通知類型創(chuàng)建用戶可自定義的渠道炼七。用戶界面將通知渠道稱之為通知類別。targeSdk升級到26之后按傅,所有的通知的實現(xiàn)都需要提供通知渠道,如果不提供通知渠道的話推捐,所有通知在8.0系統(tǒng)上面都不能正常展示牛柒。
//通知渠道id
val channelId = "channelId"
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//通知渠道名稱
val channelName = "channelName"
//通知渠道重要程度
val importance = NotificationManager.IMPORTANCE_HIGH
//構(gòu)建通知渠道
val channel = NotificationChannel(channelId, channelName, importance)
//設(shè)置通知渠道描述
channel.description = ""
//向系統(tǒng)注冊通知渠道,注冊后則不能修改重要性以及其他通知行為,但可以刪除
notificationManager.createNotificationChannel(channel)
}
val notification = NotificationCompat.Builder(this, "channelId")
.setContentTitle("標(biāo)題")
.setContentText("消息內(nèi)容")
.setSmallIcon(R.drawable.ic_launcher_background)
.setAutoCancel(true)//點(diǎn)擊自動消失
.build()
//通知id,每個通知都應(yīng)該不同否則會覆蓋
val notifyId = 1
notificationManager.notify(notifyId, notification)
2滴须、后臺執(zhí)行限制
- 如果針對 Android 8.0 的應(yīng)用嘗試在不允許其創(chuàng)建后臺服務(wù)的情況下使用 startService() 函數(shù)痛侍,則該函數(shù)將引發(fā)一個 IllegalStateException主届。
- 新的 Context.startForegroundService() 函數(shù)將啟動一個前臺服務(wù)。現(xiàn)在谈截,即使應(yīng)用在后臺運(yùn)行,系統(tǒng)也允許其調(diào)用 Context.startForegroundService()喻鳄。不過除呵,應(yīng)用必須在創(chuàng)建服務(wù)后的五秒內(nèi)調(diào)用該服務(wù)的 startForeground() 函數(shù)。
3泛豪、允許安裝未知來源應(yīng)用
8.0 的應(yīng)用需要在 AndroidManifest.xml 中聲明 REQUEST_INSTALL_PACKAGES 權(quán)限诡曙,否則將無法進(jìn)行應(yīng)用內(nèi)升級价卤。
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
4床嫌、隱式廣播的限制
我們自己定義的廣播隱式調(diào)用不能接收既鞠,顯式Intent可以接收蚯姆×淞担或者動態(tài)注冊它碎,然后隱式調(diào)用可以接收扳肛。
如果要接收系統(tǒng)廣播只能動態(tài)注冊。
5套腹、圖標(biāo)適配
在圖標(biāo)適配中有兩個部分,前景圖和背景圖,所以設(shè)計的時候需要提供前景圖和背景圖兩個圖,這樣在不同的廠商無論圖標(biāo)的背景怎么換都是對圖標(biāo)的背景圖進(jìn)行切割,而前景圖是不會變的电禀。
6、權(quán)限
之前對于隱私權(quán)限只要申請一個就會將其在的權(quán)限組全部通過,android 8.0以后申請單個只給單個葫松;
Android 9
1、在 Android 9 中珊擂,不能從非 Activity 環(huán)境中啟動 Activity圣贸,除非您傳遞 Intent 標(biāo)志 FLAG_ACTIVITY_NEW_TASK吁峻。 如果您嘗試在不傳遞此標(biāo)志的情況下啟動 Activity,則該 Activity 不會啟動帮匾,系統(tǒng)會在日志中輸出一則消息缸夹。
2虽惭、前臺服務(wù):針對 Android 9 或更高版本并使用前臺服務(wù)的應(yīng)用必須請求 FOREGROUND_SERVICE 權(quán)限。 這是普通權(quán)限佣蓉,因此疚膊,系統(tǒng)會自動為請求權(quán)限的應(yīng)用授予此權(quán)限寓盗。
3、默認(rèn)情況下啟用網(wǎng)絡(luò)傳輸層安全協(xié)議 (TLS):如果應(yīng)用以 Android 9 或更高版本為目標(biāo)平臺,則默認(rèn)情況下 isCleartextTrafficPermitted() 函數(shù)返回 false库继。 如果您的應(yīng)用需要為特定域名啟用明文榨惰,您必須在應(yīng)用的網(wǎng)絡(luò)安全性配置中針對這些域名將 cleartextTrafficPermitted 顯式設(shè)置為 true琅催。
在 res 目錄下新建xml文件夾,添加network_security_config.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config>
AndroidManifest.xml中的application添加:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="@xml/network_security_config">
...
</application>
</manifest>
4舆床、對非 SDK 接口的限制:現(xiàn)已禁止訪問特定的非 SDK 接口谷暮,無論是直接訪問湿弦,還是通過 JNI 或反射進(jìn)行間接訪問。嘗試訪問受限制的接口時班利,會生成 NoSuchFieldException 和 NoSuchMethodException 之類的錯誤罗标。
5、為改善 Android 9 中的應(yīng)用穩(wěn)定性和數(shù)據(jù)完整性宙拉,應(yīng)用無法再讓多個進(jìn)程共用同一 WebView 數(shù)據(jù)目錄。 此類數(shù)據(jù)目錄一般存儲 Cookie崔步、HTTP 緩存以及其他與網(wǎng)絡(luò)瀏覽有關(guān)的持久性和臨時性存儲。
如果開發(fā)者需要在多進(jìn)程中使用 WebView瑞你,則必須先調(diào)用 WebView.setDataDirectorySuffix() 方法為每個進(jìn)程設(shè)置用于存儲 WebView 數(shù)據(jù)的目錄。若多進(jìn)程 WebView 之間需要共享數(shù)據(jù)虏缸,開發(fā)者需自己通過 IPC 的方式實現(xiàn)甲献。
此外晃洒,若開發(fā)者只想在一個進(jìn)程中使用 WebView慨灭,并且希望嚴(yán)格執(zhí)行這個規(guī)則,可以通過在其他進(jìn)程中調(diào)用 WebView.disableWebView() 方法锥累,這樣其他進(jìn)程創(chuàng)建 WebView 實例就會拋出異常缘挑。
6、在 Android 9 中桶略,Build.SERIAL 始終設(shè)置為 "UNKNOWN" 以保護(hù)用戶的隱私语淘。
如果您的應(yīng)用需要訪問設(shè)備的硬件序列號惶翻,您應(yīng)改為請求 READ_PHONE_STATE 權(quán)限宙暇,然后調(diào)用 getSerial()碉京。
Android10
1厘灼、分區(qū)存儲:
分區(qū)存儲將外部存儲分成兩部分:
(1)App-specific directory (沙盒目錄)
APP只能在Context.getExternalFilesDir()目錄下通過File的方式創(chuàng)建文件,APP卸載的時候,這個目錄下的文件會被刪除计维;無法通過File的方式在其他路徑創(chuàng)建文件。
(2)Public Directory 公共目錄
公共目錄包括:多媒體公共目錄(Photos, Images, Videos, Audio)和下載文件目錄(Downloads)猜敢。
APP可以通過MediaStore或者SAF(System Access Framework)的方式訪問其中的文件懈费。APP卸載后,文件不會被刪除。
Android Q以上移除了WRITE_EXTERNAL_STORAGE權(quán)限荔睹,應(yīng)用不需要這個權(quán)限就可以向沙盒內(nèi)存儲文件翩瓜,也可以通過媒體數(shù)據(jù)庫的方式保存媒體數(shù)據(jù)至特定位置蕊蝗。
App卸載后幢泼,對應(yīng)的沙盒目錄也會被刪除丹允,如果APP想要在卸載時保留沙盒目錄下的數(shù)據(jù),要在AndroidManifest.xml中聲明android:hasFragileUserData="true"百宇,這樣在 APP卸載時就會有彈出框提示用戶是否保留應(yīng)用數(shù)據(jù)评肆。
2、后臺運(yùn)行時訪問設(shè)備位置信息需要權(quán)限
Android 10 引入了 ACCESS_BACKGROUND_LOCATION 權(quán)限(危險權(quán)限)腊瑟。
該權(quán)限允許應(yīng)用程序在后臺訪問位置。如果請求此權(quán)限主慰,則還必須請求ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION權(quán)限情竹。只請求此權(quán)限無效果贡耽。
Android 10中必須具有 ACCESS_FINE_LOCATION 權(quán)限才能使用的類和方法:
電話
TelephonyManager
getCellLocation()
getAllCellInfo()
requestNetworkScan()
requestCellInfoUpdate()
getAvailableNetworks()
getServiceState()
TelephonyScanManager
requestNetworkScan()
TelephonyScanManager.NetworkScanCallback
onResults()
PhoneStateListener
onCellLocationChanged()
onCellInfoChanged()
onServiceStateChanged()
WLAN
WifiManager
startScan()
getScanResults()
getConnectionInfo()
getConfiguredNetworks()
WifiAwareManager
WifiP2pManager
WifiRttManager
藍(lán)牙
BluetoothAdapter
startDiscovery()
startLeScan()
startScan()
BluetoothAdapter.LeScanCallback
BluetoothLeScanner
3像樊、后臺啟動 Activity 的限制
應(yīng)用處于后臺時,無法啟動Activity逸吵。
4凶硅、深色主題
(1)手動適配---資源替換
res 下新建 values-night目錄,創(chuàng)建對應(yīng)的colors.xml文件扫皱。
(2)自動適配---Force Dark
應(yīng)用必須選擇啟用 Force Dark足绅,方法是在其主題背景中設(shè)置 android:forceDarkAllowed="true"。此屬性會在所有系統(tǒng)及 AndroidX 提供的淺色主題背景(例如 Theme.Material.Light)上設(shè)置韩脑。
Force Dark需要注意幾點(diǎn):
- 如果使用的是 DayNight 或 Dark Theme 主題氢妈,則設(shè)置forceDarkAllowed 不生效。
- 如果有需要排除適配的部分段多,可以在對應(yīng)的View上設(shè)置forceDarkAllowed為false首量。
5、標(biāo)識符和數(shù)據(jù)
對不可重置的設(shè)備標(biāo)識符實施了限制
受影響的方法包括:
Build
getSerial()
TelephonyManager
getImei()
getDeviceId()
getMeid()
getSimSerialNumber()
getSubscriberId()
從 Android 10 開始进苍,應(yīng)用必須具有 READ_PRIVILEGED_PHONE_STATE 特許權(quán)限才能正常使用以上這些方法加缘。
如果你的應(yīng)用沒有該權(quán)限,卻仍然使用了以上的方法觉啊,則返回的結(jié)果會因目標(biāo) SDK 版本而異:
- 如果應(yīng)用以 Android 10 或更高版本為目標(biāo)平臺拣宏,則會發(fā)生 SecurityException。
- 如果應(yīng)用以 Android 9(API 級別 28)或更低版本為目標(biāo)平臺杠人,則相應(yīng)方法會返回 null 或占位符數(shù)據(jù)(如果應(yīng)用具有 READ_PHONE_STATE 權(quán)限)勋乾。否則宋下,會發(fā)生 SecurityException。
這項改動表示第三方應(yīng)用無法獲取Device ID這類唯一標(biāo)識辑莫。
6学歧、限制了對剪貼板數(shù)據(jù)的訪問權(quán)限
除非您的應(yīng)用是默認(rèn)輸入法 (IME) 或是目前處于焦點(diǎn)的應(yīng)用,否則它無法訪問 Android 10 或更高版本平臺上的剪貼板數(shù)據(jù)各吨。
7枝笨、對啟用和停用 WLAN 實施了限制
以 Android 10 或更高版本為目標(biāo)平臺的應(yīng)用無法啟用或停用 WLAN。WifiManager.setWifiEnabled()方法始終返回 false绅你。
Android11
1伺帘、分區(qū)存儲強(qiáng)制執(zhí)行
Android 11在分區(qū)存儲基礎(chǔ)上限制了應(yīng)用訪問其他應(yīng)用的文件。
分區(qū)存儲將存儲空間分為兩部分:
公共目錄:Downloads忌锯、Documents伪嫁、Pictures 、DCIM偶垮、Movies张咳、Music、Ringtones等
公共目錄的文件在App卸載后似舵,不會刪除
可以通過SAF脚猾、MediaStore接口訪問
擁有權(quán)限,也能通過路徑直接訪問
應(yīng)用專屬目錄
應(yīng)用專屬目錄只能自己直接訪問
App卸載砚哗,數(shù)據(jù)會清除龙助。
將應(yīng)用更新為以 Android 11 為目標(biāo)平臺后,您將無法使用requestLegacyExternalStorage蛛芥,而且也沒有其他標(biāo)記可以提供停用分區(qū)存儲提鸟。
所有文件訪問權(quán)限MANAGE_EXTERNAL_STORAGE,用來獲取所有文件的管理權(quán)限仅淑。
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
val intent = Intent()
intent.action= Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
startActivity(intent)
//判斷是否獲取MANAGE_EXTERNAL_STORAGE權(quán)限:
val isHasStoragePermission= Environment.isExternalStorageManager()
2称勋、電話號碼相關(guān)權(quán)限
Android 11 更改了應(yīng)用在讀取電話號碼時使用的與電話相關(guān)的權(quán)限。
如果應(yīng)用以 Android 11 或更高版本為目標(biāo)平臺涯竟,并且需要訪問以下列表中顯示的電話號碼 API赡鲜,則必須請求 READ_PHONE_NUMBERS 權(quán)限,而不是 READ_PHONE_STATE 權(quán)限庐船。
- TelephonyManager 類和 TelecomManager 類中的 getLine1Number() 方法银酬。
- TelephonyManager 類中不受支持的 getMsisdn() 方法。
如果應(yīng)用聲明 READ_PHONE_STATE 以調(diào)用前面列表中的方法以外的方法筐钟,可以繼續(xù)在所有 Android 版本中請求 READ_PHONE_STATE揩瞪。不過,如果僅對前面列表中的方法使用 READ_PHONE_STATE 權(quán)限盗棵,請按以下方式更新您的清單文件:
更改 READ_PHONE_STATE 的聲明壮韭,以使應(yīng)用僅在 Android 10(API 級別 29)及更低版本中使用該權(quán)限。
添加 READ_PHONE_NUMBERS 權(quán)限纹因。
<manifest>
<!-- Grants the READ_PHONE_STATE permission only on devices that run
Android 10 (API level 29) and lower. -->
<uses-permission android:name="READ_PHONE_STATE"
android:maxSdkVersion="29" />
<uses-permission android:name="READ_PHONE_NUMBERS" />
</manifest>
3喷屋、自定義消息框視圖被屏蔽
出于安全方面的考慮,同時也為了保持良好的用戶體驗瞭恰,如果包含自定義視圖的消息框是以 Android 11 或更高版本為目標(biāo)平臺的應(yīng)用從后臺發(fā)送的屯曹,系統(tǒng)會屏蔽這些消息框。請注意惊畏,仍允許使用文本消息框恶耽;此類消息框是使用 Toast.makeText() 創(chuàng)建的,并不調(diào)用 setView()颜启。
如果您的應(yīng)用仍嘗試從后臺發(fā)布包含自定義視圖的消息框偷俭,系統(tǒng)不會向用戶顯示相應(yīng)的消息,而是會在 logcat 中記錄以下消息:
W/NotificationService: Blocking custom toast from package \
<package> due to package not in the foreground
消息框回調(diào)
如果您希望在消息框(文本消息框或自定義消息框)出現(xiàn)或消失時收到通知缰盏,請使用 Android 11 中添加的 addCallback() 方法涌萤。
文本消息框 API 變更
以 Android 11 或更高版本為目標(biāo)平臺的應(yīng)用會發(fā)現(xiàn)文本消息框受到以下負(fù)面影響:
- getView() 方法返回 null。
以下方法的返回值并不反映實際值口猜,因此您不應(yīng)在應(yīng)用中依賴于它們:
- getHorizontalMargin()
- getVerticalMargin()
- getGravity()
- getXOffset()
- getYOffset()
以下方法是空操作负溪,因此您的應(yīng)用不應(yīng)使用它們:
- setMargin()
- setGravity()
4、媒體intent操作需要系統(tǒng)默認(rèn)相機(jī)
從 Android 11 開始济炎,只有預(yù)裝的系統(tǒng)相機(jī)應(yīng)用可以響應(yīng)以下 intent 操作:
- android.media.action.VIDEO_CAPTURE
- android.media.action.IMAGE_CAPTURE
- android.media.action.IMAGE_CAPTURE_SECURE
也就是說川抡,如果我調(diào)用intent喚起照相機(jī),使用VIDEO_CAPTURE的action须尚,只有系統(tǒng)的相機(jī)能夠響應(yīng)崖堤,而第三方的相機(jī)應(yīng)用不會響應(yīng)了。
如果要使用特定的第三方相機(jī)應(yīng)用來代表其捕獲圖片或視頻恨闪,可以通過為intent設(shè)置軟件包名稱或組件來使這些intent變得明確倘感。
5、5G
Android 11 添加了在您的應(yīng)用中支持 5G 的功能咙咽。
新的Android11也是支持了5G相關(guān)的一些功能老玛,包括:
- 檢測是否連接到了5G網(wǎng)絡(luò)
- 檢查按流量計費(fèi)性
檢測5G網(wǎng)絡(luò),通過TelephonyManager的監(jiān)聽方法:
private fun getNetworkType(){
val tManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
tManager.listen(object : PhoneStateListener() {
@RequiresApi(Build.VERSION_CODES.R)
override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
if (ActivityCompat.checkSelfPermission(this@Android11Test2Activity, android.Manifest.permission.READ_PHONE_STATE) != android.content.pm.PackageManager.PERMISSION_GRANTED) {
return
}
super.onDisplayInfoChanged(telephonyDisplayInfo)
when(telephonyDisplayInfo.networkType) {
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO -> showToast("高級專業(yè)版 LTE (5Ge)")
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA -> showToast("NR (5G) - 5G Sub-6 網(wǎng)絡(luò)")
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> showToast("5G+/5G UW - 5G mmWave 網(wǎng)絡(luò)")
else -> showToast("other")
}
}
}, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
}
檢測流量計費(fèi)方法钧敞,監(jiān)聽網(wǎng)絡(luò)蜡豹,在回調(diào)中判斷:
val manager = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
manager.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
super.onCapabilitiesChanged(network, networkCapabilities)
//true 代表連接不按流量計費(fèi)
val isNotFlowPay=networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) ||
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)
}
})
6、后臺位置信息訪問權(quán)限
在搭載 Android 11 的設(shè)備上溉苛,當(dāng)應(yīng)用中的某項功能請求在后臺訪問位置信息時镜廉,用戶看到的系統(tǒng)對話框不再包含用于啟用后臺位置信息訪問權(quán)限的按鈕。如需啟用后臺位置信息訪問權(quán)限愚战,用戶必須在設(shè)置頁面上針對應(yīng)用的位置權(quán)限設(shè)置一律允許選項娇唯。
7齐遵、軟件包可見性
Android 11 更改了應(yīng)用查詢用戶已在設(shè)備上安裝的其他應(yīng)用以及與之交互的方式。使用 <queries> 元素塔插,應(yīng)用可以定義一組自身可訪問的其他軟件包梗摇。通過告知系統(tǒng)應(yīng)向應(yīng)用顯示哪些其他軟件包,此元素有助于鼓勵最小權(quán)限原則想许。此外伶授,此元素還可幫助 Google Play 等應(yīng)用商店評估應(yīng)用為用戶提供的隱私權(quán)和安全性。
如果應(yīng)用以 Android 11 或更高版本為目標(biāo)平臺流纹,您可能需要在應(yīng)用的清單文件中添加 <queries> 元素糜烹。在 <queries> 元素中,您可以按軟件包名稱漱凝、intent 簽名或提供程序授權(quán)指定軟件包疮蹦。
8、前臺服務(wù)類型
從 Android 9 開始碉哑,應(yīng)用僅限于在前臺訪問攝像頭和麥克風(fēng)挚币。為了進(jìn)一步保護(hù)用戶,Android 11 更改了前臺服務(wù)訪問攝像頭和麥克風(fēng)相關(guān)數(shù)據(jù)的方式扣典。如果您的應(yīng)用以 Android 11 為目標(biāo)平臺并且在某項前臺服務(wù)中訪問這些類型的數(shù)據(jù)妆毕,您需要在該前臺服務(wù)的聲明的 foregroundServiceType 屬性中添加新的 camera 和 microphone 類型。
應(yīng)用某項前臺服務(wù)需要訪問位置信息贮尖、攝像頭和麥克風(fēng)笛粘,那么就要在清單文件中這樣添加:
<manifest>
<service ...
android:foregroundServiceType="location|camera|microphone" />
</manifest>
Android 12
1、SplashScreen
從 Android 12 開始湿硝,在搭載 Android 12 或更高版本的設(shè)備上運(yùn)行時薪前,所有應(yīng)用都將擁有啟動動畫。這包括啟動時的進(jìn)入應(yīng)用動作关斜、顯示應(yīng)用圖標(biāo)的啟動畫面示括,以及向應(yīng)用本身的過渡。
(1)應(yīng)用圖標(biāo)應(yīng)該是矢量可繪制對象(AVD XML)痢畜,它可以是靜態(tài)或動畫形式垛膝。雖然動畫的時長可以不受限制,但我們建議不超過1,000 毫秒丁稀。默認(rèn)情況下吼拥,使用啟動器圖標(biāo)。
(2)可以選擇添加圖標(biāo)背景线衫;在圖標(biāo)與窗口背景之間需要更高的對比度時圖標(biāo)背景很有用凿可。如果您使用一個自適應(yīng)圖標(biāo),當(dāng)該圖標(biāo)與窗口背景之間的對比度足夠高時授账,就會顯示其背景枯跑。
(3)與自適應(yīng)圖標(biāo)一樣惨驶,前景的三分之一被遮蓋。
(4)窗口背景由不透明的單色組成敛助。如果窗口背景已設(shè)置且為純色敞咧,則未設(shè)置相應(yīng)的屬性時默認(rèn)使用該背景。
2辜腺、更安全的組件導(dǎo)出
以Android 12為目標(biāo)平臺的App,如果其包含的四大組件中使用到了Intent過濾器(intent-filter)乍恐,則必須顯式聲明 android:exported 屬性评疗,否則App將無法在Android 12及更高系統(tǒng)版本的設(shè)備上安裝。
3茵烈、定位權(quán)限:大概位置
如果您的應(yīng)用請求ACCESS_COARSE_LOCATION但未請求ACCESS_FINE_LOCATION百匆,則此變更不會影響您的應(yīng)用。
如果您的應(yīng)用請求ACCESS_FINE_LOCATION 運(yùn)行時權(quán)限呜投,您還應(yīng)請求ACCESS_COARSE_LOCATION權(quán)限加匈,以便處理用戶授予應(yīng)用大致位置訪問權(quán)限的情形。
4仑荐、PendingIntent可變性
如果您的應(yīng)用程序以Android 12為目標(biāo)平臺雕拼,您必須為應(yīng)用創(chuàng)建的每個 PendingIntent 對象指定可變性。這項額外的要求可提高應(yīng)用的安全性粘招。因為三方app可以通過劫持PendingIntent啥寇,然后改寫里面的action、category洒扎、data等辑甜,造成重定向攻擊。
適配的具體就是在創(chuàng)建 PendingIntent時袍冷,使用 PendingIntent.FLAG_MUTABLE 或 PendingIntent.FLAG_IMMUTABLE 標(biāo)志磷醋。否則運(yùn)行時會報IllegalArgumentException。
5胡诗、藍(lán)牙權(quán)限
如果您的應(yīng)用程序面向Android 12或更高版本邓线,使用藍(lá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)褂痰。
對于以前的與藍(lán)牙相關(guān)的權(quán)限聲明,設(shè)置android:maxSdkVersion到30症虑。此應(yīng)用兼容性步驟可幫助系統(tǒng)僅授予您的應(yīng)用在運(yùn)行Android 12 的設(shè)備上安裝時所需的藍(lán)牙權(quán)限缩歪。
<manifest>
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- 只有當(dāng)您的應(yīng)用程序使用藍(lán)牙掃描結(jié)果來獲取物理位置時才需要 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
...
</manifest>
如果您的應(yīng)用程序使用藍(lán)牙掃描結(jié)果來獲取物理位置,請聲明ACCESS_FINE_LOCATION谍憔。以前版本中(6.0 ~ 11)是必須申請定位權(quán)限匪蝙,才可以進(jìn)行藍(lán)牙掃描主籍。
在Android 12上,如果你的應(yīng)用程序不使用藍(lán)牙掃描結(jié)果來獲取物理位置逛球∏г可以添加android:usesPermissionFlags屬性到您的BLUETOOTH_SCAN權(quán)限聲明,并將該屬性的值設(shè)置為neverForLocation颤绕。
<manifest>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<!--可以刪除定位權(quán)限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
...
</manifest>
Android13
1幸海、細(xì)化的媒體權(quán)限
如果應(yīng)用以 Android 13 或更高版本為目標(biāo)平臺,并且需要訪問其他應(yīng)用已經(jīng)創(chuàng)建的媒體文件奥务,必須請求以下一項或多項細(xì)化的媒體權(quán)限物独,而不是READ_EXTERNAL_STORAGE 權(quán)限:
| 媒體類型 | 請求權(quán)限 |
| 圖片和照片 | READ_MEDIA_IAMGES |
| 視頻 | READ_MEDIA_VIDEO |
| 音頻文件 | READ_MEDIA_AUDIO |
如果用戶之前向您的應(yīng)用授予了 READ_EXTERNAL_STORAGE 權(quán)限,系統(tǒng)會自動向您的應(yīng)用授予細(xì)化的媒體權(quán)限氯葬。否則挡篓,當(dāng)應(yīng)用請求上表中顯示的任何權(quán)限時,系統(tǒng)會顯示面向用戶的對話框帚称。
<manifest ...>
<!-- Required only if your app targets Android 13\. -->
<!-- Declare one or more the following permissions only if your app needs
to access data that's protected by them. -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- Required to maintain app compatibility. -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<application ...>
...
</application>
</manifest>
2官研、通知運(yùn)行時權(quán)限
在AndroidManifest.xml中對發(fā)送通知權(quán)限進(jìn)行聲明:
<manifest ...>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application ...>
...
</application>
</manifest>
POST_NOTIFICATIONS權(quán)限只有在應(yīng)用程序的targetSdk指定成33或更高時才會有用。
要確認(rèn)用戶是否已啟用通知闯睹,請調(diào)用 areNotificationsEnabled()戏羽。
3、通知權(quán)限會影響前臺服務(wù)的顯示
如果用戶拒絕授予通知權(quán)限楼吃,就不會在抽屜式通知欄中看到與前臺服務(wù)相關(guān)的通知蛛壳。 不過,無論是否授予通知權(quán)限所刀,用戶都會在前臺服務(wù) (FGS) 任務(wù)管理器中看到與前臺服務(wù)相關(guān)的通知衙荐。
4、WebView
從Android 13開始浮创,以Android13(API 33+)為目標(biāo)平臺的應(yīng)用忧吟,WebView存在以下方法與API調(diào)整:
- WebSettings.setAppCacheEnabled() 方法廢棄。
- WebSettings.setForceDark() 方法廢棄斩披。
4溜族、靜態(tài)廣播注冊
從Android 13開始,以Android13(API 33+)為目標(biāo)平臺的應(yīng)用垦沉,注冊靜態(tài)廣播時煌抒,需設(shè)置對其他應(yīng)用的可見性:
- 若對其他應(yīng)用可見,廣播注冊時設(shè)置:Context.RECEIVER_EXPORTED
- 若僅應(yīng)用內(nèi)使用厕倍,廣播注冊時設(shè)置:Context.RECEIVER_NOT_EXPORTED
private void registerTestReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction("com.xiaxl.test.action");
// api >= 33
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
// 跨應(yīng)用間使用
MainActivity.this.registerReceiver(mTestReceiver, filter, Context.RECEIVER_EXPORTED);
// 應(yīng)用內(nèi)使用
//MainActivity.this.registerReceiver(mTestReceiver, filter, Context.RECEIVER_EXPORTED);
}
// api <= 32
else {
MainActivity.this.registerReceiver(mTestReceiver, filter);
}
}
目前該增強(qiáng)措施并非默認(rèn)生效寡壮,開發(fā)者需啟用 DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED兼容性框架,并在動態(tài)注冊廣播時指定是否接受其他應(yīng)用的廣播。
如果啟用了 DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED 兼容性框架更改况既,則必須為每個廣播接收器指定 RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED这溅。否則,當(dāng)您嘗試注冊廣播接收器時棒仍,系統(tǒng)會拋出 SecurityException悲靴。
5、Wi-Fi 權(quán)限
在以前的 Android 版本中莫其,用戶需要向您的應(yīng)用授予 在以前的 Android 版本中癞尚,用戶需要向您的應(yīng)用授予 ACCESS_FINE_LOCATION 權(quán)限,應(yīng)用才能完成一些常見的 Wi-Fi 用例乱陡。
由于用戶很難將位置信息權(quán)限與 Wi-Fi 功能相關(guān)聯(lián)否纬,因此 Android 13(API 級別 33)在 NEARBY_DEVICES 權(quán)限組中引入了運(yùn)行時權(quán)限,適用于管理設(shè)備與附近 Wi-Fi 接入點(diǎn)連接情況的應(yīng)用蛋褥。此權(quán)限 (NEARBY_WIFI_DEVICES) 可滿足以下 Wi-Fi 用例:
查找或連接到附近的設(shè)備,如打印機(jī)或媒體投射設(shè)備睛驳。通過該工作流烙心,您的應(yīng)用可以完成以下類型的任務(wù):
通過帶外方式(例如通過 BLE)接收 AP 信息。
使用僅限本地使用的熱點(diǎn)乏沸,通過 Wi-Fi 感知和連接功能發(fā)現(xiàn)并連接到設(shè)備淫茵。
通過 Wi-Fi 直連發(fā)現(xiàn)和連接到設(shè)備。
發(fā)起與已知 SSID(例如汽車或智能家居設(shè)備)的連接蹬跃。
開啟僅限本地使用的熱點(diǎn)匙瘪。
連接到附近的 Wi-Fi 感知設(shè)備。
6蝶缀、在后臺使用身體傳感器需要新的權(quán)限
Android 13 中引入了“在使用時”訪問身體傳感器(例如心率丹喻、體溫和血氧飽和度)的概念。
如果您的應(yīng)用以 Android 13 為目標(biāo)平臺翁都,并且在后臺運(yùn)行時需要訪問身體傳感器信息碍论,那么除了現(xiàn)有的 BODY_SENSORS 權(quán)限外,您還必須聲明新的 BODY_SENSORS_BACKGROUND 權(quán)限柄慰。