1. 程式人生 > >Android8.0使用通知建立前臺服務

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                  

---------------------