Android O(8.0) Notification解決方案

1愤炸、Android O(8.0)通知的改變

NotificationChannel是android8.0新增的特性,如果App的targetSDKVersion>=26粗悯,沒有設(shè)置channel通知渠道的話俄占,就會(huì)導(dǎo)致通知無(wú)法展示辐烂。

Android O 引入了 通知渠道(Notification Channels),以提供統(tǒng)一的系統(tǒng)來(lái)幫助用戶管理通知验残,如果是針對(duì) android O 為目標(biāo)平臺(tái)時(shí)捞附,必須實(shí)現(xiàn)一個(gè)或者多個(gè)通知渠道,以向用戶顯示通知。比如聊天軟件鸟召,為每個(gè)聊天組設(shè)置一個(gè)通知渠道胆绊,指定特定聲音、燈光等配置欧募。

2压状、Android Channel通知的兼容支配

創(chuàng)建NotificationChannel

  1. 創(chuàng)建NotificationChannel對(duì)象,指定Channel的id跟继、name和通知的重要程度
  2. 使用NotificationMannager的createNotificationChannel方法來(lái)添加Channel何缓。
 private NotificationManager getNotificationManager() {
        if (mNotificationManager == null) {
            mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        }
        return mNotificationManager;
  }
    @NonNull
    private NotificationCompat.Builder getNotificationBuilder() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("channel_id", "channel_name",
                    NotificationManager.IMPORTANCE_DEFAULT);
            //是否繞過(guò)請(qǐng)勿打擾模式
            channel.canBypassDnd();
            //閃光燈
            channel.enableLights(true);
            //鎖屏顯示通知
            channel.setLockscreenVisibility(VISIBILITY_SECRET);
            //閃關(guān)燈的燈光顏色
            channel.setLightColor(Color.RED);
            //桌面launcher的消息角標(biāo)
            channel.canShowBadge();
            //是否允許震動(dòng)
            channel.enableVibration(true);
            //獲取系統(tǒng)通知響鈴聲音的配置
            channel.getAudioAttributes();
            //獲取通知取到組
            channel.getGroup();
            //設(shè)置可繞過(guò)  請(qǐng)勿打擾模式
            channel.setBypassDnd(true);
            //設(shè)置震動(dòng)模式
            channel.setVibrationPattern(new long[]{100, 100, 200});
            //是否會(huì)有燈光
            channel.shouldShowLights();
            getNotificationManager().createNotificationChannel(channel);
        }
        NotificationCompat.Builder notification = new NotificationCompat.Builder(this, "channel_id");
        notification.setContentTitle("新消息來(lái)了");
        notification.setContentText("周末到了,不用上班了");
        notification.setSmallIcon(R.mipmap.ic_launcher);
        notification.setAutoCancel(true);
        return notification;
    }
  1. 設(shè)置通知重要性級(jí)別
    該級(jí)別必須要在 NotificationChannel 的構(gòu)造函數(shù)中指定还栓,總共要五個(gè)級(jí)別碌廓;范圍是從 NotificationManager.IMPORTANCE_NONE(0) ~ NotificationManager.IMPORTANCE_HIGH(4)
    ,如果要支持 Android 7.1(API 25)及以下的設(shè)備剩盒,還得調(diào)用NotificationCompat 的 setPriority 方法來(lái)設(shè)置谷婆,如下所示
builder.setPriority(NotificationCompat.PRIORITY_DEFAULT);

Android 8.0 及以上是使用NotificationManager.IMPORTANCE_,Android 7.1 及以下是使用NotificationCompat.PRIORITY_它們都是定義的常量辽聊;下面我們以表格的形式更好的展示出來(lái)纪挎。

用戶通知級(jí)別 Android8.0及以上 Android7.0及以下
緊急級(jí)別(發(fā)出通知聲音并顯示為提示通知) IMPORTANCE_HIGH PRIORITY_HIGH或者PRIORITY_MAX
高級(jí)別(發(fā)出通知聲音并且通知欄有通知) IMPORTANCE_DEFAULT PRIORITY_DEFAULT
中等級(jí)別(沒有通知聲音但通知欄有通知) IMPORTANCE_LOW PRIORITY_LOW
低級(jí)別(沒有通知聲音也不會(huì)出現(xiàn)在狀態(tài)欄上) IMPORTANCE_MIN PRIORITY_MIN

上面這些通知級(jí)別用戶都是可以在 Channel 設(shè)置中更改

3、Android Channel通知的應(yīng)用與管理(更新跟匆、刪除)

4异袄、自定義Channel通知欄

 private void sendCustomNotification() {
        NotificationCompat.Builder builder = getNotificationBuilder();
        RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_custom_notifition);
        remoteViews.setTextViewText(R.id.notification_title, "custom_title");
        remoteViews.setTextViewText(R.id.notification_content, "custom_content");

        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, -1,
                intent, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.turn_next, pendingIntent);
        builder.setCustomContentView(remoteViews);
        getNotificationManager().notify(3, builder.build());
    }
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/notification_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="通知欄標(biāo)題"
            android:textSize="24sp"/>

        <TextView
            android:id="@+id/notification_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="通知欄內(nèi)容"/>

    </LinearLayout>

    <Button
        android:id="@+id/turn_next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="跳轉(zhuǎn)"/>
</RelativeLayout>

5、封裝的代碼


public class NotificationUtils extends ContextWrapper {

    public static final String CHANNEL_ID = "default";
    private static final String CHANNEL_NAME = "Default Channel";
    private static final String CHANNEL_DESCRIPTION = "this is default channel!";
    private NotificationManager mManager;

    public NotificationUtils(Context base) {
        super(base);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel();
        }
    }

    @TargetApi(Build.VERSION_CODES.O)
    private void createNotificationChannel() {
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
       //是否繞過(guò)請(qǐng)勿打擾模式
        channel.canBypassDnd();
        //閃光燈
        channel.enableLights(true);
        //鎖屏顯示通知
        channel.setLockscreenVisibility(VISIBILITY_SECRET);
        //閃關(guān)燈的燈光顏色
        channel.setLightColor(Color.RED);
        //桌面launcher的消息角標(biāo)
        channel.canShowBadge();
        //是否允許震動(dòng)
        channel.enableVibration(true);
        //獲取系統(tǒng)通知響鈴聲音的配置
        channel.getAudioAttributes();
        //獲取通知取到組
        channel.getGroup();
        //設(shè)置可繞過(guò)  請(qǐng)勿打擾模式
        channel.setBypassDnd(true);
        //設(shè)置震動(dòng)模式
        channel.setVibrationPattern(new long[]{100, 100, 200});
        //是否會(huì)有燈光
        channel.shouldShowLights();
        getManager().createNotificationChannel(channel);
    }

    private NotificationManager getManager() {
        if (mManager == null) {
            mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        }
        return mManager;
    }

   /**
     * 發(fā)送通知
     */
    public void sendNotification(String title, String content) {
        NotificationCompat.Builder builder = getNotification(title, content);
        getManager().notify(1, builder.build());
    }

    private NotificationCompat.Builder getNotification(String title, String content) {
        NotificationCompat.Builder builder = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID);
        } else {
            builder = new NotificationCompat.Builder(getApplicationContext());
            builder.setPriority(PRIORITY_DEFAULT);
        }
        //標(biāo)題
        builder.setContentTitle(title);
        //文本內(nèi)容
        builder.setContentText(content);
        //小圖標(biāo)
        builder.setSmallIcon(R.mipmap.ic_launcher);
        //設(shè)置點(diǎn)擊信息后自動(dòng)清除通知
        builder.setAutoCancel(true);
        return builder;
    }

    /**
     * 發(fā)送通知
     */
    public void sendNotification(int notifyId, String title, String content) {
        NotificationCompat.Builder builder = getNotification(title, content);
        getManager().notify(notifyId, builder.build());
    }

    /**
     * 發(fā)送帶有進(jìn)度的通知
     */
    public void sendNotificationProgress(String title, String content, int progress, PendingIntent intent) {
        NotificationCompat.Builder builder = getNotificationProgress(title, content, progress, intent);
        getManager().notify(0, builder.build());
    }

    /**
     * 獲取帶有進(jìn)度的Notification
     */
    private NotificationCompat.Builder getNotificationProgress(String title, String content,
                                                               int progress, PendingIntent intent) {
        NotificationCompat.Builder builder = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID);
        } else {
            builder = new NotificationCompat.Builder(getApplicationContext());
            builder.setPriority(PRIORITY_DEFAULT);
        }
        //標(biāo)題
        builder.setContentTitle(title);
        //文本內(nèi)容
        builder.setContentText(content);
        //小圖標(biāo)
        builder.setSmallIcon(R.mipmap.ic_launcher);
        //設(shè)置大圖標(biāo)玛臂,未設(shè)置時(shí)使用小圖標(biāo)代替烤蜕,拉下通知欄顯示的那個(gè)圖標(biāo)
        //設(shè)置大圖片 BitmpFactory.decodeResource(Resource res,int id) 根據(jù)給定的資源Id解析成位圖
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
        if (progress > 0 && progress < 100) {
            //一種是有進(jìn)度刻度的(false),一種是循環(huán)流動(dòng)的(true)
            //設(shè)置為false,表示刻度迹冤,設(shè)置為true讽营,表示流動(dòng)
            builder.setProgress(100, progress, false);
        } else {
            //0,0,false,可以將進(jìn)度條隱藏
            builder.setProgress(0, 0, false);
            builder.setContentText("下載完成");
        }
        //設(shè)置點(diǎn)擊信息后自動(dòng)清除通知
        builder.setAutoCancel(true);
        //通知的時(shí)間
        builder.setWhen(System.currentTimeMillis());
        //設(shè)置點(diǎn)擊信息后的跳轉(zhuǎn)(意圖)
        builder.setContentIntent(intent);
        return builder;
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市泡徙,隨后出現(xiàn)的幾起案子橱鹏,更是在濱河造成了極大的恐慌,老刑警劉巖堪藐,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件莉兰,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡礁竞,警方通過(guò)查閱死者的電腦和手機(jī)糖荒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)苏章,“玉大人寂嘉,你說(shuō)我怎么就攤上這事奏瞬。” “怎么了泉孩?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵硼端,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我寓搬,道長(zhǎng)珍昨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任句喷,我火速辦了婚禮镣典,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘唾琼。我一直安慰自己兄春,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布锡溯。 她就那樣靜靜地躺著赶舆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祭饭。 梳的紋絲不亂的頭發(fā)上芜茵,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音倡蝙,去河邊找鬼九串。 笑死,一個(gè)胖子當(dāng)著我的面吹牛寺鸥,可吹牛的內(nèi)容都是我干的猪钮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼析既,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼躬贡!你這毒婦竟也來(lái)了谆奥?” 一聲冷哼從身側(cè)響起眼坏,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎酸些,沒想到半個(gè)月后宰译,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡魄懂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年沿侈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片市栗。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缀拭,死狀恐怖咳短,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蛛淋,我是刑警寧澤咙好,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站褐荷,受9級(jí)特大地震影響勾效,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜叛甫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一层宫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧其监,春花似錦萌腿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至睛约,卻和暖如春鼎俘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辩涝。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工贸伐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人怔揩。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓捉邢,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親商膊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子伏伐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 摘自郭神的文章: 從Android 8.0系統(tǒng)開始,Google引入了通知渠道這個(gè)概念晕拆。 什么是通知渠道呢藐翎?顧名思...
    D___Will閱讀 3,318評(píng)論 0 1
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,079評(píng)論 25 707
  • 介紹 Android O 引入了 通知渠道(Notification Channels),以提供統(tǒng)一的系統(tǒng)來(lái)幫助用...
    屋檐下的燕雀閱讀 35,872評(píng)論 12 23
  • 文/今小那 小時(shí)候实幕, 夢(mèng)想是游樂場(chǎng)吝镣, 是跌跌撞撞, 是塵土飛揚(yáng)昆庇, 是零食和糖末贾, 是有你在的夢(mèng)鄉(xiāng)。 長(zhǎng)大后整吆, 夢(mèng)想是...
    金筱閱讀 321評(píng)論 1 4
  • 讀經(jīng)日期:2018年04月27日 農(nóng)歷:三月十二 星期:五 天氣:晴 煒圣:5周11個(gè)月 系統(tǒng)讀經(jīng)周期:第八十四周...
    泉州煒圣媽閱讀 130評(píng)論 0 1