Android 開發 8.0版本啟動Service的方法


前言 

google在更新Android8.0后對Service的權限越發收緊。導致目前想要啟動服務必需實現服務的前台化(否則在服務啟動5秒后,系統將自動報錯)。下面我們就來看看如何在8.0上啟動服務。

看看8.0之前的版本怎么啟動Service

  在看8.0啟動服務的方法之前,我們先看看8.0之前是怎么啟動服務的。這樣可以對比,也可以理解增加了那些部分。

  1.在Activity啟動服務:

Intent intent = new Intent(MainActivity.this,MainService.class);
startService(intent);

  8.0之前是使用startService 直接啟動服務的。后續服務就可以在后台運行了

  2.將服務前台化:

  雖然8.0之前如果沒有明確需求,是可以不需要讓服務前台化通知欄顯示的,但是我們為了對比實現下8.0之前的服務前台化。

public void onCreate() {
        super.onCreate();
        Notification notification = new Notification.Builder(this)
                .setContentTitle("主服務")//設置標題
                .setContentText("運行中...")//設置內容
                .setWhen(System.currentTimeMillis())//設置創建時間
                .setSmallIcon(R.mipmap.ic_launcher)//設置狀態欄圖標
         .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))//設置通知欄圖標
                .build();
        startForeground(1,notification);
    }

可以服務啟動后,可以在服務的onCreate()里直接實現服務前台化。

8.0版本怎么啟動Service

  1.在Activity里啟動服務

Intent intent = new Intent(MainActivity.this,MainService.class);
startForegroundService(intent);

 

  可以看到啟動的方法變成了startForegroundService();

  2.創建8.0版本必需實現的服務前台化

 

private static final String CHANNEL_ID = "NFCService";
public void onCreate() {
        super.onCreate();
        NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        NotificationChannel Channel = new NotificationChannel(CHANNEL_ID,"主服務",NotificationManager.IMPORTANCE_HIGH);                
     Channel.enableLights(true);//設置提示燈
     Channel.setLightColor(Color.RED);//設置提示燈顏色
        Channel.setShowBadge(true);//顯示logo
        Channel.setDescription("ytzn");//設置描述
        Channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); //設置鎖屏可見 VISIBILITY_PUBLIC=可見
        manager.createNotificationChannel(Channel);

        Notification notification = new Notification.Builder(this)
                .setChannelId(CHANNEL_ID)
                .setContentTitle("主服務")//標題
                .setContentText("運行中...")//內容
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)//小圖標一定需要設置,否則會報錯(如果不設置它啟動服務前台化不會報錯,但是你會發現這個通知不會啟動),如果是普通通知,不設置必然報錯
               .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                .build();
        startForeground(1,notification);//服務前台化只能使用startForeground()方法,不能使用 notificationManager.notify(1,notification); 這個只是啟動通知使用的,使用這個方法你只需要等待幾秒就會發現報錯了

        
    }  

 

8.0版本后多了一個需要創建的NotificationChannel,在Notification里多了一個需要設置的setChannelId();

  8.0版本啟動服務注意點:

  1. 請注意8.0版本只能使用startForegroundService()啟動服務,不能在使用startService()
  2. 請注意在new NotificationChannel(CHANNEL_ID,"主服務",NotificationManager.IMPORTANCE_HIGH); 的第一個參數id為Channel的通道id需要與NotificationsetChannelId()設置的id一致,否則會報前台服務無效的異常。
  3. 注意啟動服務前台化通知的方法是startForeground(),如果使用notificationManager.notify(),將不會關聯你啟動的服務,系統會將它作為一個普通通知處理

 

最后了解什么是NotificationChannel

Android O 引入了 通知渠道(Notification Channels),以提供統一的系統來幫助用戶管理通知,如果是針對 android O 為目標平台時,必須實現一個或者多個通知渠道,以向用戶顯示通知。若並不以 Android O 為目標平台,當應用運行在 android O 設備上時,其行為將與運行在 Android 7.0 上時相同。
開發者可以為需要發送的每個不同的通知類型創建一個通知渠道。還可以創建通知渠道來反映應用的用戶做出的選擇。例如,可以為聊天應用的用戶創建的每個聊天組建立單獨的通知渠道。
Android O 的用戶可以使用一致的系統 UI 管理大多數與通知有關的設置。所有發布至通知渠道的通知都具有相同的行為。當用戶修改任何下列特性的行為時,修改將作用於通知渠道:

  • 重要性
  • 聲音
  • 振動
  • 在鎖屏上顯示
  • 替換免打擾模式

通知優先級和重要性

Android O 棄用了為單個通知設置優先級的功能。創建通知渠道時可以設置建議重要性級別。為通知渠道指定的重要性級別適用於發布至該渠道的所有通知消息。可以配置五個級別中的一個,這些級別代表着通知渠道可以打斷用戶的程度,范圍是 IMPORTANCE_NONE(0)IMPORTANCE_HIGH(4)。默認重要性級別為 3:在所有位置顯示,發出提示音,但不會對用戶產生視覺干擾。創建通知渠道后,只有系統可以修改其重要性。用戶可以在設置中找到。

創建通知渠道

要創建通知渠道,請執行下列操作:

  • 構建一個在軟件包內具有唯一 ID 的通知渠道對象。
  • 為該通知渠道對象配置所需的任何初始設置(例如提示音以及對用戶可見的可選說明)。
  • 將通知渠道對象提交到通知管理器。

如果試圖使用初始值創建的通知渠道已存在,不會執行任何操作,因此啟動應用時可以放心地執行以上步驟序列。

創建通知渠道組

如果應用支持多個帳戶,則可為每個帳戶創建一個通知渠道組。通知渠道組用於對一款應用內的多個同名通知渠道進行管理。例如,一款社交網絡應用可能提供面向個人帳戶以及企業帳戶的支持。在此情境下,每個帳戶可能都需要多個功能和名稱相同的通知渠道。
一個包括 2 個通知渠道的個人帳戶:

  • 帖子新增評論的通知。
  • 聯系人推薦帖子的通知。

一個包括 2 個通知渠道的企業帳戶:

  • 帖子新增評論的通知。
  • 聯系人推薦帖子的通知。

在本例中,將與每個用戶帳戶相關的通知渠道組織成專用組可確保用戶能在 Settings 中輕松地進行區分。每個通知渠道組都必須在軟件包內具有唯一 ID,並具有用戶可見的名稱。下面這段代碼演示了如何創建通知渠道組。

// 通知渠道組的id.
String group = "my_group_01";
// 用戶可見的通知渠道組名稱.
CharSequence name = getString(R.string.group_name);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannelGroup(new NotificationChannelGroup(group, name));

新建渠道組后,便可調用 setGroup()將某個新渠道關聯到該組。注意,只能在將渠道提交給通知管理器之前修改通知渠道與組之間的關聯。

創建通知

要創建通知,請調用 Notification.Builder.build(),它返回的 Notification對象包含的指定值。要發出通知,請通過調用 [notify()](https://developer.android.google.cn/reference/android/app/NotificationManager.html#notify(int, android.app.Notification))將 Notification對象傳遞給系統。
創建的通知Notification對象必須包含以下內容:

如果 應用是以 Android O 為目標平台並且在不指定有效通知渠道的情況下發布通知,那么通知將無法發布,系統會記錄錯誤。
注:可以在 Android O 中啟用一個新設置,當針對 Android O 的應用試圖在沒有通知渠道的情況下發布時,以 toast 形式顯示屏幕警告。要為運行 Android O 的開發設備啟用該設置,請轉到 Settings > Developer options,然后打開 Show notification channel warnings

向渠道發布通知

下面這段代碼說明如何向通知渠道發布簡單通知。請注意,代碼利用渠道的 ID 將通知與通知渠道關聯起來。

mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 為該通知設置一個id
int notifyID = 1;
// 通知渠道的id
String CHANNEL_ID = "my_channel_01";
// Create a notification and set the notification channel.
Notification notification = new Notification.Builder(MainActivity.this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status) 
.setChannelId(CHANNEL_ID)
.build();
// 發布通知
mNotificationManager.notify(id, notification);  

讀取通知渠道設置

用戶可以修改通知渠道的設置,包括振動和提示音等行為。開發者可以調用以下兩個方法來發現用戶對通知渠道應用的設置:

更新通知渠道設置

一旦創建了通知渠道,其設置和行為就由用戶掌控。可以再次調用 createNotificationChannel()以重命名現有通知渠道,或更新其說明。以下示例代碼說明如何通過創建啟動 Activity 的 Intent 將用戶重定向到通知渠道的設置。在本例中,Intent 要求提供擴展數據,包括通知渠道的 ID 和應用的軟件包名稱。

Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_CHANNEL_ID,mChannel.getId());
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());startActivity(intent);

刪除通知渠道

可以通過調用 deleteNotificationChannel()
來刪除通知渠道。作為一個垃圾信息預防機制,通知設置中將顯示已刪除渠道的數量。可以通過以下任一方法清除開發設備上的測試渠道:重新安裝應用;清除與應用副本關聯的數據。以下示例代碼演示了如何刪除通知渠道。

NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 通知渠道的id
String id = "my_channel_01";
NotificationChannel mChannel = mNotificationManager.getNotificationChannel(id);
mNotificationManager.deleteNotificationChannel(mChannel);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM