Android 8.0 及以上 Notification 的適配工作

博主聲明:

轉載請在開頭附加本文鏈接及作者信息,並標記爲轉載。本文由博主 威威喵 原創,請多支持與指教。

本文首發於此   博主威威喵  |  博客主頁https://blog.csdn.net/smile_running

由於博主之前寫過的通知代碼,在 Android 8.0 以上跑的時候,卻怎麼也通知不出來。本來之前在其它模擬器(android 5.x)上進行測試的時候,還是好好的。突然在 8.0 上跑的時候,就不行了,這很明顯就是版本適配出現了問題。

於是呢,博主就去看了一些相關的資料,原來在 8.0 版本,谷歌就爲每一個通知設定了一個 NotificationChannel,如果在通知代碼裏沒有加這個 Channel 的話,在 8.0 及以上都無法顯示通知出來的。

好了,接下來通過一個簡單的 Demo 去適配 Android 8.0 及以上的通知,案例中包含了普通樣式的通知、自定義View樣式的通知、帶進度條的通知、以及懸浮式通知。

首先,我們要解決的一個問題,如何進行適配,既適配 8.0 及以上,和 8.0 以下。

先獲取 NotificationManager 的實例,用於管理通知:

    private NotificationManager mNotificationManager;

    mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

接着是創建 Notification 代碼,這裏就要對 Android 版本進行適配工作

    private Notification.Builder getNotificationBuilder() {
        checkOpenNotification(this);

        Notification.Builder builder;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // if android version >= 8.0
            builder = new Notification.Builder(this, "channel_id");

            @SuppressLint("WrongConstant")
            NotificationChannel channel = new NotificationChannel("channel_id", "channel_name",
                    NotificationManager.IMPORTANCE_DEFAULT);
            channel.setLockscreenVisibility(NotificationCompat.VISIBILITY_PUBLIC);
            mNotificationManager.createNotificationChannel(channel);
        } else {
            builder = new Notification.Builder(this);
        }

        builder.setContentTitle("content-title");
        builder.setContentText("content-text");
        builder.setSubText("sub-text");
        builder.setShowWhen(true);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
        builder.setSmallIcon(R.mipmap.ic_launcher_round);
        return builder;
    }

如果在 sdk 大於 8.0 及以上的時候,就要創建一個 NotificationChannel 的實例,小於 8.0 那就不需要了,並且可以在 Channel 中設置鈴聲、震動、呼吸燈、優先級等等。

接下來也是非常重要的一步,就是去系統設置裏面,將本應用的通知功能給打開,由於一些手機自己定製的系統,會默認將這項通知功能給關閉,如果不打開的話,也照樣顯示不了通知信息的。

由於用戶可以並不知道如何進行設置,我們可以用代碼來先檢測該功能是否被打開了,代碼如下:

    private void checkOpenNotification(Context context) {
        boolean notify = NotificationManagerCompat.from(context).areNotificationsEnabled();
        if (!notify) {
            Intent intent = new Intent();
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { // android 5.x - 9.x
                intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
                intent.putExtra("app_package", context.getPackageName());
                intent.putExtra("app_uid", context.getApplicationInfo().uid);
            } else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // android 4.x
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                intent.setData(Uri.parse("package:" + context.getPackageName()));
            } else {
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                intent.setData(Uri.fromParts("package", context.getPackageName(), null));
            }
            context.startActivity(intent);
        }
    }

 這裏設計到了不同版本系統的區別,以及跳轉到通知設置的方法,如果用戶沒有打開該權限,就會引導跳轉到設置頁面,將下面的通知功能打開即可。

一、創建普通樣式的通知

普通樣式的通知,就設置了通知內容、標題、副標題等信息,代碼很簡單,如下:

    private void showNormalNotification() {
        mNotificationManager.notify(1, getNotificationBuilder().build());
    }

效果圖如下:

二、創建自定義View樣式的通知 

自定義View樣式的通知,需要根據自己的需求來決定,比如像音樂播放器那種樣式的,就是一個自定義樣式,下面是一個簡單的佈局文件:

<?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="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_notify_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:textColor="#000000"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tv_notify_sub_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_notify_text"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="8dp"
        android:textSize="14sp" />

    <ImageView
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_below="@+id/tv_notify_sub_text"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:src="@mipmap/ic_launcher" />

    <Button
        android:id="@+id/btn_pending_intent"
        android:layout_width="80dp"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="8dp"
        android:text="點擊跳轉" />
</RelativeLayout>

通知代碼如下:

    private void showCustomNotification() {
        Notification.Builder builder = getNotificationBuilder();
        RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notify_content_view);
        contentView.setTextViewText(R.id.tv_notify_text, "Text");
        contentView.setTextViewText(R.id.tv_notify_sub_text, "SubText");
        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        contentView.setOnClickPendingIntent(R.id.btn_pending_intent, pendingIntent);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            builder.setCustomContentView(contentView);
        }
        mNotificationManager.notify(2, builder.build());
    }

效果圖:

 三、創建帶進度樣式的通知 

帶進度樣式的通知,可以用於系統更新、下載服務上,給用戶通知一下下載進度,代碼如下:

    private void showProgressNotification() {
        final Notification.Builder builder = getNotificationBuilder();
        builder.setOnlyAlertOnce(true);//設置震動、鈴聲等只提醒一次
        mNotificationManager.notify(3, builder.build());

        new Thread(new Runnable() {
            @Override
            public void run() {

                for (int i = 0; i <= 100; i++) {
                    try {
                        Thread.sleep(100);
                        builder.setProgress(100, i, false);
                        mNotificationManager.notify(3, builder.build());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        }).start();
    }

這裏僅做了一個線程模擬下載的例子,效果如下:

 四、創建懸浮式樣式的通知 

懸浮式樣式的通知場景也很多,比如現在的 App 一般都是用這種方式,但是博主發現,在我現在這個模擬器,Android 9.0 上始終無法懸浮出來,目前也沒有成功。但是,在 5.x 的系統上,是可以實現懸浮效果的。就如下面顯示的這樣:

其代碼如下:

    private void showSuspendNotification() {
        Notification.Builder builder = getNotificationBuilder();
        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        builder.setContentText("SuspendNotification")
                .setFullScreenIntent(pendingIntent, true);

        mNotificationManager.notify(4, builder.build());
    }

最後,這就是關於 Android 的通知方面的適配以及通知樣式相關的案例,到此也基本滿足我們日常開發中所需求的通知方式。

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