不同版本的變化
Android6.0發(fā)布時間: 2015年5月28日
主要變化:
- 運行時權限
- 增加低電耗模式和應用待機模式
- 取消支持 Apache HTTP 客戶端
- 移除硬件標識符訪問權
- WLAN 和網絡連接變更
- 相機服務變更
Android7.0發(fā)布時間: 2016年8月22日
主要變化:
- 私有文件訪問權限更改
- 多窗口支持(分屏顯示)
- 通知增強功能
- 隨時隨地低電耗模式
- 多語言區(qū)域支持,更多語言
- 新增的表情符號
- Chrome 和 WebView 配合使用
- APK signature scheme v2
Android8.0發(fā)布時間:2017年8月22日
主要變化:
- 通知渠道
- 啟動圖標
- 統(tǒng)一的布局外邊距和內邊距
- 自動填充框架
- 畫中畫模式
- 多顯示器支持媒體增強功能
Android9.0發(fā)布時間:2018年8月7日
主要變化:
- 劉海屏適配
- 通知功能的變更
- 隱私權變更
- 對使用非 SDK 接口的限制 和 適配策略
- 非Activity-Context啟動Activity
- Apache HTTP 客戶端棄用,影響采用非標準 ClassLoader 的應用
- 前臺服務
注意:每個版本都有比較多的變化,但并不是所有內容都需要適配。適配某個版本,需要將targetSdkVersion改為對應的版本號,點擊sync Now然后進行適配。
Android8.0適配
(1)通知渠道(Channeld)適配
Android O版本對通知做了規(guī)范性的控制,強制用戶在發(fā)送通知的時候,對通知進行系統(tǒng)性的管理,新增了ChanneID,用來允許要為顯示的每種通知類型創(chuàng)建用戶可自定義的渠道,用戶界面將通知渠道稱之為通知類別。
注意:在8.0中所有通知的實現(xiàn)都需要提供通知渠道,否則,所有通知在8.0系統(tǒng)上面都不能正常顯示
適配流程
1.創(chuàng)建 NotificationChannel 對象,并設置應用內唯一的通知 ID。在 NotificationManager 中注冊通知渠道對象。
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("新聞標題")
.setContentText("新聞內容")
.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("通內容")
.setAutoCancel(true)
.setSmallIcon(R.mipmap.ic_launcher)
.build();
manager.notify(1, notification);
}
4.通知完成后需要及時關閉通道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//關閉通知通道
notificationManager.deleteNotificationChannel("新聞");
}
(2)懸浮窗適配
8.0 API 新增了一種懸浮窗的窗口類型,TYPE_APPLICATION_OVERLAY;
如果應用使用 SYSTEM_ALERT_WINDOW 權限并且嘗試使用以下窗口類型之一來在其他應用和系統(tǒng)窗口上方顯示提醒窗口:
TYPE_PHONE
TYPE_PRIORITY_PHONE
TYPE_SYSTEM_ALERT
TYPE_SYSTEM_OVERLAY
TYPE_SYSTEM_ERROR
TYPE_TOAST
這些窗口將始終顯示在使用 TYPE_APPLICATION_OVERLAY 窗口類型的窗口下方。
如果該應用適配了8.0,則應用只能使用TYPE_APPLICATION_OVERLAY窗口類型來創(chuàng)建懸浮窗。(其它窗口類型在8.0已經被廢棄掉)
適配流程
1.申請權限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
2.給懸浮窗設置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去除了“允許未知來源”選項,所以如果我們的App有安裝App的功能(檢查更新之類的),那么會無法正常安裝。
適配流程
1.首先在AndroidManifest文件中添加安裝未知來源應用的權限,這樣系統(tǒng)會自動詢問用戶完成授權。
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
2.當然也可以先使用 canRequestPackageInstalls()查詢是否有此權限,如果沒有的話使用Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES這個action將用戶引導至安裝未知應用權限界面去授權。
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) {
//安裝應用
} else {
//跳轉至“安裝未知應用”權限界面,引導用戶開啟權限
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 {
//安裝應用
}
}
//接收“安裝未知應用”權限的開啟結果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_UNKNOWN_APP) {
installAPK();
}
}
(4)權限適配
Android 8.0中PHONE權限組新增兩個權限
ANSWER_PHONE_CALLS:允許您的應用通過編程方式接聽呼入電話。要在您的應用中處理呼入電話,您可以使用 acceptRingingCall() 函數。
READ_PHONE_NUMBERS:權限允許您的應用讀取設備中存儲的電話號碼。
(5)廣播適配
Android 8.0 引入了新的廣播接收器限制,靜態(tài)廣播無法正常接收,因此應該移除所有為隱式廣播 Intent 注冊的廣播接收器。
解決方案:使用動態(tài)廣播代替靜態(tài)廣播。
(6)透明主題的Activity適配
Android 8.0 非全屏透明頁面不允許設置方向,否則報錯(后面8.1系統(tǒng)谷歌就去掉了這個限制)
適配流程
1.要么去掉對應activity中的 screenOrientation 屬性,或者對應設置方向的代碼。
2.要么舍棄透明效果,在它的Theme中添加:
<item name="android:windowIsTranslucent">false</item>
3.使用透明的dialog或者PopupWindow來代替,也可以用DialogFragment
(7)其他
項目使用了ActiveAndroid,在 8.0 或 8.1 系統(tǒng)上使用 26 或以上的版本的 SDK 時,調用 ContentResolver 的 notifyChange 方法通知數據更新,或者調用 ContentResolver 的 registerContentObserver 方法監(jiān)聽數據變化時,會出現(xiàn)上述異常。
解決方案:
1.在清單文件配置:
<provider
android:name="com.activeandroid.content.ContentProvider"
android:authorities="com.jz.androidclient"
android:enabled="true"
android:exported="false"/>
2.去掉這個監(jiān)聽刷新的方法,改為廣播刷新
Android9.0適配
Android P 限制了明文流量的網絡請求,非加密的流量請求都會被系統(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>