關於Android 通知

什麼是通知渠道

每條通知都要屬於一個對應的渠道。每一個App均可以自由地建立當前App擁有哪些通知渠道,可是這些通知渠道的控制權都是掌握在用戶手上的。用戶能夠自由地選擇這些通知渠道的重要程度,是否響鈴、是否振動、或者是否要關閉這個渠道的通知。Google此次對於8.0系統通知渠道的推廣態度仍是比較強硬的,targetSdkVersion在26以上若是不使用通知渠道的話,那麼App的通知將徹底沒法彈出。java

建立通知渠道

上代碼git

String channelId = "message";
    	String channelName = "消息提示";
        int importance = NotificationManager.IMPORTANCE_HIGH;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
            NotificationManager notificationManager = (NotificationManager) getSystemService(
                    NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);
        }
複製代碼

這裏建立了一個叫消息提示的的通知渠道,重要程度爲NotificationManager.IMPORTANCE_HIGH 緊急。github

建立通知渠道的這部分代碼,你能夠寫在Activity中,也能夠寫在Application中,實際上能夠寫在程序的任何位置,只須要保證在通知彈出以前調用就能夠了。而且建立通知渠道的代碼只在第一次執行的時候纔會建立,之後每次執行建立代碼系統會檢測到該通知渠道已經存在了,所以不會重複建立,也並不會影響任何效率。bash

顯示通知

NotificationManager notificationManager =
                (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE);

        Intent intent = new Intent(getContext(), NotificationActivity.class);
        PendingIntent pi = PendingIntent.getService(getContext(), 0, intent, 0);

        Notification notification = new NotificationCompat.Builder(this, channelId)
                //標題
                .setContentTitle("收到一條聊天消息")
                //內容
                .setContentText("今天中午吃什麼")
                //設置發送的時間
                .setWhen(System.currentTimeMillis())
                //設置小圖標(通知欄沒有下拉的圖標)
                .setSmallIcon(R.drawable.icon_done)
                //設置右側大圖標
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                        R.drawable.icon_head_hydra_2))
                //設置點擊通知後自動刪除通知
                .setAutoCancel(true)
                .setContentIntent(pi)
                .build();
        notificationManager.notify(1, notification);


        //彷佛只有設置了setContentIntent,AutoCancel才能生效
複製代碼

image.png

多行文字通知微信

NotificationManager notificationManager =
                (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE);

        Intent intent = new Intent(getContext(), NotificationActivity.class);
        PendingIntent pi = PendingIntent.getService(getContext(), 0, intent, 0);

        String title = "多行文字標題";
        String content =
                "多行文字內容,多行文字內容,多行文字內容,多行文字內容,多行文字內容,多行文字內容,多行文字內容,多行文字內容,多行文字內容,多行文字內容,多行文字內容";


        //建立多文字樣式
        NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle()
                .setBigContentTitle(title)
                .bigText(content);
        Notification notification = new NotificationCompat.Builder(this, channelId)
                //標題
                .setContentTitle("你有一條新消息")
                //設置小圖標(通知欄沒有下拉的圖標)
                .setSmallIcon(R.drawable.icon_done)
                //設置右側大圖標
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                        R.drawable.icon_head_hydra_2))
                //設置發送的時間
                .setWhen(System.currentTimeMillis())
                //設置點擊通知後自動刪除通知
                .setAutoCancel(true)
                .setContentIntent(pi)
                .setStyle(bigTextStyle)
                .build();
        notificationManager.notify(1, notification);

        //這裏設置setContentText 也不會生效,會直接顯示bigTextStyle裏的內容,下拉以後不會顯示setContentTitle,直接顯示bigText

複製代碼

彈出樣式

image.png

微信消息樣式app

NotificationManager notificationManager =
                (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE);

        Intent intent = new Intent(getContext(), NotificationActivity.class);
        PendingIntent pi = PendingIntent.getService(getContext(), 0, intent, 0);

        String title = "冰冰";
        ArrayList<String> messageList = new ArrayList<String>();
        messageList.add("今晚有空嗎?");
        messageList.add("晚上跟我一塊兒去玩吧?");
        messageList.add("怎麼不回覆我??我生氣了!!");
        messageList.add("我真生氣了!!!!!你聽見了嗎!");
        messageList.add("別不理我!!!");
        String content = "[" + messageList.size() + "條]" + title + ": " + messageList.get(0);


        NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
        for (String msg : messageList) {
            inboxStyle.addLine(msg);
        }
        inboxStyle.setSummaryText("[" + messageList.size() + "條]" + title);


        Notification notification = new NotificationCompat.Builder(this, channelId)
                //標題
                .setContentTitle(title)
                //內容
                .setContentText(content)
                //設置小圖標(通知欄沒有下拉的圖標)
                .setSmallIcon(R.drawable.icon_done)
                //設置右側大圖標
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                        R.drawable.icon_head_hydra_2))
                //設置發送的時間
                .setWhen(System.currentTimeMillis())
                //設置點擊通知後自動刪除通知
                .setAutoCancel(true)
                .setContentIntent(pi)
                .setStyle(inboxStyle)
                .build();
        notificationManager.notify(1, notification);
複製代碼

image.png

image.png

進度條樣式測試

NotificationManager notificationManager =
        (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE);

Intent intent = new Intent(getContext(), NotificationActivity.class);
PendingIntent pi = PendingIntent.getService(getContext(), 0, intent, 0);

Notification notification = new NotificationCompat.Builder(this, channelId)
        //標題
        .setContentTitle("正在下載")
        //內容
        .setContentText("50%")
        //設置發送的時間
        .setWhen(System.currentTimeMillis())
        //設置小圖標(通知欄沒有下拉的圖標)
        .setSmallIcon(R.drawable.icon_done)
        //設置右側大圖標
        .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                R.drawable.icon_head_hydra_2))
        //設置點擊通知後自動刪除通知
        .setAutoCancel(true)
        .setContentIntent(pi)
        //主要是這句
        .setProgress(100, 50, false)
        .build();
notificationManager.notify(1, notification);

//setProgress(100, 50, false)
複製代碼

image.png

大圖樣式ui

NotificationManager notificationManager =
        (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE);

Intent intent = new Intent(getContext(), NotificationActivity.class);
PendingIntent pi = PendingIntent.getService(getContext(), 0, intent, 0);


NotificationCompat.BigPictureStyle bigPictureStyle =
        new NotificationCompat.BigPictureStyle()
        .bigPicture(BitmapFactory.decodeResource(getResources(),
                R.drawable.icon_head_hydra_5))
        .setBigContentTitle("圖片標題");


Notification notification = new NotificationCompat.Builder(this, channelId)
        //標題
        .setContentTitle("你有一條新消息")
        .setContentText("圖片")
        //設置小圖標(通知欄沒有下拉的圖標)
        .setSmallIcon(R.drawable.icon_done)
        //設置右側大圖標
        .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                R.drawable.icon_head_hydra_2))
        //設置發送的時間
        .setWhen(System.currentTimeMillis())
        //設置點擊通知後自動刪除通知
        .setAutoCancel(true)
        .setContentIntent(pi)
        .setStyle(bigPictureStyle)
        .build();
notificationManager.notify(1, notification);
複製代碼

image.png

image.png

自定義通知欄viewthis

RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.custom_view_layout);
        // 設置點擊事件
        remoteViews.setOnClickPendingIntent(R.id.iv_play_or_pause, getActivityPendingIntent(1));
        remoteViews.setOnClickPendingIntent(R.id.iv_next, getActivityPendingIntent(2));
        remoteViews.setOnClickPendingIntent(R.id.iv_cancel, getActivityPendingIntent(3));

        remoteViews.setTextViewText(R.id.tv_title, "標題");
        remoteViews.setTextViewText(R.id.tv_summery, "藝術家");

NotificationManager notificationManager =
                (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE);

        Intent intent = new Intent(getContext(), NotificationActivity.class);
        PendingIntent pi = PendingIntent.getService(getContext(), 0, intent, 0);

        Notification notification = new NotificationCompat.Builder(this, channelId)
                //設置發送的時間
                .setWhen(System.currentTimeMillis())
                //設置小圖標(通知欄沒有下拉的圖標)
                .setSmallIcon(R.drawable.icon_done)
                //設置右側大圖標
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                        R.drawable.icon_head_hydra_2))
                //設置點擊通知後自動刪除通知
                .setAutoCancel(true)
                .setContentIntent(pi)
                .setContent(remoteViews)
                .build();
        notificationManager.notify(1, notification);
複製代碼

image.png

關於通知欄塊是很混亂的,Android系統大版本更新的時候常常有變更。國內廠商修改很嚴重,我手上有小米和vivo的測試機,以上的代碼在不一樣的手機上表現也各不相同。若是有用到複雜視圖的通知欄,最好是自定義通知欄view。spa

傳送門

資料

Android通知欄微技巧,8.0系統中通知欄的適配 NotifyUtil NotificationDemo

相關文章
相關標籤/搜索