Android 實現應用更新適配 Android O (Android 8.0)
之前寫過一篇 Android 實現應用更新(適配Anndroid N),本篇主要講解Android O(Android 8.0)上應用更新的適配問題,應用更新的完整實現請結合上一篇文章一起,文末也會給出完整程式碼連結。
最近測試反饋在Android 8.0的手機上,提示應用更新,更新時會出現下載失敗,並且通知欄也沒有顯示下載的進度的情況,即使下載成功也不會彈出應用安裝介面。
實測發現確實是有這樣的問題。當targetSdkVersion小於26時,沒有問題,當targetSDK等於26時,就會出現上述問題。
上述問題實際上是三個問題:
(1)APK檔案下載失敗
(2)通知欄不顯示
(3)下載成功沒有跳出應用安裝介面
於是馬上想到了應該是Android O(Android 8.0)的新特性導致的。
-APK檔案下載失敗
通過檢視日誌資訊,是因為在本地SD卡建立下載檔案失敗。
而建立下載檔案失敗,日誌資訊竟然是沒有許可權,怎麼可能,明明點選更新時,動態申請了“讀寫”許可權,這裡“讀寫”許可權打雙引號,是因為程式碼中申請的其實是READ_EXTERNAL_STORAGE讀儲存許可權,這在Android O(Android 8.0)之前是沒有任何問題的,因為讀寫是一組許可權,同屬儲存許可權,只要申請了同組許可權中的一個,同組中的其他在清單檔案中列出了的許可權也就被授予了。但是Android O(Android 8.0)執行時許可權有了變動,就是系統只會授予應用明確請求的許可權,
然而一旦使用者為應用授予某個許可權,則所有後續對該許可權組中許可權的請求都將被自動批准,但是還是需要去申請,這點和Android O(Android 8.0)之前不同。
由於這裡建立下載檔案,實際上是往儲存中寫檔案,需要寫儲存許可權WRITE_EXTERNAL_STORAGE,於是將程式碼點選更新時申請READ_EXTERNAL_STORAGE改為申請WRITE_EXTERNAL_STORAGE。執行測試,APK檔案是可以下載成功了。第一個問題得到解決。
-通知欄不顯示問題
在Android O(Android 8.0)之前的手機上,更新下載APK檔案時,通知欄會顯示下載進度的通知,然而Android O(Android 8.0)的手機上,targetSDK等於26時,下載檔案並沒有通知欄顯示。檢視官網Android O行為變更,發現通知的建立與顯示發生了變化,建立通知之前還需要建立一個NotificationChannel。按照官網的示例對通知的顯示做了相容性處理:(完整程式碼,文末會給出連結
private void notifyUser(int progress) {
if (Build.VERSION.SDK_INT >= 26) {
if (mNotificationChannel == null) {
//建立 通知通道 channelid和channelname是必須的(自己命名就好)
mNotificationChannel = new NotificationChannel("1",
"Channel1",NotificationManager.IMPORTANCE_HIGH);
mNotificationChannel.enableLights(true);//是否在桌面icon右上角展示小紅點
mNotificationChannel.setLightColor(Color.GREEN);//小紅點顏色
mNotificationChannel.setShowBadge(true); //是否在久按桌面圖示時顯示此渠道的通知
mNotificationManager.createNotificationChannel(mNotificationChannel);
}
int notificationId = 0x1234;
Notification.Builder builder = new Notification.Builder(getApplicationContext(), "1");
builder.setOnlyAlertOnce(true);
builder.setSmallIcon(R.mipmap.ic_launcher)
.setContentText("正在下載新版本,請稍後...")
.setAutoCancel(true);
if (progress > 0 && progress <= 100) {
builder.setProgress(100, progress, false);
} else {
builder.setProgress(0, 0, false);
}
builder.setContentIntent(progress >= 100 ? this.getContentIntent() :
PendingIntent.getActivity(this, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT));
Notification notification = builder.build();
mNotificationManager.notify(notificationId, notification);
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this,null);
builder.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setContentTitle(getString(R.string.app_name));
if (progress > 0 && progress <= 100) {
builder.setProgress(100, progress, false);
} else {
builder.setProgress(0, 0, false);
}
builder.setAutoCancel(true);
builder.setWhen(System.currentTimeMillis());
builder.setContentIntent(progress >= 100 ? this.getContentIntent() :
PendingIntent.getActivity(this, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT));
mNotification = builder.build();
mNotificationManager.notify(0, mNotification);
}
}
這裡要特別宣告一點的是 builder.setOnlyAlertOnce(true);這句程式碼,
因為在測試的時候發現,通知更新進度的時候,手機會一直有提示音,加上這句程式碼後就不會一直有提示音了。
然後測試發現下載APK檔案時,通知欄就會正常顯示通知顯示APK下載進度了。
第二個問題也得到了解決。
-APK檔案下載成功沒有正常跳到應用安裝介面。
Android O (Android 8.0) 中,Google 移除掉了容易被濫用的“允許未知來源”應用的開關,在安裝 Play Store 之外的第三方來源的 Android 應用的時候,竟然沒有了“允許未知來源”的檢查框,如果你還是想要安裝某個被自己所信任的開發者的 app,則需要在每一次都手動授予“安裝未知應用”的許可。
首先在AndroidManifest.xml 清單檔案中新增安裝未知來源應用的許可權
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
然後在使用者點選更新時判斷是否開啟了該應用的“允許安裝未知來源”的許可權,沒有的話,就引導使用者去開啟該應用的“允許安裝未知來源”的許可權,判斷程式碼如下:(完整程式碼,文末會給出連結)
private void downloadAPK(){
boolean hasInstallPerssion = getPackageManager().canRequestPackageInstalls();
if (hasInstallPerssion ) {
//安裝應用的邏輯
} else {
//跳轉至“安裝未知應用”許可權介面,引導使用者開啟許可權,可以在onActivityResult中接收許可權的開啟結果
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
startActivityForResult(intent, REQUEST_CODE_UNKNOWN_APP);
}
}
//接收“安裝未知應用”許可權的開啟結果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_UNKNOWN_APP) {
downloadAPK();
}
}
這樣點選更新時引導使用者開啟“允許安裝未知來源”的許可權後,APK檔案下載成功後也
成功的跳轉到應用安裝介面。第三個問題也得到了解決。
至此應用更新在Android O(Android 8.0)上的問題就都得到了解決,成功的適配了Android O。