Android 通知的应用

333 阅读5分钟

1、创建基本通知

最基本、精简形式(也称为折叠形式)的通知会显示一个图标、一个标题和少量内容文本。在本部分中,您将了解如何创建用户点击后可启动应用中的 Activity 的通知。

设置通知内容 首先,您需要使用 NotificationCompat.Builder 对象设置通知内容和渠道。以下示例显示了如何创建包含下列内容的通知: 小图标,通过 setSmallIcon() 设置。这是所必需的唯一用户可见内容。标题, 通过 setContentTitle() 设置。 正文文本,通过 setContentText() 设置。 通知优先级,通过 setPriority() 设置。 优先级确定通知在 Android 7.1 和更低版本上的干扰程度。(对于 Android 8.0 和更高版本,必须设置渠道重要性)

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle(textTitle)
            .setContentText(textContent)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);

请注意,NotificationCompat.Builder 构造函数要求您提供渠道 ID。这是兼容 Android 8.0(API 级别 26)及更高版本所必需的,但会被较旧版本忽略。 默认情况下,通知的文本内容会被截断以放在一行。如果您想要更长的通知,可以使用 setStyle() 添加样式模板来启用可展开的通知。例如,以下代码会创建更大的文本区域:

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Much longer text that cannot fit one line...")
            .setStyle(new NotificationCompat.BigTextStyle()
                    .bigText("Much longer text that cannot fit one line..."))
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);

创建渠道并设置重要性 必须先通过向 createNotificationChannel() 传递 NotificationChannel 的实例在系统中注册应用的通知渠道,然后才能在 Android 8.0 及更高版本上提供通知。因此以下代码会被 SDK_INT 版本上的条件阻止:

private void createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = getString(R.string.channel_name);
            String description = getString(R.string.channel_description);
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
            channel.setDescription(description);
            // Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }

2、创建展开式通知

基本通知通常包括标题、一行文本,以及用户可以执行的一项或多项响应操作。如需提供更多信息,您还可以应用本页介绍的多个通知模板之一来创建大型展开式通知。

首先,使用创建通知中介绍的所有基本内容创建通知。然后,使用一个样式对象调用 setStyle(),并提供与每个模板相对应的信息(如下所示)。

添加大图片

如需在通知中添加图片,请将 NotificationCompat.BigPictureStyle 的一个实例传递给 setStyle()。

Notification notification = new NotificationCompat.Builder(context, CHANNEL_ID)
            .setSmallIcon(R.drawable.new_post)
            .setContentTitle(imageTitle)
            .setContentText(imageDescription)
            .setStyle(new NotificationCompat.BigPictureStyle()
                   .bigPicture(myBitmap))
            .build();

如需使该图片仅在通知收起时显示为缩略图(如图 1 所示),请调用 setLargeIcon() 并向其传递图片,同时调用 BigPictureStyle.bigLargeIcon() 并向其传递 null,这样大图标就会在通知展开时消失:

Notification notification = new NotificationCompat.Builder(context, CHANNEL_ID)
            .setSmallIcon(R.drawable.new_post)
            .setContentTitle(imageTitle)
            .setContentText(imageDescription)
            .setLargeIcon(myBitmap)
            .setStyle(new NotificationCompat.BigPictureStyle()
                    .bigPicture(myBitmap)
                    .bigLargeIcon(null))
            .build();

工具类

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.widget.RemoteViews;

/**
 * @author 阿童木
 * @date 2020/8/28 9:57
 * @功能: 自定义通知
 */

public class NotificationManager {
    private static PushNotionManager instance;
    private String CHANNEL_ID = "custom_notification";
    Context context;

    public static PushNotionManager getInstance() {
        if (instance == null) {
            instance = new PushNotionManager();
        }
        return instance;
    }

    /**
     * @author 阿童木
     * @create 2020/8/28 14:10
     * @Describe 显示通知
     * 显示通知,请调用 NotificationManagerCompat.notify(),并将通知的唯一 ID 和 NotificationCompat.Builder.build() 的结果传递给它
     */
    int notificationId=1;
    public void showNotification(Context context) {
        NotificationManager notificationManager = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            notificationManager = context.getSystemService(NotificationManager.class);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //创建渠道并设置重要性
            //必须先通过向 createNotificationChannel() 传递 NotificationChannel 的实例在系统中注册应用的通知渠道,
            //然后才能在 Android 8.0 及更高版本上提供通知。
            //因此以下代码会被 SDK_INT 版本上的条件阻止:
            CharSequence name = "channel_name";
            String description = "channel_name_cch";
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
            channel.setDescription(description);
            // Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            notificationManager.createNotificationChannel(channel);
        }
        // notificationId is a unique int for each notification that you must define(notificationId是您必须定义的每个通知的唯一int)
        //请记得保存您传递到 NotificationManagerCompat.notify() 的通知 ID,因为如果之后您想要更新或移除通知,将需要使用这个 ID。
        notificationManager.notify(notificationId, getBigNotification(context));
    }

    /**
     * @author 阿童木
     * @create 2020/8/28 11:57
     * @Describe Create a custom notification layout(创建自定义通知布局)
     * 根据手机系统不同,有的可以直接展开大图模式,有的需要下拉才能展开。
     */
    private Notification getCustomNotification(Context context) {
        this.context = context;
        // 获取要在自定义通知中使用的布局(默认)
        RemoteViews notificationLayout = new RemoteViews(context.getPackageName(), R.layout.notification_small);
        //获取要在自定义通知中使用的布局(展开时的)
        RemoteViews notificationLayoutExpanded = new RemoteViews(context.getPackageName(), R.layout.notification_large);

        // Apply the layouts to the notification
        //使用 NotificationCompat.Builder 构建基本通知。
        return new NotificationCompat.Builder(context, CHANNEL_ID)
                .setSmallIcon(R.mipmap.notifation_small_icon)
                //调用 setStyle(),向其传递一个 NotificationCompat.DecoratedCustomViewStyle 实例。
                .setStyle(new NotificationCompat.DecoratedCustomViewStyle())
                //调用 setCustomContentView() 以设置收起后通知的布局。
                .setCustomContentView(notificationLayout)
                //自定义布局扩充为 RemoteViews
                .setCustomBigContentView(notificationLayoutExpanded)
                .build();
    }

    /**
     * @author 阿童木
     * @create 2020/8/28 13:59
     * @Describe 创建展开式通知
     */
    public Notification getBigNotification(Context context) {
        this.context = context;
        Notification notification = new NotificationCompat.Builder(context, CHANNEL_ID)
                .setSmallIcon(R.mipmap.notifation_small_icon)
                .setContentTitle("imageTitle")
                .setContentText("创建展开式通知基本通知通常包括标题、一行文本,以及用户可以执行的一项或多项响应操作。如需提供更多信息,您还可以应用本页介绍的多个通知模板之一来创建大型展开式通知。首先,使用创建通知中介绍的所有基本内容创建通知。然后,使用一个样式对象调用 setStyle(),并提供与每个模板相对应的信息(如下所示)。")
                //添加大图片\添加一大段文本
                .setStyle(getBigContentStyle(1))
                //通知优先级,通过 setPriority()
                .setPriority(NotificationCompat.PRIORITY_DEFAULT )
                // Set the intent that will fire when the user taps the notification  设置通知的点按操作 创建基本 Intent,以在用户点按通知时打开 Activity
                .setContentIntent(getPendingIntent())
                //此代码会调用 setAutoCancel(),它会在用户点按通知后自动移除通知。
                .setAutoCancel(true)
                .build();
        return notification;
    }

    /**
     * @author 阿童木
     * @create 2020/8/28 13:59
     * @Describe 添加大图片\添加一大段文本
     */
    private NotificationCompat.Style getBigContentStyle(int i) {
        if (i == 1) {
            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.big_picture);
            //添加大图片 如需在通知中添加图片,请将 NotificationCompat.BigPictureStyle 的一个实例传递给 setStyle()。
            return new NotificationCompat.BigPictureStyle().bigPicture(bitmap);
        } else {
            //添加一大段文本 应用 NotificationCompat.BigTextStyle,以在通知的展开内容区域显示文本
            return new NotificationCompat.BigTextStyle().bigText("添加一大段文本\n" +
                    "应用 NotificationCompat.BigTextStyle,以在通知的展开内容区域显示文本:" + "Notification notification = new NotificationCompat.Builder(context, CHANNEL_ID)\n" +
                    "            .setSmallIcon(R.drawable.new_mail)\n" +
                    "            .setContentTitle(emailObject.getSenderName())\n" +
                    "            .setContentText(emailObject.getSubject())\n" +
                    "            .setLargeIcon(emailObject.getSenderAvatar())\n" +
                    "            .setStyle(new NotificationCompat.BigTextStyle()\n" +
                    "                    .bigText(emailObject.getSubjectAndSnippet()))\n" +
                    "            .build();");
        }
    }

    /**
     * @author 阿童木
     * @create 2020/8/28 14:03
     * @Describe 设置通知的点按操作
     */
    public PendingIntent getPendingIntent() {
        // Create an explicit intent for an Activity in your app
        Intent intent = new Intent(context, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
        return pendingIntent;
    }


}