Android 6
1、運行時權限
android6.0以前,我們把app需要用到的權限全部羅列在Manifest清單文件中。安裝app時android系統(tǒng)會詢問用戶是否授予這些權限,拒絕后則無法安裝app。如果授予,則安裝app,之后無法修改授予狀態(tài)。
android6.0將權限分為普通權限(不涉及用戶隱私和安全)和危險權限(設計用戶隱私和安全)。普通權限和andorid6.0之前一樣,在Manifest清單文件中申請即可。危險權限需要在使用時動態(tài)申請,由用戶決定是否授予。
危險權限分組:

2、HttpClient的移除
自Android6.0起,HttpClient系列代碼從SDK中剔除,推薦使用HttpURLConnection。
Android 7
1、應用間共享文件
對于面向 Android 7.0 的應用,Android 框架執(zhí)行的 StrictMode API 政策禁止在您的應用外部公開 file:// URI。如果一項包含文件 URI 的 intent 離開您的應用,則應用出現(xiàn)故障,并出現(xiàn) FileUriExposedException 異常。
要在應用間共享文件,您應發(fā)送一項 content:// URI,并授予 URI 臨時訪問權限。進行此授權的最簡單方式是使用 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:文件夾“相對路徑”,完整路徑取決于當前的標簽類型。
<external-path/> 代表Environment.getExternalStorageDirectory()
<files-path/> 代表context.getFilesDir()
<cache-path/> 代表context.getCacheDir()
<external-files-path>代表context.getExternalFilesDirs()
<external-cache-path>代表getExternalCacheDirs()
<root-path/> 代表設備的根目錄new File("/");
7.0之前跳轉到系統(tǒng)相機拍照的代碼,需要提前設定好保存圖片的uri,跳轉到相機應用
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ā)的應用不會收到 CONNECTIVITY_ACTION 廣播,即使它們已有清單條目來請求接受這些事件的通知。在主線程中通過Context.registerReceiver()動態(tài)注冊了CONNECTIVITY_ACTION廣播,該應用程序仍然可以接收到該廣播。
應用無法發(fā)送或接收 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO 廣播。此項優(yōu)化會影響所有應用,而不僅僅是面向 Android 7.0 的應用。
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
//構建通知渠道
val channel = NotificationChannel(channelId, channelName, importance)
//設置通知渠道描述
channel.description = ""
//向系統(tǒng)注冊通知渠道,注冊后則不能修改重要性以及其他通知行為,但可以刪除
notificationManager.createNotificationChannel(channel)
}
val notification = NotificationCompat.Builder(this, "channelId")
.setContentTitle("標題")
.setContentText("消息內(nèi)容")
.setSmallIcon(R.drawable.ic_launcher_background)
.setAutoCancel(true)//點擊自動消失
.build()
//通知id,每個通知都應該不同否則會覆蓋
val notifyId = 1
notificationManager.notify(notifyId, notification)
2、后臺執(zhí)行限制
如果針對 Android 8.0 的應用嘗試在不允許其創(chuàng)建后臺服務的情況下使用 startService() 函數(shù),則該函數(shù)將引發(fā)一個 IllegalStateException。
新的 Context.startForegroundService() 函數(shù)將啟動一個前臺服務?,F(xiàn)在,即使應用在后臺運行,系統(tǒng)也允許其調(diào)用 Context.startForegroundService()。不過,應用必須在創(chuàng)建服務后的五秒內(nèi)調(diào)用該服務的 startForeground() 函數(shù)。
3、允許安裝未知來源應用
8.0 的應用需要在 AndroidManifest.xml 中聲明 REQUEST_INSTALL_PACKAGES 權限,否則將無法進行應用內(nèi)升級。
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
4、隱式廣播的限制
我們自己定義的廣播隱式調(diào)用不能接收,顯式Intent可以接收?;蛘邉討B(tài)注冊,然后隱式調(diào)用可以接收。
如果要接收系統(tǒng)廣播只能動態(tài)注冊。
5、圖標適配
在圖標適配中有兩個部分,前景圖和背景圖,所以設計的時候需要提供前景圖和背景圖兩個圖,這樣在不同的廠商無論圖標的背景怎么換都是對圖標的背景圖進行切割,而前景圖是不會變的。
6、權限
之前對于隱私權限只要申請一個就會將其在的權限組全部通過,android 8.0以后申請單個只給單個;
Android 9
1、在 Android 9 中,不能從非 Activity 環(huán)境中啟動 Activity,除非您傳遞 Intent 標志 FLAG_ACTIVITY_NEW_TASK。 如果您嘗試在不傳遞此標志的情況下啟動 Activity,則該 Activity 不會啟動,系統(tǒng)會在日志中輸出一則消息。
2、前臺服務:針對 Android 9 或更高版本并使用前臺服務的應用必須請求 FOREGROUND_SERVICE 權限。 這是普通權限,因此,系統(tǒng)會自動為請求權限的應用授予此權限。
3、默認情況下啟用網(wǎng)絡傳輸層安全協(xié)議 (TLS):如果應用以 Android 9 或更高版本為目標平臺,則默認情況下 isCleartextTrafficPermitted() 函數(shù)返回 false。 如果您的應用需要為特定域名啟用明文,您必須在應用的網(wǎng)絡安全性配置中針對這些域名將 cleartextTrafficPermitted 顯式設置為 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 或反射進行間接訪問。嘗試訪問受限制的接口時,會生成 NoSuchFieldException 和 NoSuchMethodException 之類的錯誤。
5、為改善 Android 9 中的應用穩(wěn)定性和數(shù)據(jù)完整性,應用無法再讓多個進程共用同一 WebView 數(shù)據(jù)目錄。 此類數(shù)據(jù)目錄一般存儲 Cookie、HTTP 緩存以及其他與網(wǎng)絡瀏覽有關的持久性和臨時性存儲。
如果開發(fā)者需要在多進程中使用 WebView,則必須先調(diào)用 WebView.setDataDirectorySuffix() 方法為每個進程設置用于存儲 WebView 數(shù)據(jù)的目錄。若多進程 WebView 之間需要共享數(shù)據(jù),開發(fā)者需自己通過 IPC 的方式實現(xiàn)。
此外,若開發(fā)者只想在一個進程中使用 WebView,并且希望嚴格執(zhí)行這個規(guī)則,可以通過在其他進程中調(diào)用 WebView.disableWebView() 方法,這樣其他進程創(chuàng)建 WebView 實例就會拋出異常。
6、在 Android 9 中,Build.SERIAL 始終設置為 "UNKNOWN" 以保護用戶的隱私。
如果您的應用需要訪問設備的硬件序列號,您應改為請求 READ_PHONE_STATE 權限,然后調(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權限,應用不需要這個權限就可以向沙盒內(nèi)存儲文件,也可以通過媒體數(shù)據(jù)庫的方式保存媒體數(shù)據(jù)至特定位置。
App卸載后,對應的沙盒目錄也會被刪除,如果APP想要在卸載時保留沙盒目錄下的數(shù)據(jù),要在AndroidManifest.xml中聲明android:hasFragileUserData="true",這樣在 APP卸載時就會有彈出框提示用戶是否保留應用數(shù)據(jù)。
2、后臺運行時訪問設備位置信息需要權限
Android 10 引入了 ACCESS_BACKGROUND_LOCATION 權限(危險權限)。
該權限允許應用程序在后臺訪問位置。如果請求此權限,則還必須請求ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION權限。只請求此權限無效果。
Android 10中必須具有 ACCESS_FINE_LOCATION 權限才能使用的類和方法:
電話
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
藍牙
BluetoothAdapter
startDiscovery()
startLeScan()
startScan()
BluetoothAdapter.LeScanCallback
BluetoothLeScanner
3、后臺啟動 Activity 的限制
應用處于后臺時,無法啟動Activity。
4、深色主題
(1)手動適配---資源替換
res 下新建 values-night目錄,創(chuàng)建對應的colors.xml文件。
(2)自動適配---Force Dark
應用必須選擇啟用 Force Dark,方法是在其主題背景中設置 android:forceDarkAllowed="true"。此屬性會在所有系統(tǒng)及 AndroidX 提供的淺色主題背景(例如 Theme.Material.Light)上設置。
Force Dark需要注意幾點:
如果使用的是 DayNight 或 Dark Theme 主題,則設置forceDarkAllowed 不生效。
如果有需要排除適配的部分,可以在對應的View上設置forceDarkAllowed為false。
5、標識符和數(shù)據(jù)
對不可重置的設備標識符實施了限制
受影響的方法包括:
Build
getSerial()
TelephonyManager
getImei()
getDeviceId()
getMeid()
getSimSerialNumber()
getSubscriberId()
從 Android 10 開始,應用必須具有 READ_PRIVILEGED_PHONE_STATE 特許權限才能正常使用以上這些方法。
如果你的應用沒有該權限,卻仍然使用了以上的方法,則返回的結果會因目標 SDK 版本而異:
如果應用以 Android 10 或更高版本為目標平臺,則會發(fā)生 SecurityException。
如果應用以 Android 9(API 級別 28)或更低版本為目標平臺,則相應方法會返回 null 或占位符數(shù)據(jù)(如果應用具有 READ_PHONE_STATE 權限)。否則,會發(fā)生 SecurityException。
這項改動表示第三方應用無法獲取Device ID這類唯一標識。
6、限制了對剪貼板數(shù)據(jù)的訪問權限
除非您的應用是默認輸入法 (IME) 或是目前處于焦點的應用,否則它無法訪問 Android 10 或更高版本平臺上的剪貼板數(shù)據(jù)。
7、對啟用和停用 WLAN 實施了限制
以 Android 10 或更高版本為目標平臺的應用無法啟用或停用 WLAN。WifiManager.setWifiEnabled()方法始終返回 false。
Android11
1、分區(qū)存儲強制執(zhí)行
Android 11在分區(qū)存儲基礎上限制了應用訪問其他應用的文件。
分區(qū)存儲將存儲空間分為兩部分:
公共目錄:Downloads、Documents、Pictures 、DCIM、Movies、Music、Ringtones等
公共目錄的文件在App卸載后,不會刪除
可以通過SAF、MediaStore接口訪問
擁有權限,也能通過路徑直接訪問
應用專屬目錄
應用專屬目錄只能自己直接訪問
App卸載,數(shù)據(jù)會清除。
將應用更新為以 Android 11 為目標平臺后,您將無法使用requestLegacyExternalStorage,而且也沒有其他標記可以提供停用分區(qū)存儲。
所有文件訪問權限MANAGE_EXTERNAL_STORAGE,用來獲取所有文件的管理權限。
<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權限:
val isHasStoragePermission= Environment.isExternalStorageManager()
2、電話號碼相關權限
Android 11 更改了應用在讀取電話號碼時使用的與電話相關的權限。
如果應用以 Android 11 或更高版本為目標平臺,并且需要訪問以下列表中顯示的電話號碼 API,則必須請求 READ_PHONE_NUMBERS 權限,而不是 READ_PHONE_STATE 權限。
TelephonyManager 類和 TelecomManager 類中的 getLine1Number() 方法。
TelephonyManager 類中不受支持的 getMsisdn() 方法。
如果應用聲明 READ_PHONE_STATE 以調(diào)用前面列表中的方法以外的方法,可以繼續(xù)在所有 Android 版本中請求 READ_PHONE_STATE。不過,如果僅對前面列表中的方法使用 READ_PHONE_STATE 權限,請按以下方式更新您的清單文件:
更改 READ_PHONE_STATE 的聲明,以使應用僅在 Android 10(API 級別 29)及更低版本中使用該權限。
添加 READ_PHONE_NUMBERS 權限。
<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 或更高版本為目標平臺的應用從后臺發(fā)送的,系統(tǒng)會屏蔽這些消息框。請注意,仍允許使用文本消息框;此類消息框是使用 Toast.makeText() 創(chuàng)建的,并不調(diào)用 setView()。
如果您的應用仍嘗試從后臺發(fā)布包含自定義視圖的消息框,系統(tǒ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 或更高版本為目標平臺的應用會發(fā)現(xiàn)文本消息框受到以下負面影響:
getView() 方法返回 null。
以下方法的返回值并不反映實際值,因此您不應在應用中依賴于它們:
getHorizontalMargin()
getVerticalMargin()
getGravity()
getXOffset()
getYOffset()
以下方法是空操作,因此您的應用不應使用它們:
setMargin()
setGravity()
4、媒體intent操作需要系統(tǒng)默認相機
從 Android 11 開始,只有預裝的系統(tǒng)相機應用可以響應以下 intent 操作:
android.media.action.VIDEO_CAPTURE
android.media.action.IMAGE_CAPTURE
android.media.action.IMAGE_CAPTURE_SECURE
也就是說,如果我調(diào)用intent喚起照相機,使用VIDEO_CAPTURE的action,只有系統(tǒng)的相機能夠響應,而第三方的相機應用不會響應了。
如果要使用特定的第三方相機應用來代表其捕獲圖片或視頻,可以通過為intent設置軟件包名稱或組件來使這些intent變得明確。
5、5G
Android 11 添加了在您的應用中支持 5G 的功能。
新的Android11也是支持了5G相關的一些功能,包括:
檢測是否連接到了5G網(wǎng)絡
檢查按流量計費性
檢測5G網(wǎng)絡,通過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)絡")
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> showToast("5G+/5G UW - 5G mmWave 網(wǎng)絡")
else -> showToast("other")
}
}
}, PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
}
檢測流量計費方法,監(jiān)聽網(wǎng)絡,在回調(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 代表連接不按流量計費
val isNotFlowPay=networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) ||
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)
}
})
6、后臺位置信息訪問權限
在搭載 Android 11 的設備上,當應用中的某項功能請求在后臺訪問位置信息時,用戶看到的系統(tǒng)對話框不再包含用于啟用后臺位置信息訪問權限的按鈕。如需啟用后臺位置信息訪問權限,用戶必須在設置頁面上針對應用的位置權限設置一律允許選項。
7、軟件包可見性
Android 11 更改了應用查詢用戶已在設備上安裝的其他應用以及與之交互的方式。使用 <queries> 元素,應用可以定義一組自身可訪問的其他軟件包。通過告知系統(tǒng)應向應用顯示哪些其他軟件包,此元素有助于鼓勵最小權限原則。此外,此元素還可幫助 Google Play 等應用商店評估應用為用戶提供的隱私權和安全性。
如果應用以 Android 11 或更高版本為目標平臺,您可能需要在應用的清單文件中添加 <queries> 元素。在 <queries> 元素中,您可以按軟件包名稱、intent 簽名或提供程序授權指定軟件包。
8、前臺服務類型
從 Android 9 開始,應用僅限于在前臺訪問攝像頭和麥克風。為了進一步保護用戶,Android 11 更改了前臺服務訪問攝像頭和麥克風相關數(shù)據(jù)的方式。如果您的應用以 Android 11 為目標平臺并且在某項前臺服務中訪問這些類型的數(shù)據(jù),您需要在該前臺服務的聲明的 foregroundServiceType 屬性中添加新的 camera 和 microphone 類型。
應用某項前臺服務需要訪問位置信息、攝像頭和麥克風,那么就要在清單文件中這樣添加:
<manifest>
<service ...
android:foregroundServiceType="location|camera|microphone" />
</manifest>
Android 12
1、SplashScreen
從 Android 12 開始,在搭載 Android 12 或更高版本的設備上運行時,所有應用都將擁有啟動動畫。這包括啟動時的進入應用動作、顯示應用圖標的啟動畫面,以及向應用本身的過渡。

(1)應用圖標應該是矢量可繪制對象(AVD XML),它可以是靜態(tài)或動畫形式。雖然動畫的時長可以不受限制,但我們建議不超過1,000 毫秒。默認情況下,使用啟動器圖標。
(2)可以選擇添加圖標背景;在圖標與窗口背景之間需要更高的對比度時圖標背景很有用。如果您使用一個自適應圖標,當該圖標與窗口背景之間的對比度足夠高時,就會顯示其背景。
(3)與自適應圖標一樣,前景的三分之一被遮蓋。
(4)窗口背景由不透明的單色組成。如果窗口背景已設置且為純色,則未設置相應的屬性時默認使用該背景。
2、更安全的組件導出
以Android 12為目標平臺的App,如果其包含的四大組件中使用到了Intent過濾器(intent-filter),則必須顯式聲明 android:exported 屬性,否則App將無法在Android 12及更高系統(tǒng)版本的設備上安裝。
3、定位權限:大概位置
如果您的應用請求ACCESS_COARSE_LOCATION但未請求ACCESS_FINE_LOCATION,則此變更不會影響您的應用。
如果您的應用請求ACCESS_FINE_LOCATION 運行時權限,您還應請求ACCESS_COARSE_LOCATION權限,以便處理用戶授予應用大致位置訪問權限的情形。
4、PendingIntent可變性
如果您的應用程序以Android 12為目標平臺,您必須為應用創(chuàng)建的每個 PendingIntent 對象指定可變性。這項額外的要求可提高應用的安全性。因為三方app可以通過劫持PendingIntent,然后改寫里面的action、category、data等,造成重定向攻擊。
適配的具體就是在創(chuàng)建 PendingIntent時,使用 PendingIntent.FLAG_MUTABLE 或 PendingIntent.FLAG_IMMUTABLE 標志。否則運行時會報IllegalArgumentException。
5、藍牙權限
如果您的應用程序面向Android 12或更高版本,使用藍牙功能時請在應用程序的清單文件中聲明以下權限:
BLUETOOTH_SCAN:允許藍牙設備掃描。
BLUETOOTH_CONNECT:允許藍牙設備連接。
BLUETOOTH_ADVERTISE:允許當前藍牙設備可以被其他藍牙設備發(fā)現(xiàn)。
對于以前的與藍牙相關的權限聲明,設置android:maxSdkVersion到30。此應用兼容性步驟可幫助系統(tǒng)僅授予您的應用在運行Android 12 的設備上安裝時所需的藍牙權限。
<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" />
<!-- 只有當您的應用程序使用藍牙掃描結果來獲取物理位置時才需要 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
...
</manifest>
如果您的應用程序使用藍牙掃描結果來獲取物理位置,請聲明ACCESS_FINE_LOCATION。以前版本中(6.0 ~ 11)是必須申請定位權限,才可以進行藍牙掃描。
在Android 12上,如果你的應用程序不使用藍牙掃描結果來獲取物理位置??梢蕴砑觓ndroid:usesPermissionFlags屬性到您的BLUETOOTH_SCAN權限聲明,并將該屬性的值設置為neverForLocation。
<manifest>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<!--可以刪除定位權限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
...
</manifest>
Android13
1、細化的媒體權限
如果應用以 Android 13 或更高版本為目標平臺,并且需要訪問其他應用已經(jīng)創(chuàng)建的媒體文件,必須請求以下一項或多項細化的媒體權限,而不是READ_EXTERNAL_STORAGE 權限:
媒體類型 |
請求權限 |
圖片和照片 |
READ_MEDIA_IAMGES |
視頻 |
READ_MEDIA_VIDEO |
音頻文件 |
READ_MEDIA_AUDIO |
如果用戶之前向您的應用授予了 READ_EXTERNAL_STORAGE 權限,系統(tǒng)會自動向您的應用授予細化的媒體權限。否則,當應用請求上表中顯示的任何權限時,系統(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、通知運行時權限
在AndroidManifest.xml中對發(fā)送通知權限進行聲明:
<manifest ...>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application ...>
...
</application>
</manifest>
POST_NOTIFICATIONS權限只有在應用程序的targetSdk指定成33或更高時才會有用。
要確認用戶是否已啟用通知,請調(diào)用 areNotificationsEnabled()。
3、通知權限會影響前臺服務的顯示
如果用戶拒絕授予通知權限,就不會在抽屜式通知欄中看到與前臺服務相關的通知。 不過,無論是否授予通知權限,用戶都會在前臺服務 (FGS) 任務管理器中看到與前臺服務相關的通知。
4、WebView
從Android 13開始,以Android13(API 33+)為目標平臺的應用,WebView存在以下方法與API調(diào)整:
WebSettings.setAppCacheEnabled() 方法廢棄。
WebSettings.setForceDark() 方法廢棄。
4、靜態(tài)廣播注冊
從Android 13開始,以Android13(API 33+)為目標平臺的應用,注冊靜態(tài)廣播時,需設置對其他應用的可見性:
若對其他應用可見,廣播注冊時設置:Context.RECEIVER_EXPORTED
若僅應用內(nèi)使用,廣播注冊時設置: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) {
// 跨應用間使用
MainActivity.this.registerReceiver(mTestReceiver, filter, Context.RECEIVER_EXPORTED);
// 應用內(nèi)使用
//MainActivity.this.registerReceiver(mTestReceiver, filter, Context.RECEIVER_EXPORTED);
}
// api <= 32
else {
MainActivity.this.registerReceiver(mTestReceiver, filter);
}
}
目前該增強措施并非默認生效,開發(fā)者需啟用 DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED兼容性框架,并在動態(tài)注冊廣播時指定是否接受其他應用的廣播。
如果啟用了 DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED 兼容性框架更改,則必須為每個廣播接收器指定 RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED。否則,當您嘗試注冊廣播接收器時,系統(tǒng)會拋出 SecurityException。
5、Wi-Fi 權限
在以前的 Android 版本中,用戶需要向您的應用授予 在以前的 Android 版本中,用戶需要向您的應用授予 ACCESS_FINE_LOCATION 權限,應用才能完成一些常見的 Wi-Fi 用例。
由于用戶很難將位置信息權限與 Wi-Fi 功能相關聯(lián),因此 Android 13(API 級別 33)在 NEARBY_DEVICES 權限組中引入了運行時權限,適用于管理設備與附近 Wi-Fi 接入點連接情況的應用。此權限 (NEARBY_WIFI_DEVICES) 可滿足以下 Wi-Fi 用例:
查找或連接到附近的設備,如打印機或媒體投射設備。通過該工作流,您的應用可以完成以下類型的任務:
通過帶外方式(例如通過 BLE)接收 AP 信息。
使用僅限本地使用的熱點,通過 Wi-Fi 感知和連接功能發(fā)現(xiàn)并連接到設備。
通過 Wi-Fi 直連發(fā)現(xiàn)和連接到設備。
發(fā)起與已知 SSID(例如汽車或智能家居設備)的連接。
開啟僅限本地使用的熱點。
連接到附近的 Wi-Fi 感知設備。
6、在后臺使用身體傳感器需要新的權限
Android 13 中引入了“在使用時”訪問身體傳感器(例如心率、體溫和血氧飽和度)的概念。文章來源:http://www.zghlxwxcb.cn/news/detail-781573.html
如果您的應用以 Android 13 為目標平臺,并且在后臺運行時需要訪問身體傳感器信息,那么除了現(xiàn)有的 BODY_SENSORS 權限外,您還必須聲明新的 BODY_SENSORS_BACKGROUND 權限。文章來源地址http://www.zghlxwxcb.cn/news/detail-781573.html
到了這里,關于Android(6-13)適配的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!