一、Android 14——34 適配[詳細地址]https://juejin.cn/post/7231835495557890106
1、對隱式 intent 和待處理 intent 的限制
隱式 intent 只能傳送到導出的組件。應用必須使用顯式 intent 傳送到未導出的組件 帶包名的去跳轉,或將該組件標記為已導出。如果應用通過未指定組件或軟件包的 intent 創(chuàng)建可變待處理 intent,系統(tǒng)現(xiàn)在會拋出異常。
<activity
android:name=".AppActivity"
android:exported="false"> //false 不可導出 true可導出
<intent-filter>
<action android:name="com.example.action.APP_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Intent explicitIntent =new Intent("com.example.action.APP_ACTION")
//跳轉不可導出,需要設置包名
explicitIntent.setPackage(context.getPackageName());
context.startActivity(explicitIntent);
2、在運行時注冊的廣播接收器必須指定導出行為
在 Android 14 上,運行時通過 Context#registerReceiver() 動態(tài)注冊廣播接收器,需要設置標記 RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED ,標識是否導出該廣播,避免應用程序出現(xiàn)安全漏洞,如果注冊的是系統(tǒng)廣播,則不需要指定標記。
三方SDK兼容修改方式:
如果三方SDK適配困難可以先在Activity或者Application中復寫廣播注冊方法,如果有未添加是否可導出標記可以手動添加上
@Override
public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {
return registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED或者Context.RECEIVER_NOT_EXPORTED);
}
@Override
public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter, int flags) {
Intent intent=null;
try {
boolean flagExported = (flags & Context.RECEIVER_EXPORTED) != 0;
boolean flagNotExported = (flags & Context.RECEIVER_NOT_EXPORTED) != 0;
if(!flagExported && !flagNotExported){
intent = super.registerReceiver(receiver, filter, flags|Context.RECEIVER_EXPORTED或者Context.RECEIVER_NOT_EXPORTED);
return intent;
}
intent = super.registerReceiver(receiver, filter,flag);
} catch (Throwable e) {
}
return intent;
}
3、啟動前臺服務必須設置前臺服務類型
如果有使用[startForeground()] 在清單文件中必須要指定服務的前臺類型,例如音頻播放類的可以使用mediaPlayback
為了幫助開發(fā)者更有目的地定義面向用戶的[前臺服務]Android 10 在 [<service>]元素內(nèi)引入了 android:foregroundServiceType 屬性。
二、Android 13——33 適配[詳細地址]https://blog.csdn.net/as425017946/article/details/127530660
1、細分媒體權限 圖片、視頻、音頻
從Android 13開始,以Android13(API 33+)為目標平臺的應用,系統(tǒng)新增運行時權限READ_MEDIA_IAMGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO 替代原有的READ_EXTERNAL_STORAGE權限。
2、靜態(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);
}
}
3、剪切板內(nèi)容隱藏
從Android 13(API 33)開始,Android剪切板新增了一項新API:
Android 13(API 33)開始,用戶可以選擇使用API PersistableBundle#(ClipDescription.EXTRA_IS_SENSITIVE, true)隱藏要復制到剪切板的用戶賬戶、密碼登敏感信息。
private void addData2Clipboard() {
ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData = ClipData.newPlainText("111111", "我是密碼");
ClipDescription description = clipData.getDescription();
// 隱私內(nèi)容:剪切板加密
PersistableBundle persistableBundle = new PersistableBundle();
if (Build.VERSION.SDK_INT >= 33) {
persistableBundle.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true);
} else {
persistableBundle.putBoolean("android.content.extra.IS_SENSITIVE", true);
}
description.setExtras(persistableBundle);
// 剪切板添加加密內(nèi)容
clipboardManager.setPrimaryClip(clipData);
}
三、Android 12——31 適配[詳細地址]http://www.itdecent.cn/p/60e061165667
四、Android 11——30 適配[詳細地址]https://blog.csdn.net/JasonXu94/article/details/129290096
五、Android 10——29 適配[詳細地址]https://blog.csdn.net/qq_33979657/article/details/106919681