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 的通知方面的适配以及通知样式相关的案例,到此也基本满足我们日常开发中所需求的通知方式。

发布了101 篇原创文章 · 获赞 766 · 访问量 87万+

猜你喜欢

转载自blog.csdn.net/smile_Running/article/details/94357188