preface

Notification, which I’m sure most Android students will be familiar with, Many online tutorials on the use of Notification are based on Android 8.0 or below. Currently, most Android devices are from Android 6.0 to Android9.0, and this section introduces Android to you 8.0 or below,Android8.0 or above adaptation;

You can check it out

[the official documentation] developer. The android. Google. Cn/guide/topic…

Notification Bar Introduction

The function of the notification bar

Notification bar’s main purpose is to tell even if some important information users, the design of the notification bar is very clever, don’t have to take up the space, only in the notification bar shows that when the user can see the drop-down, set up a notification if the user has the highest level of words, when the message will display content in the current interface (time to 2 seconds), then I will hide in the notification bar.

Notification panel adaptation

The main difficulty here is 8.0(targetSdkVersion=26). If below 8.0, we can find display notifications in the application and turn them off. In this way, we can not receive all notifications (including some important information). That is, every notification should belong to a corresponding channel. Each App is free to create what notification channels the App currently has, but the control of these notification channels is always in the hands of the user.

Does it have to fit?

Google this time for 8.0 system notification channels to promote the attitude is relatively strong.

First, if you upgrade the AppCompat library, all places that use the AppCompat library to build notifications will be given deprecation methods, as shown below:

The figure above tells us that this method is obsolete and needs to be used with a notification channel.

Method of use

Create notification channels

First make sure targetSdkVersion is specified to 26 or higher, as shown below:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.example.notificationtest"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
}
Copy the code

Create channel code

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
     String channelId = "chat";
     String channelName = "Chat message";
     int importance = NotificationManager.IMPORTANCE_HIGH;
     createNotificationChannel(channelId, channelName, importance);

     channelId = "subscribe";
     channelName = "Other news";
     importance = NotificationManager.IMPORTANCE_DEFAULT;
     createNotificationChannel(channelId, channelName, importance);
}

@TargetApi(Build.VERSION_CODES.O)
private void createNotificationChannel(String channelId, String channelName, int importance) {
     NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
     NotificationManager notificationManager = (NotificationManager) getSystemService(
                NOTIFICATION_SERVICE);
     notificationManager.createNotificationChannel(channel);
    }
Copy the code

It’s not a long code, so let me explain it briefly. Here we create two notification channels in MainActivity. The first thing to make sure is that the current operating system version of the phone must be Android 8.0 or higher, because the earlier version of the phone does not have notification channels, failing to check the system version will cause a crash on the earlier version of the phone.

Create a notification channel way is very simple, here I enclosed a createNotificationChannel () method, the logic inside believe that everyone can read. Note that creating a notification channel requires at least three parameters: channel ID, channel name, and importance level. The channel ID can be arbitrarily defined as long as global uniqueness is guaranteed. The channel name is for the user to see and needs to be able to express the purpose of the channel. Of course, the importance level here is only in the initial state. Users can manually change the importance level of a channel at any time, and App cannot intervene.

Encapsulated utility class

Write it down for later study

/** * Notification tool class **@authorIwen was surprised@create2021/11/16 alone * /
public class QlNotificationUtil {

    private static final String TAG = "QlNotificationUtil";

    /** * request code */
    public static final int RequestCode = 1;

    /** * New message */
    public static final String NEW_MESSAGE = "chat";

    /**
     * 群消息
     */
    public static final String NEW_GROUP = "chat_group";

    /**
     * 其他消息
     */
    public static final String OTHER_MESSAGE = "other";

    /** ** prompt */
    public static final String Ticker = "You have a new message.";

    / * * * * /
    public static final String CHECK_OP_NO_THROW = "checkOpNoThrow";

    /** * Release notification */
    public static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";

    /** * notifyId */
    public static int notifyId = 0;

    /** * create notification channels for Android8.0 * tips: you can write in MainActivity, in Application, in fact, anywhere in the Application, * just make sure that the notification is called before it pops up. In addition, the code to create the notification channel is created only at the first execution. * Each subsequent execution of the code creation system will detect that the notification channel already exists, so it will not be created repeatedly and will not affect any efficiency. * /
    public static void setNotificationChannel(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String channelId = NEW_MESSAGE;
            String channelName = "New Message Notification";
            createNotificationChannel(context, channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
            channelId = OTHER_MESSAGE;
            channelName = "Other Notices"; createNotificationChannel(context, channelId, channelName, NotificationManager.IMPORTANCE_HIGH); }}/** * create a configuration notification channel **@paramChannelId channelId *@paramChannelName channelName *@paramPriority */
    @TargetApi(Build.VERSION_CODES.O)
    private static void createNotificationChannel(Context context, String channelId, String channelName, int importance) {
// createNotificationGroup(context,channelId,channelName);
        NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
        // Forbid this channel to use corner markers
        channel.setShowBadge(false);
        // Set the channel group ID
// channel.setGroup(channelId);
        // Configure the properties of the notification channel
// channel.setDescription (" Channel description ");
        // Set the flashing light when notifications appear (if supported by Android devices)
        channel.enableLights(true);
        // Set the vibration when notifications appear (if supported by Android devices)
        channel.enableVibration(true);
        // The above Settings make the mobile phone: static for 1 second, vibrate for 2 seconds, static for 1 second, vibrate for 3 seconds
/ / channel. SetVibrationPattern (new long [] {1000, 2000, 1000300 0}).
        // Set whether the lock screen displays notifications
        channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        // Set the breath lamp color
        channel.setLightColor(Color.BLUE);
        // Set whether do not Disturb mode can be bypassed
        channel.setBypassDnd(true);
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannel(channel);
    }

    /** * Create channel group (if there are many notification channels, divide channel group) **@paramGroupId channel groupId *@paramGroupName channel groupName */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static void createNotificationGroup(Context context, String groupId, String groupName) {
        NotificationChannelGroup group = new NotificationChannelGroup(groupId, groupName);
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannelGroup(group);
    }

    /** * Send notification (refresh previous notification) **@paramContext *@paramContentTitle title *@param* / contentText content
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void show(Context context, String contentTitle, String contentText, Class
        cls) {
        show(context, contentTitle, contentText, null.0, NEW_MESSAGE, cls);
    }

    /** * Send custom notifications (refresh previous notifications) **@paramContext *@paramContentTitle title *@param* / contentText content
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void show(Context context, String contentTitle, String contentText, RemoteViews views, Class
        cls) {
        show(context, contentTitle, contentText, views, 0, NEW_MESSAGE, cls);
    }

    /** * Send notifications (refresh previous notifications to specify notification channels) **@paramContentTitle title *@paramContentText content *@paramChannelId channelId */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void show(Context context, String contentTitle, String contentText, String channelId, Class
        cls) {
        show(context, contentTitle, contentText, null.0, channelId, cls);
    }

    /** * Send custom notifications (refresh previous notifications to specify notification channels) **@paramContentTitle title *@paramContentText content *@paramChannelId channelId */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void show(Context context, String contentTitle, String contentText, RemoteViews views, String channelId, Class
        cls) {
        show(context, contentTitle, contentText, views, 0, channelId, cls);
    }

    /** * Send multiple notifications (default notification channel) **@paramContentTitle title *@param* / contentText content
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void showMuch(Context context, String contentTitle, String contentText, Class
        cls) {
        show(context, contentTitle, contentText, null, ++notifyId, NEW_MESSAGE, cls);
    }

    /** * Send multiple custom notifications (default notification channel) **@paramContentTitle title *@param* / contentText content
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void showMuch(Context context, String contentTitle, String contentText, RemoteViews views, Class
        cls) {
        show(context, contentTitle, contentText, views, ++notifyId, NEW_MESSAGE, cls);
    }

    /** * Send multiple notifications (specify notification channels) **@paramContentTitle title *@paramContentText content *@paramChannelId channelId */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void showMuch(Context context, String contentTitle, String contentText, String channelId, Class
        cls) {
        show(context, contentTitle, contentText, null, ++notifyId, channelId, cls);
    }

    /** * Send multiple custom notifications (specify notification channels) **@paramContentTitle title *@paramContentText content *@paramChannelId channelId */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void showMuch(Context context, String contentTitle, String contentText, String channelId, RemoteViews views, Class
        cls) {
        show(context, contentTitle, contentText, views, ++notifyId, channelId, cls);
    }

    /** * Send notifications (set default: large icon/small icon/subtitle/subtitle/priority/first pop-up text) **@paramContentTitle title *@paramContentText content *@paramNotifyId Notification bar ID *@paramChannelId indicates the channelId *@paramCLS intent class */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void show(Context context, String contentTitle, String contentText, RemoteViews views, intnotifyId, String channelId, Class<? > cls) {
        show(context, 0.0, contentTitle, null, contentText, NotificationManager.IMPORTANCE_DEFAULT, null, views, notifyId, channelId, cls);
    }

    /** ** Send notification **@paramLargeIcon largeIcon *@paramSmallIcon smallIcon *@paramContentTitle title *@paramSubText Subtitle/subtitle *@paramContentText content *@paramPriority Priority *@paramThe text * displayed on the status bar when ticker notifications first pop up@paramNotifyId defines whether to display multiple notification bars *@paramCLS intent class */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void show(Context context, int largeIcon,
                            int smallIcon, String contentTitle,
                            String subText, String contentText,
                            int priority, String ticker, RemoteViews view,
                            intnotifyId, String channelId, Class<? > cls) {
        //flags
        // FLAG_ONE_SHOT: indicates that this PendingIntent can only be used once
        // FLAG_IMMUTABLE: indicates that a created PendingIntent should be immutable
        FLAG_NO_CREATE: indicates that if the described PendingIntent does not already exist, null is returned instead of creating it.
        FLAG_CANCEL_CURRENT: indicates that if the described PendingIntent already exists, it should be canceled before generating a new PendingIntent
        FLAG_UPDATE_CURRENT: indicates that if the described PendingIntent already exists, it is retained, but its additional data is replaced with the content in the new Intent
        PendingIntent pendingIntent = null;
        // Add hidden schematics
        if(cls ! =null) {
            Intent intent = new Intent(context, cls);
            pendingIntent = PendingIntent.getActivity(context, RequestCode, intent, FLAG_UPDATE_CURRENT);
        }
        // Get the notification service manager
        NotificationManager manager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
        // Check whether application notifications are enabled
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if(! openNotificationChannel(context, manager, channelId)) {return; }}This constructor Builder(context, channel name) is recommended in API 26.1.0
        NotificationCompat.Builder builder = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) ? new NotificationCompat.Builder(context, channelId) : new NotificationCompat.Builder(context);
        builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), largeIcon == 0 ? R.mipmap.app_icon : largeIcon)) // Set the large ICONS displayed in the ticker box and notifications.
                .setSmallIcon(smallIcon == 0 ? R.mipmap.app_icon : smallIcon) / / small icon
                .setContentText(TextUtils.isEmpty(contentText) ? null : contentText) / / content
                .setContentTitle(TextUtils.isEmpty(contentTitle) ? null : contentTitle) / / title
                .setSubText(TextUtils.isEmpty(subText) ? null : subText) // Subtitle of APP name
                .setPriority(priority) // Set the priority PRIORITY_DEFAULT
                .setTicker(TextUtils.isEmpty(ticker) ? Ticker : ticker) // Sets the text to display in the status bar when the notification first pops up
                .setContent(view)
                .setWhen(System.currentTimeMillis()) // Set the timestamp for notifications to be sent
                .setShowWhen(true)// Sets whether to display the timestamp
                .setAutoCancel(true)// Click the notification and the notification disappears in the notification bar
                .setDefaults(Notification.PRIORITY_HIGH)// Set the default notification options used by default sound, vibration mode, lighting, etc
                .setContentIntent(pendingIntent) // Set the notification click event
                // Display the notification icon and title when the screen is locked
                VISIBILITY_PUBLIC displays this notification in its entirety on all lock screens
                // 2. VISIBILITY_PRIVATE Hides sensitive or private information on the security lock screen
                // 3, VISIBILITY_SECRET does not display any part
                //.setvisibility (notification.visibility_private)// Some phones have no effect
                .setFullScreenIntent(pendingIntent, true)// Suspension notification 8.0 needs to be opened manually
// .setColorized(true)
//.setGroupSummary(true)// Sets this notification to the group summary of a set of notifications
SetGroup (NEW_GROUP)// Use the group key
SetDeleteIntent (pendingIntent)// Send an intent when the user clears the notification directly from the notification panel
// .setFullScreenIntent(pendingIntent,true)
SetContentInfo (" big text ")// Set the big text to the right of the notification.
//.setContent(RemoteViews RemoteView)// Set custom notification bar
// .setColor(Color.parseColor("#ff0000"))
SetLights ()// The arGB value and rate at which the LED on the device is expected to blink
SetTimeoutAfter (3000)// Specifies when to cancel this notification (if it has not been cancelled).
        ;

        // Notification id
        manager.notify(notifyId, builder.build()); The build() method requires a minimum of 16 apis,
    }

    /** * Check whether app channel notifications are enabled (adaptation 8.0) **@returnTrue open * /
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static Boolean openNotificationChannel(Context context, NotificationManager manager, String channelId) {
        // Check whether the notification is open
        if(! isNotificationEnabled(context)) { toNotifySetting(context,null);
            return false;
        }
        // Check whether channel notifications are open
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = manager.getNotificationChannel(channelId);
            if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
                // The Settings screen is not opened
                toNotifySetting(context, channel.getId());
                return false; }}return true;
    }

    /** * Check whether application notifications are enabled@return* /
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static boolean isNotificationEnabled(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
            return notificationManagerCompat.areNotificationsEnabled();
        }
        AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        Class appOpsClass = null;
        /* Context.APP_OPS_MANAGER */
        try {
            appOpsClass = Class.forName(AppOpsManager.class.getName());
            Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE, String.class);
            Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION);
            int value = (Integer) opPostNotificationValue.get(Integer.class);
            return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, context.getApplicationInfo().uid, context.getPackageName()) == AppOpsManager.MODE_ALLOWED);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /** * Manually open app notifications */
    public static void toNotifySetting(Context context, String channelId) {
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // For 8.0 and later (8.0 requires opening app notifications first, then channel notifications)
            if (TextUtils.isEmpty(channelId)) {
                intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
            } else{ intent.setAction(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName()); intent.putExtra(Settings.EXTRA_CHANNEL_ID, channelId); }}else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {// For 5.0 and above
            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra("app_package", context.getPackageName());
            intent.putExtra("app_uid", context.getApplicationInfo().uid);
        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {// Fit 4.4 and above
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setData(Uri.fromParts("package", context.getPackageName(), null));
        } else{ intent.setAction(Settings.ACTION_SETTINGS); } context.startActivity(intent); }}Copy the code

Method of use

  • To initialize the
  • Direct callshowmethods
// Initialize the notification bar (adaptation 8.0)
QlNotificationUtil.setNotificationChannel(getContext());
// Send the same notification
QlNotificationUtil.show(getContext(),"Received a chat message."."What's for lunch today?".null);
// Send multiple notifications
QlNotificationUtil.showMuch(getContext(),"Received a subscription message"."What's for lunch today?".null);
Copy the code

Well, that’s all for today’s introduction ~