最近時間在做Android8.0及其以上系統(tǒng)下App版本更新時碧磅,使用Android 8.0的手機測試發(fā)現(xiàn)兩個問題:
1.彈出通知欄沒有展示旗闽,Toast:Developer warning for package “xxx.xxx.xxx” Failed to post notification on channel “null” See log for more details
2.新安裝包下載完成之后,沒有自動跳轉(zhuǎn)到安裝界面蜡塌,使用8.0以下的手機并沒有這個問題碉纳。
針對問題1:
查閱官方文檔得知,NotificationChannel是android8.0新增的特性馏艾,如果App的targetSDKVersion>=26劳曹,沒有設(shè)置channel通知渠道的話,就會導致通知無法展示琅摩。
Android O 引入了 通知渠道(Notification Channels)铁孵,以提供統(tǒng)一的系統(tǒng)來幫助用戶管理通知,如果是針對 android O 為目標平臺時房资,必須實現(xiàn)一個或者多個通知渠道蜕劝,以向用戶顯示通知。比如聊天軟件轰异,為每個聊天組設(shè)置一個通知渠道岖沛,指定特定聲音、燈光等配置溉浙。
因此解決方案是給通知設(shè)置渠道 createNotification(). 具體設(shè)置渠道的代碼如下:
final NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
RemoteViews view = new RemoteViews(getPackageName(), R.layout.notift_item);
//適配安卓8.0的消息渠道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
/**
* Oreo不用Priority了烫止,用importance
* IMPORTANCE_NONE 關(guān)閉通知
* IMPORTANCE_MIN 開啟通知,不會彈出戳稽,但沒有提示音馆蠕,狀態(tài)欄中無顯示
* IMPORTANCE_LOW 開啟通知,不會彈出惊奇,不發(fā)出提示音互躬,狀態(tài)欄中顯示
* IMPORTANCE_DEFAULT 開啟通知,不會彈出颂郎,發(fā)出提示音吼渡,狀態(tài)欄中顯示
* IMPORTANCE_HIGH 開啟通知,會彈出乓序,發(fā)出提示音寺酪,狀態(tài)欄中顯示
*/
NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_LOW);
manager.createNotificationChannel(channel);
}
notification = new NotificationCompat.Builder(this).setContent(view)
.setTicker("正在下載") //通知首次出現(xiàn)在通知欄坎背,帶上升動畫效果的
.setOngoing(true)//設(shè)置他為一個正在進行的通知。他們通常是用來表示一個后臺任務,用戶積極參與(如播放音樂) 或以某種方式正在等待,因此占用設(shè)備(如一個文件下載,同步操作,主動網(wǎng)絡(luò)連接)
.setSmallIcon(R.mipmap.jycicon)//設(shè)置通知小ICON
.setContentTitle("下載中")//設(shè)置通知欄標題
.setContentText("正在下載請稍等")//設(shè)置通知欄顯示內(nèi)容
.setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL))//設(shè)置通知欄點擊意圖
.setChannelId(channelID)
.build();
此時寄雀,推送通知得滤,不再有上面的錯誤提示,同時可以看到頂部有通知正常彈出盒犹。
上面代碼是針對android8.0懂更,因此還要在重寫的方法上面加上@RequiresApi(api =26)。
針對問題2:
Android 8.0 Oreo 中急膀,Google 移除掉了容易被濫用的“允許位置來源”應用的開關(guān)沮协,在安裝 Play Store 之外的第三方來源的 Android 應用的時候,已經(jīng)沒有了“允許未知來源”的檢查框卓嫂,其實并不是沒有這個檢查框了慷暂,只是放在了apk安裝的界面,如果你還是想要安裝某個被自己所信任的開發(fā)者的 app晨雳,則需要在清單文件AndroidManifest中加上如下權(quán)限
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
然后再Android上8.0的機器上運行呜呐,發(fā)現(xiàn)新的apk下載完成后可以自動跳到安裝界面,這時“允許安裝未知來源”的檢查框出現(xiàn)了悍募。點擊允許apk就可以順利安裝了蘑辑。
這時你是否會想就加一個權(quán)限就可以了,so easy坠宴!我們可以做如下操作讓我們的App更加完美洋魂。
/** * 判斷是否是8.0,8.0需要處理未知應用來源權(quán)限問題,否則直接安裝 */
private void checkIsAndroidO() {
if (Build.VERSION.SDK_INT >= 26) {
boolean b = getPackageManager().canRequestPackageInstalls();
if (b) {
installApk();//安裝應用的邏輯(寫自己的就可以)
} else {
//請求安裝未知應用來源的權(quán)限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, INSTALL_PACKAGES_REQUESTCODE);}
} else {
installApk();
}
}
以上代碼可以放在首次進入app時申請動態(tài)權(quán)限。
首次進行版本更新時喜鼓,我們得到的應該是false副砍,因為系統(tǒng)默認并沒有允許該權(quán)限。我們可以請求該權(quán)限庄岖,在權(quán)限請求結(jié)果的回調(diào)中處理邏輯如下:
@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case INSTALL_PACKAGES_REQUESTCODE:
if (grantResults.length > 0 && grantResults[0]== PackageManager.PERMISSION_GRANTED) {
installApk();
} else {
Intent localIntent = new Intent();
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= 9) {//2.3
localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
localIntent.setData(Uri.fromParts("package", context.getPackageName(), null));
} else if (Build.VERSION.SDK_INT <= 8) {//2.2
localIntent.setAction(Intent.ACTION_VIEW);
localIntent.setClassName("com.android.settings","com.android.settings.InstalledAppDetails");
localIntent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName());
}
context.startActivity(localIntent);
}
break;
}
}
若是沒有獲得該權(quán)限豁翎,我們可以使用else里的操作將用戶引導至應用信息界面,設(shè)置權(quán)限隅忿、允許安裝未知來源心剥,如圖
?
做了如上操作后,用戶下次版本更新的時候背桐,已經(jīng)允許了未知來源的應用优烧,就可以直接安裝了,無需用戶再手動授權(quán)允許链峭!