Android8.0使用通知建立前臺服務
Android8.0後臺執行限制
為提高裝置效能,系統會限制未在前臺執行的應用的某些行為。具體而言:
在後臺執行的應用對後臺服務的訪問受到限制 應用無法使用其清單註冊大部分隱式廣播
預設情況下,這些限制僅適用於針對O的應用。不過使用者可以從Settinfs螢幕為任意應用啟用這些限制,即使應用並不是以O為目標平臺。
Android8.0還對特定函式做出瞭如下變更:
如果針對Android8.0的應用嘗試子不允許建立其後臺服務的情況下使用startService()函式,則該函式將引發一個IllegalStateException. Context.startForegroundService()函式將啟動一個前臺服務。即使應用在後臺執行,系統也允許其呼叫Context.startForegroundService().不過,應用必須在建立服務後的5秒內呼叫改服務的startForegroun()函式,否則將報ANR(Application Not Responding)錯誤。
建立和管理通知渠道
從Android8.0開始,需要為傳送的每種不同型別的通知建立一個渠道,如果在Android8.0及以上在未指定通知頻道的情況下發送通知,通知不會顯示,會記錄錯誤。 建立通知渠道步驟:
通過一個唯一的channel ID ,對使用者可見的channel name,通知重要程度importance level構建一個通知渠道。 可選的使用setDescription()指定使用者在系統設定頁面看到的關於通知的相關描述。 通過createNotificationChannel()註冊通知渠道。
//Channel ID 必須保證唯一 private static final String CHANNEL_ID = "com.appname.notification.channel"; /** *建立通知渠道 */ private void createNotificationChannel() { // 在API>=26的時候建立通知渠道 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //設定的通知渠道名稱 String channelName = getString(R.string.channel_name); //設定通知的重要程度 int importance = NotificationManager.IMPORTANCE_LOW; //構建通知渠道 NotificationChannel channel = new NotificationChannel(CHANNEL_ID, channelName, importance); channel.setDescription(description); //向系統註冊通知渠道,註冊後不能改變重要性以及其他通知行為 NotificationManager notificationManager = getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } }1234567891011121314151617181920
importance level主要有七種層次:
IMPORTANCE_DEFAULT: 預設notification importance,可以在任何地方顯示,有聲音。 IMPORTANCE_HIGH:可以在任何地方顯示,有聲音. IMPORTANCE_LOW:可以在任何地方顯示,沒有聲音. IMPORTANCE_MAX:重要程度最高,可以在任何地方顯示,有聲音,可以在使用者當前螢幕上顯示通知,可以使用full screen intents.比如來電。 IMPORTANCE_MIN:無聲音,不會出現在狀態列中。 IMPORTANCE_NONE:在任何地方都不會顯示,被阻塞。 IMPORTANCE_UNSPECIFIED:表示使用者沒有表示重要性的值。這個值是為了持久的首選項,並且永遠不應該與實際的通知相關聯。
開啟前臺服務
public class MonitorService extends Service { /* * @param intent * @param flags * @param startId * @return */ @Override public int onStartCommand(Intent intent, int flags, int startId) { //處理任務 return START_STICKY; } @SuppressLint("CommitPrefEdits") @Override public void onCreate() { super.onCreate(); Log.d("foreground", "onCreate"); //如果API在26以上即版本為O則呼叫startForefround()方法啟動服務 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { setForegroundService(); } }
/** *通過通知啟動服務 */ @TargetApi(Build.VERSION_CODES.N) public void setForegroundService() { //設定的通知渠道名稱 String channelName = getString(R.string.channel_name); //設定通知的重要程度 int importance = NotificationManager.IMPORTANCE_LOW; //構建通知渠道 NotificationChannel channel = new NotificationChannel(CHANNEL_ID, channelName, importance); channel.setDescription(description); //在建立的通知渠道上傳送通知 NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID); builder.setSmallIcon(R.drawable.ic_logo) //設定通知圖示 .setContentTitle(notificationTitle)//設定通知標題 .setContentText(notificationContent)//設定通知內容 .setAutoCancel(true) //使用者觸控時,自動關閉 .setOngoing(true);//設定處於執行狀態 //向系統註冊通知渠道,註冊後不能改變重要性以及其他通知行為 NotificationManager notificationManager = getSystemService( Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(channel); //將服務置於啟動狀態 NOTIFICATION_ID指的是建立的通知的ID startForeground(NOTIFICATION_ID,builder.build()); } } 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
在Application或需要開啟服務的地方呼叫
// Android 8.0使用startForegroundService在前臺啟動新服務 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(mMonitorService); } else{ context.startService(mMonitorService); }12345678
---------------------