android 8.0手机开服务端,Android 8.0 + Service开启方式兼容处理
Android 8.0 + ,對后臺服務進行了限制了。如果依然采用之前startService()方式。
會導致問題。
前后臺服務的一些區別:
有人可能會問,后臺服務我們可以自己創建 ONGOING 的 Notification 這樣就成為前臺服務嗎?答案是否定的,前臺服務是在做了上述工作之后需要調用 startForeground ( android 2.0 及其以后版本 )或 setForeground (android 2.0 以前的版本)使服務成為 前臺服務。這樣做的好處在于,當服務被外部強制終止掉的時候,ONGOING 的 Notification 任然會移除掉。
api 8.0+ 、9.0 關于服務的行為變更。
8.0
后臺執行限制
Android 8.0 為提高電池續航時間而引入的變更之一是,當您的應用進入已緩存狀態時,如果沒有活動的組件,系統將解除應用具有的所有喚醒鎖。
此外,為提高設備性能,系統會限制未在前臺運行的應用的某些行為。具體而言:
現在,在后臺運行的應用對后臺服務的訪問受到限制。
應用無法使用其清單注冊大部分隱式廣播(即,并非專門針對此應用的廣播)。
默認情況下,這些限制僅適用于針對 O 的應用。不過,用戶可以從 Settings 屏幕為任意應用啟用這些限制,即使應用并不是以 O 為目標平臺。
Android 8.0 還對特定函數做出了以下變更:
如果針對 Android 8.0 的應用嘗試在不允許其創建后臺服務的情況下使用 startService() 函數,則該函數將引發一個 IllegalStateException。
新的 Context.startForegroundService() 函數將啟動一個前臺服務。現在,即使應用在后臺運行,系統也允許其調用 Context.startForegroundService()。不過,應用必須在創建服務后的五秒內調用該服務的 startForeground() 函數。
如需了解詳細信息,請參閱后臺執行限制。
9.0
前臺服務
針對 Android 9 或更高版本并使用前臺服務的應用必須請求 FOREGROUND_SERVICE 權限。 這是普通權限,因此,系統會自動為請求權限的應用授予此權限。
如果針對 Android 9 或更高版本的應用嘗試創建一個前臺服務且未請求 FOREGROUND_SERVICE,則系統會引發 SecurityException。
網友推薦的解決方式:
原來startService()需要根據sdk版本進行兼容
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
系統說明在調用 context.startForegroundService(intent);服務后5s內需要調用
startForeground(1, notification);
根據網友提供方案,在 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 關于 Notification 的行為變更 ###通知
在 Android 8.0 中,我們已重新設計通知,以便為管理通知行為和設置提供更輕松和更統一的方式。這些變更包括:
圖 1. 用戶可以長按應用啟動器圖標以查看 Android 8.0 中的通知。
通知渠道:Android 8.0 引入了通知渠道,其允許您為要顯示的每種通知類型創建用戶可自定義的渠道。用戶界面將通知渠道稱之為通知類別。要了解如何實現通知渠道的信息,請參閱通知標志指南。
通知標志:Android 8.0 引入了對在應用啟動器圖標上顯示通知標志的支持。通知標志可反映某個應用是否存在與其關聯、并且用戶尚未予以清除也未對其采取行動的通知。通知標志也稱為通知點。要了解如何調整通知標志,請參閱通知標志指南。
休眠:用戶可以將通知置于休眠狀態,以便稍后重新顯示它。重新顯示時通知的重要程度與首次顯示時相同。應用可以移除或更新已休眠的通知,但更新休眠的通知并不會使其重新顯示。
通知超時:現在,使用 setTimeoutAfter() 創建通知時您可以設置超時。您可以使用此函數指定一個持續時間,超過該持續時間后,通知應取消。如果需要,您可以在指定的超時持續時間之前取消通知。
通知設置:當您使用 Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCESIntent 從通知創建指向應用通知設置的鏈接時,您可以調用 setSettingsText() 來設置要顯示的文本。此系統可以提供以下 Extra 數據和 Intent,用于過濾應用必須向用戶顯示的設置:EXTRA_CHANNEL_ID、NOTIFICATION_TAG 和 NOTIFICATION_ID。
通知清除:系統現在可區分通知是由用戶清除,還是由應用移除。要查看清除通知的方式,您應實現 NotificationListenerService 類的新 onNotificationRemoved() 函數。
背景顏色:您現在可以設置和啟用通知的背景顏色。只能在用戶必須一眼就能看到的持續任務的通知中使用此功能。例如,您可以為與駕車路線或正在進行的通話有關的通知設置背景顏色。您還可以使用 Notification.Builder.setColor() 設置所需的背景顏色。這樣做將允許您使用 Notification.Builder.setColorized() 啟用通知的背景顏色設置。
消息樣式:現在,使用 MessagingStyle 類的通知可在其折疊形式中顯示更多內容。對于與消息有關的通知,您應使用 MessagingStyle 類。您還可以使用新的 addHistoricMessage() 函數,通過向與消息相關的通知添加歷史消息為會話提供上下文。
根據上面提示,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;
//開啟服務兼容
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
}
……
……
…….
}
引用
總結
以上是生活随笔為你收集整理的android 8.0手机开服务端,Android 8.0 + Service开启方式兼容处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpaceX首次绕月之旅2023年1月开
- 下一篇: 新手怎样开水果店 其实很简单只要多学习