Android 通知

Android版本迭代速度很快,API也是改的很迅速,特別是Notification,很多API版本提供的方法樣式都不一樣,但是好在Android在appcompat-v7庫裏面提供了一個NofificationCompat類來處理兼容。在平時開發通知用的比較少,也沒有去總結他們,但是現在看到很多app的通知都比較炫酷,自己不熟悉心裏有個疙瘩。我們總結一些通知的類型以及使用。

通知分類

我們把通知分爲如下這四類:

  • 正常視圖,經常在狀態欄看到的高度爲64dp的通知視圖;
  • 在API16中引入的以Style方式展示的MediaStyle,InboxStyle,BigTexStyle,BigPictureStyle四種風格樣式
  • 自定義通知通知佈局
  • 在API21中加入的headsUpContentView

由於國產手機的定製我在自己的小米5Android 7.0系統上面顯示通知有一些問題,所以我們下面的分類圖以及代碼是根據Galaxy_Nexus_API_25的Android模擬器來做的。

普通通知

效果圖:


這裏寫圖片描述

實現代碼:

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext());
        Notification notification = builder
                .setContentTitle("這是普通通知標題")
                .setContentText("這是普通通知內容")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher2)
             .setLargeIcon(BitmapFactory.decodeResource(
                        getResources(), R.mipmap.ic_launcher2))
                .build();
        manager.notify(1, notification);

這類通知是我們平時看到App的最多的通知類型,實現代碼頁挺簡單。

API16以上的四種Style類型通知

在普通通知的基礎上面,可以增添這四種Style的類型

MediaStyle

我們通常看到音樂播放器之類的App會顯示這個通知類型。
效果圖:


這裏寫圖片描述

注意這個可以收縮的看我們從普通的通知模式到擴展Style的顯示樣式。
實現代碼:

private void typeMedia() {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle("MediaStyle");
        builder.setContentText("Song Title");
        builder.setSmallIcon(R.mipmap.ic_launcher2);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher2));
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        Intent intent = new Intent(this, ImageActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(this, 1, intent, 0);
        builder.setContentIntent(pIntent);
        //第一個參數是圖標資源id 第二個是圖標顯示的名稱,第三個圖標點擊要啓動的PendingIntent
        builder.addAction(R.drawable.ic_skip_previous_white_24dp, "", null);
        builder.addAction(R.drawable.ic_stop_white_24dp, "", null);
        builder.addAction(R.drawable.ic_play_arrow_white_24dp, "", pIntent);
        builder.addAction(R.drawable.ic_skip_next_white_24dp, "", null);
        NotificationCompat.MediaStyle style = new NotificationCompat.MediaStyle();
        style.setMediaSession(new MediaSessionCompat(this, "MediaSession",
                new ComponentName(MainActivity.this, Intent.ACTION_MEDIA_BUTTON), null).getSessionToken());
        //CancelButton在5.0以下的機器有效
        style.setCancelButtonIntent(pIntent);
        style.setShowCancelButton(true);
        //設置要現實在通知右方的圖標 最多三個
        style.setShowActionsInCompactView(2, 3);
        builder.setStyle(style);
        builder.setShowWhen(false);
        Notification notification = builder.build();
        manager.notify(TYPE_MEDIA, notification);
    }

InboxStyle

收件箱樣式,支持展示具有一串消息內容的樣式,按行顯示,適用於短信,郵件,IM等。
這裏寫圖片描述

private void typeInboxStyle() {
        NotificationCompat.InboxStyle style = new android.support.v4.app.NotificationCompat.InboxStyle();
        style.setBigContentTitle("這是InboxStyle的標題");
        for (int i = 0; i < 5; i++) {
            style.addLine("行" + i);
        }
        Notification notification = builder
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(
                        getResources(), R.mipmap.ic_launcher))
                .setStyle(style)
                .build();

        manager.notify(TYPE_INBOX, notification);
    }

BigTextStyle

可以顯示大段文字內容。


這裏寫圖片描述

private void typeBigText() {
        NotificationCompat.BigTextStyle style = new android.support.v4.app.NotificationCompat.BigTextStyle();
        style.bigText("很長的文本很長的文本很長的文本很長的文本" +
                "很長的文本很長的文本很長的文本很長的文本" +
                "很長的文本很長的文本很長的文本很長的文本");
        style.setBigContentTitle("這是很長的標題");
        style.setSummaryText("這是很長的末尾");
        Notification notification = builder
                .setContentTitle("這是通知標題")
                .setContentText("這是通知內容")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(
                        getResources(), R.mipmap.ic_launcher))
                .setStyle(style)
                .build();

        manager.notify(TYPE_BIG_TEXT, notification);
    }

BigPictureStyle

大圖樣式,除了在通知欄顯示標題和內容外,還可以顯示一張大圖片,最大高度爲256dp。


這裏寫圖片描述

public void bigPictureStyle(){
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
        android.support.v4.app.NotificationCompat.BigPictureStyle style = new android.support.v4.app.NotificationCompat.BigPictureStyle();
        style.setBigContentTitle("BigPictureTitle");
        style.setSummaryText("SummaryText");
        style.bigPicture(BitmapFactory.decodeResource(getResources(),R.drawable.big_picture));
        builder.setStyle(style);
        builder.setAutoCancel(true);
        Intent intent = new Intent(this,ImageActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
        //設置點擊大圖後跳轉
        builder.setContentIntent(pIntent);
        Notification notification = builder.build();
        manager.notify(TYPE_BIG_PICTURE,notification);
    }

自定義通知佈局

當以上的通知都無法滿足我們的需求的時候我們可以選擇RemoteViews來進行自定義通知的佈局文件。


這裏寫圖片描述

private void typeCustom(){
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
        RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.statu_view);
        builder.setContent(remoteViews);
        Intent intent = new Intent(this,ImageActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,1,intent,0);
        remoteViews.setOnClickPendingIntent(R.id.reply,pendingIntent);
        remoteViews.setTextViewText(R.id.title,"我是自定義標題");
        remoteViews.setTextViewText(R.id.content,"我是自定義內容");
        Notification notification = builder.build();
        manager.notify(TYPE_CUSTOM,notification);
    }

上述的設置的View我們發現是一個固定的64dp的高度。如果我們想要一個比這個高的咋辦呢,在API16引入了bigContentView它最大支持256dp。
佈局文件高度更改,代碼稍微改動一下

private void typeCustom(){
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
        RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.statu_view);
        Notification notification = builder.build();
        if(android.os.Build.VERSION.SDK_INT >= 16) {
            notification = builder.build();
            notification.bigContentView = remoteViews;
        }
        builder.setContent(remoteViews);
        Intent intent = new Intent(this,ImageActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,1,intent,0);
        remoteViews.setOnClickPendingIntent(R.id.reply,pendingIntent);
        remoteViews.setTextViewText(R.id.title,"我是自定義標題");
        remoteViews.setTextViewText(R.id.content,"我是自定義內容");
        manager.notify(TYPE_CUSTOM,notification);
    }

關於通知佈局適配手機通知的背景顏色可以參考這篇文章:查看。其實就是通過獲取手機的通知欄顯示的顏色來決定我們的佈局顏色。

headsUpContentView

這個通知不顯示在通知欄而是以橫幅的方式顯示在應用上方。這個效果在API21上纔有效。


這裏寫圖片描述

private void typeHeadsUpContentView(){
        builder.setContentTitle("橫幅通知標題");
        builder.setContentText("橫幅通知內容");
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
        Intent intent = new Intent(this,ImageActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
        builder.setContentIntent(pIntent);
        //這句是重點
        builder.setFullScreenIntent(pIntent,true);
        builder.setAutoCancel(true);
        Notification notification = builder.build();
        manager.notify(TYPE_HEAD_UP,notification);
    }

開發中使用過的通知

下載通知進度

  • 使用NotificationCompat.Builder.setProgress來實現
private void typeProgress() {
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setContentTitle("下載");
        builder.setContentText("正在下載");
        manager.notify(TYPE_PROGRESS, builder.build());
        builder.setProgress(100, 0, false);
        //下載以及安裝線程模擬
        new Thread(new Runnable() {
            @Override
            public void run() {
                float preProgress = 0;
                //模擬下載文件的小數點的progress避免1.01,1.02都更新倒置卡死應用。
                for (float progress = 0; progress < 100; progress++) {
                    int currProgress = (int) progress;
                    if (preProgress < currProgress) {
                        builder.setContentText(progress + "%");
                        builder.setProgress(100, (int) progress, false);
                        //下載進度提示
                        builder.setContentText("下載" + currProgress + "%");
                        manager.notify(TYPE_PROGRESS, builder.build());
                    }
                    preProgress = progress;
                    try {
                        Thread.sleep(50);//演示休眠50毫秒
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //下載完成後更改標題以及提示信息
                builder.setContentTitle("開始安裝");
                builder.setContentText("安裝中...");
                //設置進度爲不確定,用於模擬安裝
                builder.setProgress(0, 0, true);
                manager.notify(TYPE_PROGRESS, builder.build());
//                manager.cancel(TYPE_PROGRESS);//設置關閉通知欄
            }
        }).start();
    }
  • 使用系統提供的DownloadManager來實現
    參考查看

參考鏈接:
基本使用介紹
版本變更以及坑的解決
小圖標灰色問題
基礎知識以及適配

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章