android 8.0手机开服务端,Android 8.0 + Service开启方式兼容处理
Android 8.0 + ,對后臺服務(wù)進(jìn)行了限制了。如果依然采用之前startService()方式。
會導(dǎo)致問題。
前后臺服務(wù)的一些區(qū)別:
有人可能會問,后臺服務(wù)我們可以自己創(chuàng)建 ONGOING 的 Notification 這樣就成為前臺服務(wù)嗎?答案是否定的,前臺服務(wù)是在做了上述工作之后需要調(diào)用 startForeground ( android 2.0 及其以后版本 )或 setForeground (android 2.0 以前的版本)使服務(wù)成為 前臺服務(wù)。這樣做的好處在于,當(dāng)服務(wù)被外部強制終止掉的時候,ONGOING 的 Notification 任然會移除掉。
api 8.0+ 、9.0 關(guān)于服務(wù)的行為變更。
8.0
后臺執(zhí)行限制
Android 8.0 為提高電池續(xù)航時間而引入的變更之一是,當(dāng)您的應(yīng)用進(jìn)入已緩存狀態(tài)時,如果沒有活動的組件,系統(tǒng)將解除應(yīng)用具有的所有喚醒鎖。
此外,為提高設(shè)備性能,系統(tǒng)會限制未在前臺運行的應(yīng)用的某些行為。具體而言:
現(xiàn)在,在后臺運行的應(yīng)用對后臺服務(wù)的訪問受到限制。
應(yīng)用無法使用其清單注冊大部分隱式廣播(即,并非專門針對此應(yīng)用的廣播)。
默認(rèn)情況下,這些限制僅適用于針對 O 的應(yīng)用。不過,用戶可以從 Settings 屏幕為任意應(yīng)用啟用這些限制,即使應(yīng)用并不是以 O 為目標(biāo)平臺。
Android 8.0 還對特定函數(shù)做出了以下變更:
如果針對 Android 8.0 的應(yīng)用嘗試在不允許其創(chuàng)建后臺服務(wù)的情況下使用 startService() 函數(shù),則該函數(shù)將引發(fā)一個 IllegalStateException。
新的 Context.startForegroundService() 函數(shù)將啟動一個前臺服務(wù)?,F(xiàn)在,即使應(yīng)用在后臺運行,系統(tǒng)也允許其調(diào)用 Context.startForegroundService()。不過,應(yīng)用必須在創(chuàng)建服務(wù)后的五秒內(nèi)調(diào)用該服務(wù)的 startForeground() 函數(shù)。
如需了解詳細(xì)信息,請參閱后臺執(zhí)行限制。
9.0
前臺服務(wù)
針對 Android 9 或更高版本并使用前臺服務(wù)的應(yīng)用必須請求 FOREGROUND_SERVICE 權(quán)限。 這是普通權(quán)限,因此,系統(tǒng)會自動為請求權(quán)限的應(yīng)用授予此權(quán)限。
如果針對 Android 9 或更高版本的應(yīng)用嘗試創(chuàng)建一個前臺服務(wù)且未請求 FOREGROUND_SERVICE,則系統(tǒng)會引發(fā) SecurityException。
網(wǎng)友推薦的解決方式:
原來startService()需要根據(jù)sdk版本進(jìn)行兼容
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
系統(tǒng)說明在調(diào)用 context.startForegroundService(intent);服務(wù)后5s內(nèi)需要調(diào)用
startForeground(1, notification);
根據(jù)網(wǎng)友提供方案,在 api =26 級別可以正常跑起來,但是在api =27 級別下,啟動直接崩潰,具體crash 異常日志如下:
09-03 16:13:28.563 6124-6124/com.nuoyuan.nyd E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.nuoyuan.nyd, PID: 6124
android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel= pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 vis=PRIVATE)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1768)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
這里牽扯到android 8.0 關(guān)于 Notification 的行為變更 ###通知
在 Android 8.0 中,我們已重新設(shè)計通知,以便為管理通知行為和設(shè)置提供更輕松和更統(tǒng)一的方式。這些變更包括:
圖 1. 用戶可以長按應(yīng)用啟動器圖標(biāo)以查看 Android 8.0 中的通知。
通知渠道:Android 8.0 引入了通知渠道,其允許您為要顯示的每種通知類型創(chuàng)建用戶可自定義的渠道。用戶界面將通知渠道稱之為通知類別。要了解如何實現(xiàn)通知渠道的信息,請參閱通知標(biāo)志指南。
通知標(biāo)志:Android 8.0 引入了對在應(yīng)用啟動器圖標(biāo)上顯示通知標(biāo)志的支持。通知標(biāo)志可反映某個應(yīng)用是否存在與其關(guān)聯(lián)、并且用戶尚未予以清除也未對其采取行動的通知。通知標(biāo)志也稱為通知點。要了解如何調(diào)整通知標(biāo)志,請參閱通知標(biāo)志指南。
休眠:用戶可以將通知置于休眠狀態(tài),以便稍后重新顯示它。重新顯示時通知的重要程度與首次顯示時相同。應(yīng)用可以移除或更新已休眠的通知,但更新休眠的通知并不會使其重新顯示。
通知超時:現(xiàn)在,使用 setTimeoutAfter() 創(chuàng)建通知時您可以設(shè)置超時。您可以使用此函數(shù)指定一個持續(xù)時間,超過該持續(xù)時間后,通知應(yīng)取消。如果需要,您可以在指定的超時持續(xù)時間之前取消通知。
通知設(shè)置:當(dāng)您使用 Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCESIntent 從通知創(chuàng)建指向應(yīng)用通知設(shè)置的鏈接時,您可以調(diào)用 setSettingsText() 來設(shè)置要顯示的文本。此系統(tǒng)可以提供以下 Extra 數(shù)據(jù)和 Intent,用于過濾應(yīng)用必須向用戶顯示的設(shè)置:EXTRA_CHANNEL_ID、NOTIFICATION_TAG 和 NOTIFICATION_ID。
通知清除:系統(tǒng)現(xiàn)在可區(qū)分通知是由用戶清除,還是由應(yīng)用移除。要查看清除通知的方式,您應(yīng)實現(xiàn) NotificationListenerService 類的新 onNotificationRemoved() 函數(shù)。
背景顏色:您現(xiàn)在可以設(shè)置和啟用通知的背景顏色。只能在用戶必須一眼就能看到的持續(xù)任務(wù)的通知中使用此功能。例如,您可以為與駕車路線或正在進(jìn)行的通話有關(guān)的通知設(shè)置背景顏色。您還可以使用 Notification.Builder.setColor() 設(shè)置所需的背景顏色。這樣做將允許您使用 Notification.Builder.setColorized() 啟用通知的背景顏色設(shè)置。
消息樣式:現(xiàn)在,使用 MessagingStyle 類的通知可在其折疊形式中顯示更多內(nèi)容。對于與消息有關(guān)的通知,您應(yīng)使用 MessagingStyle 類。您還可以使用新的 addHistoricMessage() 函數(shù),通過向與消息相關(guān)的通知添加歷史消息為會話提供上下文。
根據(jù)上面提示,Notification 需要添加 channelId 才可以正常使用
如下修改,可以正常兼容 api 級別 8.0 ,8.1 + 的service 正常開啟
public class UploadFilesIntentService extends IntentService {
private static final String UPLOAD_FILE = "com.nuoyuan.statistic.action.UPLOAD_FILE";
private static String loadUrlPath = "";
private static SttcHeadParams mHeadParams;
public static final String CHANNEL_ID_STRING = "nyd001";
@Override
public void onCreate() {
super.onCreate();
//適配8.0service
NotificationManager notificationManager = (NotificationManager) MyApp.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel mChannel = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
mChannel = new NotificationChannel(CHANNEL_ID_STRING, "諾秒貸", NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(mChannel);
Notification notification = new Notification.Builder(getApplicationContext(), CHANNEL_ID_STRING).build();
startForeground(1, notification);
}
}
public UploadFilesIntentService() {
super("UploadFilesIntentService");
}
public static void startActionFoo(Context context, String loadPath, SttcHeadParams headParams) {
Intent intent = new Intent(context, UploadFilesIntentService.class);
intent.setAction(UPLOAD_FILE);
mHeadParams = headParams;
loadUrlPath = loadPath;
//開啟服務(wù)兼容
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
}
……
……
…….
}
引用
總結(jié)
以上是生活随笔為你收集整理的android 8.0手机开服务端,Android 8.0 + Service开启方式兼容处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: SpaceX首次绕月之旅2023年1月开
- 下一篇: 新手怎样开水果店 其实很简单只要多学习
