Android 8.0系統(tǒng)的通知欄適配

為什么要進行通知欄適配搞糕?
現(xiàn)在經常是早上一覺醒來拿起手機一看脊髓,通知欄上全是各種APP的推送,煩署辉。隨著智能手機發(fā)展的成熟族铆,通知欄搞得越來越不討人喜歡了。各個App都希望搶占通知欄的空間哭尝,來盡可能地銷售自己的產品哥攘。

通知欄是Android系統(tǒng)原創(chuàng)的,雖說喬布斯一直認為Android系統(tǒng)是徹底抄襲iOS的一個產品材鹦,蘋果在iOS 5之后也抄襲了Android的通知欄逝淹。

通知欄的設計巧妙,它不占用屏幕空間桶唐,只有當用戶需要的時候用手指在狀態(tài)欄上向下滑動栅葡,通知欄的內容才會顯示出來,在智能手機發(fā)展的初期解決了手機屏幕小尤泽,內容展示不足的問題欣簇。

從Android 8.0系統(tǒng)開始规脸,Google引入了通知渠道這個概念。
什么是通知渠道呢熊咽?顧名思義莫鸭,就是每條通知都要屬于一個對應的渠道。每個App自由創(chuàng)建通知渠道横殴,但這些通知渠道的控制權都是掌握在用戶手上被因。用戶隨便設置通知渠道的重要程度,是否響鈴滥玷、是否振動氏身、或者是否要關閉這個渠道的通知。

舉個例子惑畴,我希望立馬收到支付寶的收款信息蛋欣,因為不想錯過每筆錢,但是又不想收到支付寶給我推薦的周圍美食如贷,因為我沒錢去大飯店陷虎。這種情況,支付寶就可以創(chuàng)建兩種通知渠道杠袱,一個收支尚猿,一個推薦,而我作為用戶對推薦類的通知討厭楣富,那么我直接把推薦通知渠道關閉凿掂,這樣不影響我關心的通知,又不會讓那些我不關心的通知來打擾我了纹蝴。

我一定要搞適配嗎庄萎?
Google這次對于8.0系統(tǒng)通知渠道的態(tài)度硬硬的。如果你升級了AppCompat庫塘安,所有使用AppCompat庫來構建通知的地方全部會進行廢棄方法提示糠涛,如下所示:


image.png

Google也并沒做絕,即使方法標為廢棄兼犯,還是可以湊合用忍捡。可是如果你將項目中的targetSdkVersion指定到了26或者更高切黔,Android系統(tǒng)認為APP已經做好了8.0系統(tǒng)的適配工作砸脊,當然包括了通知欄的適配。這個時候不使用通知渠道绕娘,你App的通知將不彈出脓规。

那么現(xiàn)在開始我們就正式來學習一下如何進行8.0系統(tǒng)中通知欄的適配。

創(chuàng)建通知渠道
首先我們使用Android Studio來新建一個項目险领,就叫它NoticationChannel

創(chuàng)建好項目侨舆,打開app/build.gradle文件檢查一下,targetSdkVersion已經指定到了26或者更高绢陌,如下:

android {
    compileSdkVersion 28
    buildToolsVersion "28.0.0"
    defaultConfig {
        applicationId "com.example.noticationchannel"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 100
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
}

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void sendChatMsg(View view) {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
      
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            String channelId = "chat";
            String channelName = "聊天消息";
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
            NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);
        }

        Notification notification = new NotificationCompat.Builder(this, "chat")
                .setContentTitle("來了吧挨下,小伙子 聊天消息")
                .setContentText("中午吃點啥呢臭笆?")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setAutoCancel(true)
                .build();
        manager.notify(1, notification);
    }

    public void sendSubscribeMsg(View view) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            String channelId = "subscribe";
            String channelName = "訂閱消息";
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
            NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);
        }

        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        Notification notification = new NotificationCompat.Builder(this, "subscribe")
                .setContentTitle("來了吧愁铺,小伙子 訂閱消息")
                .setContentText("房子便宜賣啦茵乱,有要買的嗎瓶竭!")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .setAutoCancel(true)
                .build();
        manager.notify(2, notification);
    }

    public void cancelChatMsg(View view) {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.cancel(1);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            manager.deleteNotificationChannel("chat");
        }
    }

    public void cancelSubscribeMsg(View view) {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.cancel(2);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            manager.deleteNotificationChannel("chat");
        }
    }

}
下面我們就來讓通知顯示出來首先修改activity_main.xml中的代碼斤贰,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="60dp"
        android:gravity="center_horizontal"
        android:orientation="horizontal">

        <androidx.appcompat.widget.AppCompatButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="sendChatMsg"
            android:text="發(fā)送聊天消息" />

        <androidx.appcompat.widget.AppCompatButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="cancelChatMsg"
            android:text="取消聊天消息" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="60dp"
        android:gravity="center_horizontal"
        android:orientation="horizontal">

        <androidx.appcompat.widget.AppCompatButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="sendSubscribeMsg"
            android:text="發(fā)送訂閱消息" />

        <androidx.appcompat.widget.AppCompatButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="cancelSubscribeMsg"
            android:text="取消訂閱消息" />

    </LinearLayout>

</LinearLayout>

想象一下我們正在開發(fā)類似于微信的APP,其中APP通知主要分為兩類送巡,一類是聊天消息授艰,這類消息非常重要世落,因此重要等級設為了IMPORTANCE_HIGH。另一類公眾號訂閱消息谷朝,這類消息不那么重要武花,重要等級+我設為了IMPORTANCE_DEFAULT。當然专钉,重要等級還可以設置為IMPORTANCE_LOW、+IMPORTANCE_MIN跃须,分別對應更低的通知重要程度菇民。

代碼不長第练,要確保的是當前手機的系統(tǒng)版本必須是Android 8.0系統(tǒng)或者更高娇掏,低版本的手機系統(tǒng)沒有通知渠道功能驹碍,不做系統(tǒng)版本檢查會在低版本手機上造成崩潰。

創(chuàng)建通知渠道很簡單怔球,需要注意的是竟坛,創(chuàng)建一個通知渠道需要渠道ID钧舌、渠道名稱以及重要等級這三個參數(shù)洼冻,其中渠道ID隨便寫崭歧,只要保證全局獨一份就可以。渠道名稱是給用戶看的撞牢,要能夠表達清楚這個渠道的用途。等級不同決定通知行為不同屋彪,這里只是初始狀態(tài)下的等級,用戶隨時更改渠道的等級畜挥,APP 無法干預仔粥。

現(xiàn)在運行一下代碼了,運行成功之后躯泰,點擊發(fā)送聊天消息谭羔,點擊發(fā)送訂閱消息,狀態(tài)欄上會有通知小圖標斟冕,用手指在狀態(tài)欄上向下滑動缅阳,如下圖所示:


image.png

剛才我們創(chuàng)建兩個通知渠道已經顯示出來了十办。由于這兩個通知渠道的重要等級不同,通知的行為也是不同的,聊天消息可以發(fā)出在屏幕上彈出通知再扭,而訂閱消息不會彈出通知。

進入到設置 -> 應用 -> 通知當中泛范,查看NoticationChannel這個APP的通知界面罢荡,如下圖所示:


image.png

當然,用戶還可以點擊進去對該通知渠道進行任意的修改对扶,比如降低聊天消息的重要等級区赵,甚至是可以完全關閉該渠道的通知。

管理通知渠道
通知渠道一旦創(chuàng)建就不能再通過代碼修改了浪南。為此笼才,Android賦予了開發(fā)者讀取通知渠道配置的權限,如果某個功能必須配置通知渠道才能使用络凿,可以提示用戶手動更改通知渠道配置骡送。

概念總是抽象,我們還是通過具體例子來實象喷众。想象我們開發(fā)的是一個類似于微信的APP各谚,聊天消息是重要地,如果用戶將聊天消息的通知渠道關閉了到千,所有重要聊天通知全部都丟了昌渤,為此我們一定要保證用戶打開了聊天消息通知渠道才行。

修改MainActivity中的代碼

public void sendChatMsg(View view) {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = manager.getNotificationChannel("chat");
            if (channel != null && channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
                Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
                intent.putExtra(Settings.EXTRA_CHANNEL_ID, channel.getId());
                startActivity(intent);
                Toast.makeText(this, "請手動將通知打開", Toast.LENGTH_SHORT).show();
            }
        }
      ......
}

這里我們對sendChatMsg()方法進行了修改憔四,通過getNotificationChannel()方法獲取到了NotificationChannel對象膀息,如果為null般眉,沒有設置通知渠道,否則就可以讀取該通知渠道下的所有配置了潜支。這里我們判斷如果通知渠道的importance等于IMPORTANCE_NONE甸赃,就說明用戶將該渠道的通知給關閉了,這時會跳轉到通知的設置界面提醒用戶手動打開冗酿。

1 當聊天消息的通知渠道關閉后埠对,下次再次發(fā)送聊天消息直接跳轉到通知設置界面,提醒用戶手動將通知打開裁替。
2 除了以上管理通知渠道的方式之外项玛,Android 8.0還賦予了我們刪除通知渠道的功能,只需使用如下代碼即可刪除:
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.deleteNotificationChannel(channelId);

文章中的示例源碼點擊 https://github.com/githubwwj/NoticationChannel下載

喜歡就分享給你身邊的三個小伙伴

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末弱判,一起剝皮案震驚了整個濱河市襟沮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌昌腰,老刑警劉巖开伏,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異遭商,居然都是意外死亡固灵,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門株婴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怎虫,“玉大人,你說我怎么就攤上這事困介〈笊螅” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵座哩,是天一觀的道長徒扶。 經常有香客問我,道長根穷,這世上最難降的妖魔是什么姜骡? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮屿良,結果婚禮上圈澈,老公的妹妹穿的比我還像新娘。我一直安慰自己尘惧,他們只是感情好康栈,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般啥么。 火紅的嫁衣襯著肌膚如雪登舞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天悬荣,我揣著相機與錄音菠秒,去河邊找鬼。 笑死氯迂,一個胖子當著我的面吹牛践叠,可吹牛的內容都是我干的。 我是一名探鬼主播囚戚,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼酵熙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了驰坊?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤哮独,失蹤者是張志新(化名)和其女友劉穎拳芙,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體皮璧,經...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡舟扎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了悴务。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片睹限。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖讯檐,靈堂內的尸體忽然破棺而出羡疗,到底是詐尸還是另有隱情,我是刑警寧澤别洪,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布叨恨,位于F島的核電站,受9級特大地震影響挖垛,放射性物質發(fā)生泄漏痒钝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一痢毒、第九天 我趴在偏房一處隱蔽的房頂上張望送矩。 院中可真熱鬧,春花似錦哪替、人聲如沸栋荸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒸其。三九已至敏释,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間摸袁,已是汗流浹背钥顽。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留靠汁,地道東北人蜂大。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像蝶怔,于是被迫代替她去往敵國和親奶浦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356