不同版本的變化
Android6.0發(fā)布時(shí)間: 2015年5月28日
主要變化:
- 運(yùn)行時(shí)權(quán)限
- 增加低電耗模式和應(yīng)用待機(jī)模式
- 取消支持 Apache HTTP 客戶端
- 移除硬件標(biāo)識(shí)符訪問權(quán)
- WLAN 和網(wǎng)絡(luò)連接變更
- 相機(jī)服務(wù)變更
Android7.0發(fā)布時(shí)間: 2016年8月22日
主要變化:
- 私有文件訪問權(quán)限更改
- 多窗口支持(分屏顯示)
- 通知增強(qiáng)功能
- 隨時(shí)隨地低電耗模式
- 多語言區(qū)域支持峭判,更多語言
- 新增的表情符號(hào)
- Chrome 和 WebView 配合使用
- APK signature scheme v2
Android8.0發(fā)布時(shí)間:2017年8月22日
主要變化:
- 通知渠道
- 啟動(dòng)圖標(biāo)
- 統(tǒng)一的布局外邊距和內(nèi)邊距
- 自動(dòng)填充框架
- 畫中畫模式
- 多顯示器支持媒體增強(qiáng)功能
Android9.0發(fā)布時(shí)間:2018年8月7日
主要變化:
- 劉海屏適配
- 通知功能的變更
- 隱私權(quán)變更
- 對(duì)使用非 SDK 接口的限制 和 適配策略
- 非Activity-Context啟動(dòng)Activity
- Apache HTTP 客戶端棄用捆愁,影響采用非標(biāo)準(zhǔn) ClassLoader 的應(yīng)用
- 前臺(tái)服務(wù)
注意:每個(gè)版本都有比較多的變化秀睛,但并不是所有內(nèi)容都需要適配鸠匀。適配某個(gè)版本咨察,需要將targetSdkVersion改為對(duì)應(yīng)的版本號(hào),點(diǎn)擊sync Now然后進(jìn)行適配担忧。
Android8.0適配
(1)通知渠道(Channeld)適配
Android O版本對(duì)通知做了規(guī)范性的控制馁启,強(qiáng)制用戶在發(fā)送通知的時(shí)候,對(duì)通知進(jìn)行系統(tǒng)性的管理秋度,新增了ChanneID炸庞,用來允許要為顯示的每種通知類型創(chuàng)建用戶可自定義的渠道,用戶界面將通知渠道稱之為通知類別荚斯。
注意:在8.0中所有通知的實(shí)現(xiàn)都需要提供通知渠道埠居,否則,所有通知在8.0系統(tǒng)上面都不能正常顯示
適配流程
1.創(chuàng)建 NotificationChannel 對(duì)象事期,并設(shè)置應(yīng)用內(nèi)唯一的通知 ID滥壕。在 NotificationManager 中注冊(cè)通知渠道對(duì)象。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel newsChannel = new NotificationChannel(CHANNEL_NEWS, "新聞",NotificationManager.IMPORTANCE_HIGH);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.createNotificationChannel(newsChannel);
}
2.配置通知渠道的屬性兽泣,比如提示聲音等绎橘。
public void sendNews(View view) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_NEWS)
.setContentTitle("新聞標(biāo)題")
.setContentText("新聞內(nèi)容")
.setAutoCancel(true)
.build();
manager.notify(1, notification);
}
public void sendNoChannel(View view) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("沒有渠道的通知")
.setContentText("通內(nèi)容")
.setAutoCancel(true)
.setSmallIcon(R.mipmap.ic_launcher)
.build();
manager.notify(1, notification);
}
4.通知完成后需要及時(shí)關(guān)閉通道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//關(guān)閉通知通道
notificationManager.deleteNotificationChannel("新聞");
}
(2)懸浮窗適配
8.0 API 新增了一種懸浮窗的窗口類型,TYPE_APPLICATION_OVERLAY唠倦;
如果應(yīng)用使用 SYSTEM_ALERT_WINDOW 權(quán)限并且嘗試使用以下窗口類型之一來在其他應(yīng)用和系統(tǒng)窗口上方顯示提醒窗口:
TYPE_PHONE
TYPE_PRIORITY_PHONE
TYPE_SYSTEM_ALERT
TYPE_SYSTEM_OVERLAY
TYPE_SYSTEM_ERROR
TYPE_TOAST
這些窗口將始終顯示在使用 TYPE_APPLICATION_OVERLAY 窗口類型的窗口下方称鳞。
如果該應(yīng)用適配了8.0,則應(yīng)用只能使用TYPE_APPLICATION_OVERLAY窗口類型來創(chuàng)建懸浮窗稠鼻。(其它窗口類型在8.0已經(jīng)被廢棄掉)
適配流程
1.申請(qǐng)權(quán)限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
2.給懸浮窗設(shè)置type
public static void showLogoutDialog(final Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
View view = View.inflate(context, R.layout.dialog_logout, null);
builder.setView(view);
final AlertDialog dialog = builder.create();
if (Build.VERSION.SDK_INT>=26) {//8.0新特性
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
}else{
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
}
dialog.show();
}
(3)安裝Apk適配
Android 8.0去除了“允許未知來源”選項(xiàng)冈止,所以如果我們的App有安裝App的功能(檢查更新之類的),那么會(huì)無法正常安裝枷餐。
適配流程
1.首先在AndroidManifest文件中添加安裝未知來源應(yīng)用的權(quán)限靶瘸,這樣系統(tǒng)會(huì)自動(dòng)詢問用戶完成授權(quán)。
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
2.當(dāng)然也可以先使用 canRequestPackageInstalls()查詢是否有此權(quán)限毛肋,如果沒有的話使用Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES這個(gè)action將用戶引導(dǎo)至安裝未知應(yīng)用權(quán)限界面去授權(quán)怨咪。
private static final int REQUEST_CODE_UNKNOWN_APP = 100;
private void installAPK(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
boolean hasInstallPermission = getPackageManager().canRequestPackageInstalls();
if (hasInstallPermission) {
//安裝應(yīng)用
} else {
//跳轉(zhuǎn)至“安裝未知應(yīng)用”權(quán)限界面,引導(dǎo)用戶開啟權(quán)限
Uri selfPackageUri = Uri.parse("package:" + this.getPackageName());
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, selfPackageUri);
startActivityForResult(intent, REQUEST_CODE_UNKNOWN_APP);
}
}else {
//安裝應(yīng)用
}
}
//接收“安裝未知應(yīng)用”權(quán)限的開啟結(jié)果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_UNKNOWN_APP) {
installAPK();
}
}
(4)權(quán)限適配
Android 8.0中PHONE權(quán)限組新增兩個(gè)權(quán)限
ANSWER_PHONE_CALLS:允許您的應(yīng)用通過編程方式接聽呼入電話润匙。要在您的應(yīng)用中處理呼入電話诗眨,您可以使用 acceptRingingCall() 函數(shù)。
READ_PHONE_NUMBERS:權(quán)限允許您的應(yīng)用讀取設(shè)備中存儲(chǔ)的電話號(hào)碼孕讳。
(5)廣播適配
Android 8.0 引入了新的廣播接收器限制匠楚,靜態(tài)廣播無法正常接收,因此應(yīng)該移除所有為隱式廣播 Intent 注冊(cè)的廣播接收器厂财。
解決方案:使用動(dòng)態(tài)廣播代替靜態(tài)廣播芋簿。
(6)透明主題的Activity適配
Android 8.0 非全屏透明頁(yè)面不允許設(shè)置方向,否則報(bào)錯(cuò)(后面8.1系統(tǒng)谷歌就去掉了這個(gè)限制)
適配流程
1.要么去掉對(duì)應(yīng)activity中的 screenOrientation 屬性璃饱,或者對(duì)應(yīng)設(shè)置方向的代碼与斤。
2.要么舍棄透明效果,在它的Theme中添加:
<item name="android:windowIsTranslucent">false</item>
3.使用透明的dialog或者PopupWindow來代替,也可以用DialogFragment
(7)其他
項(xiàng)目使用了ActiveAndroid撩穿,在 8.0 或 8.1 系統(tǒng)上使用 26 或以上的版本的 SDK 時(shí)磷支,調(diào)用 ContentResolver 的 notifyChange 方法通知數(shù)據(jù)更新,或者調(diào)用 ContentResolver 的 registerContentObserver 方法監(jiān)聽數(shù)據(jù)變化時(shí)食寡,會(huì)出現(xiàn)上述異常雾狈。
解決方案:
1.在清單文件配置:
<provider
android:name="com.activeandroid.content.ContentProvider"
android:authorities="com.jz.androidclient"
android:enabled="true"
android:exported="false"/>
2.去掉這個(gè)監(jiān)聽刷新的方法,改為廣播刷新
Android9.0適配
Android P 限制了明文流量的網(wǎng)絡(luò)請(qǐng)求抵皱,非加密的流量請(qǐng)求都會(huì)被系統(tǒng)禁止掉
解決方案:
1.在資源文件新建xml目錄善榛,新建文件network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
2.清單文件配置:
<application
android:networkSecurityConfig="@xml/network_security_config">
<!--Android 9.0加的-->
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
</application>