[JAVA] Programming from 51 years old Note --reference

I didn't understand Notification well, so I made a reference memo for myself. The code is handmade, so if you want to refer to it, use the linked code.

Reference site

https://developer.android.com/guide/topics/ui/notifiers/notifications?hl=ja

A little preamble

android-Level and notification

Level Notification unit
Android7(API25)Before Notification isApp unit
Android8(API26)Or later Notification isChannel unit
Assign all notifications to channels
Multiple channel (notification) settings in one app
Channel ID required
Level Importance setting
Android7(API25)Before priority
Android8(API26)Or later importance

Notification compatibility

Use the support library notification API ・ NotificationCompat and its subclasses ・ NotificationManagerCompat

ForegroundService

https://developer.android.com/guide/components/services.html#Foreground

Needed to be resident ・ Excludes the target of forced termination by the system ・ Notification is required for services that perform background processing for a long time ・ To delete the notification, stop the service or cancel the foreground state.

** Run service in the foreground ** startForeground (notification identification ID, notification) Notification identification ID is other than 0

** Remove service from foreground ** stopForeground () parametar: bool value-> whether to delete the notification

** Stop service itself ** Service itself stopSelf () Other components stopService () Bind service unbindService ()

Notification creation Android 4.0 (API 14) or later

https://developer.android.com/training/notify-user/build-notification.html

at first

Here, coding is done using NotificationCompat of APIs of Android Support library, but it is supported by android4.0 (API14) or later, and some functions are not compatible.

Most projects created in Android Studio need to use NotificationCompat, so make sure that "com.android.support:suppport-compat: 28.0.0" is included in build.gradle. However, even if you are using another com.android.support group, there are APIs that can use NotificationCompat, so in that case it is OK even if build.gradle does not include support-compat: 28.0.0.

Basic notification items

・ Icon (small) ・ Title ・ Text content

For other settings, see> https://developer.android.com/guide/topics/ui/notifiers/notifications.html#Templates

Setting the content to be notified

Use the NotificationCompat.Builder object </ font> to set the content and channels to be notified.

content Method to use Remarks
Small icon serSmallIcon() Limited to content that users can manage
title serContentTitle()
Text setContentText()
priority setPriority() Android7.Before 1 depends on the need for notification
Android8.After 0, the developer sets the channel priority

python


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

For API26 and above, NotificationCompat.Buileder requires a channel ID. </ font> (API 25 and below are controlled by application, not by channel)

By default, the notification text is one line, and if you want to make it longer, use the setStyle () method (usage omitted). For longer notifications, images and media,> https://developer.android.com/training/notify-user/expanded.html

Set the channel for notifications and set the importance

Please use the createNotificationChannel (channnel) method </ font> to subscribe to the channel before you can be notified on Android 8.0 or later. The argument channel is an instance of NotificationChannnel (Channel_ID, name, importance) </ font>. The code below checks the Android version with SDK_INT and subscribes to the channel while blocking levels below Android 8.0.

python


private void createNotificationChannel(){
     //Generate a notification channel.
     //Since the notification channel is a function of API 26 or later
     //This process is only for API 26 or later

    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 notification channel in the system
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
         }
}

On Android 8.0 and above, you need to generate a notification channel before sending notifications, so run this code immediately after running the app.

Reuse the already created notification channel (channel in the above code) and create a new channel (notificationManager.createNotificationChannele (channel) in the above code) to notify. Does not work as well. So it's safer to run the above code every time you notify. </ font>

In the NotificationChannel constructor, it is necessary to specify the importance, so specify it with a constant of the NotificationManager class.

Constant of importance Remarks
IMPORTANCE_HIGH There is sound, there is head up
IMPORTANCE_DEFAULT With sound
IMPORTANCE_LOW No sound
IMPORTANCE_MIN No sound, no status bar display

The display and sound are determined by the importance of the notification. The importance can be changed by the user in the system settings. In Android7.1 (API25) or earlier, the importance is determined by the priority of Notification.

The developer has to set the importance (API26 ~; importance / ~ API25: priority), but the system may change the importance due to various factors, or the user may change the importance. Therefore, it may not meet the expectations of the developer.

For more information on importance> https://developer.android.com/training/notify-user/channels.html#importance

Notification tap operation

Normally, tapping a notification opens an activity that responds to the notification. For that, the developer defines content intent PendingIntent object </ font> (like an intent that continues to exist even after the activity ends). Specify / font and execute setContentIntent () </ font>. Below is the generic code.

--The following starts AlertDetails.class by tapping - If you want to open MainActivity by tapping, set
Intent intent = new Intent (this, MainActivity.class);
. </ font>

python


//Generate an explicit intent to open the activity
//Tap to open Alert Details
// MainActivity.Open MainActivity when class is specified
Intent intent = new Intent(this, AlertDetails.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
      //Set Intent to fire with notification tap
        .setContentIntent(pendingIntent)
        .setAutoCancel(true);

Below is a code supplement

setAutoCancel() Tap to automatically delete notifications

setFlag() Keep a history of apps opened from notifications. Whether to use Flag depends on the type of activity you are starting. During normal app usage, the user does not need to navigate to this activity, so the activity starts a new task instead of adding an existing task and back stack.

In the above code (intent.setFlag ()), Intent.FLAG_ACTIVITY_NEW_TASK Always start with a new task Intent.FLAG_ACTIVITY_CLEAR_TASK Clear the task and start it As you are launching a new task.

If the activity is in the normal flow of the app (? Is it working properly?) Generates a back stack at the start of the activity and keeps the back, up, and button functions (?).

If you want to create a different notification intent> https://developer.android.com/training/notify-user/navigation.html

Display notifications

Execution of notification is NotificationManagerCompat.notify (notificationId, builder.build ()) </ font> notification ID is a unique ID (integer) </ font> builder.build () is the return value of the NoticicatonCompat.Builder.build () </ font> method

python


NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);

//notificationID is a unique integer. The developer assigns a number to each notification
notificationManager.notify(notificationId, builder.build());

The notificationID set by notify () will be used later when deleting updates and notifications, so be sure to record it. </ font>

Starting with Android 8.1 (API level 27), the app cannot play the notification sound multiple times per second. If the app sends multiple notifications within a second, all notifications will appear as expected, but only the first notification will sound However, Android also enforces rate limiting when updating notifications. If you send one notification update too often (many times in less than a second), the system may discard some updates.

Add action button

It provides three action buttons to help users respond quickly, including smooth reminders and text message notifications. Don't do button actions when the user taps the notification.

To generate an action button, addAction (icon, string, PendingIntent) </ font> You can do various things instead of invoking the activity. For example, start a broadcast receive in the background without interrupting an already open app.

Code that sends a broadcast to a specific receiver
Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
snoozeIntent.setAction(ACTION_SNOOZE);
snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
PendingIntent snoozePendingIntent =
        PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent);

For details on how to use the background processing of Broadvast Receiver, see> https://developer.android.com/guide/components/broadcasts.html

To create a notification from the pause button, skip track button (next song), etc.> https://developer.android.com/training/notify-user/expanded.html#media-style

Direct reply action

Ability to enter text directly into notifications without opening an activity

For example, you can have users respond to notifications directly with messages, or you can update your task list.

The direct reply action is implemented by adding a text entry field to the notification. The system passes the user's response message to the application through the intent of the action that corresponds to the notification.

Generate reply button

Creating a notification with a direct reply function

    1. Create a RemoteInput.Builder instance
  1. Generate PendingIntent
    1. Associate a RemoteInput object with an action using addRemoteInput ()
  2. Associate actions with notifications and execute notifications </ font>

1. RemoteInput.Builder Instance Creation </ font> Add a RemoteInput.Builder instance to the notification. The constructor of this class takes a string of key values of the input text used by the system as an actual argument. The developer extracts the input text from the key value and uses it.

//Key value (string) to pass to the intent of the action
private static final String KEY_TEXT_REPLY = "key_text_reply";

String replyLabel = getResources().getString(R.string.reply_label);
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
        .setLabel(replyLabel)
        .build();

2. PendingIntent generation </ font>

PendeingIntent replyPendingIntent = 
       PendingIntent.getBroadcast(
               getApplicationContext(),
               conversation.getConversationId(),
               getMessageReplyIntent(conversation.getConversationId()),
               PendingIntent.FLAG_UPDATE_CURRENT
               );

* Note
When reusing PendingIntent, the user will try to reply to a different conversation than before the reuse. Developers can either issue a unique request code for each conversation, or issue an intent that does not return true when using the equals () method in the reply intent of another conversation. Make sure to distinguish it from the reply. </ font>

3. addRemoteIntent (): Associate a RemoteInput object with an action </ font>

//Create reply actions and add remote inputs
// new NotificationCompat.Action.Builder().addRemoteInput().build()

NotificationCompat.Action action =
        new NotificationCompat.Action.Builder(
                 R.drawable.ic_reply_icon,
                 getString(R.string.label), 
                 replyPendingIntent)
            .addRemoteInput(remoteInput).build();

4. Associate action with notification to execute notification </ font>

python


//Create notifications and add actions
Notification newMessageNotification = new Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentTitle(getString(R.string.title))
        .setContentText(getString(R.string.content))
        .addAction(action)
        .build();

//Notification issuance
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, newMessageNotification);

As shown in Figure 3 (omitted), the notification action triggers the user to enter a response.

Get user input from reply

to receive user input from the notification reply UI Call RemoteInput.getResultsFromIntent () </ font> and Obtained through the Intent received by BroadcastReceiver </ font>.

python


private CharSequence getMessageText(Intent intent) {
    Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
    if (remoteInput != null) {
        return remoteInput.getCharSequence(KEY_TEXT_REPLY);
    }
    return null;
 }

After processing the user input text, call NotificationManagerCompat.notify () </ font> to notify using the same ID as the notification ID (if you used a tag, the same tag). Please update. This process is necessary to pass the user's reply, check whether the process was performed correctly, and hide the reply UI.

python


//The system generates a new notification to let you know that the previous notification exchange has been processed.
Notification repliedNotification = new Notification.Builder(context, CHANNEL_ID)
        .setSmallIcon(R.drawable.ic_message)
        .setContentText(getString(R.string.replied))
        .build();

//Issue a notification
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, repliedNotification);

Use the context passed to the received onReceive () method </ font> when this new notification is working.

Developers use setRemoteInputHistory () </ font> to add a reply to the notification button. If the developer is creating a messaging app, the developer should generate a "messageing-style notificaton" and add the new message to the user interaction.

For more information on messaging app related notifications> https://developer.android.com/training/notify-user/build-notification.html#messaging-best-practices

Add progress bar

You can add an animated display (progress bar) to the notification to let the user know the progress of the process.

If you can measure the progress of the process, use setProgress (max, progress, false) </ font> to display the progress using the indicator's "determinaite" form. The first parameter of setProgress () is an indicator of completion such as 100% display, the second parameter is an indicator of how much progress is currently being made, and finally, a "determinate" progress bar is specified for progress. Masu (?).

As the process progresses, setProgress (max, progress, false) will be called constantly with updates to the progress value, and notifications will continue to be issued.

python


NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setContentTitle("Picture Download")
        .setContentText("Download in progress")
        .setSmallIcon(R.drawable.ic_notification)
        .setPriority(NotificationCompat.PRIORITY_LOW);

//Issue first notification of progress 0
int PROGRESS_MAX = 100;
int PROGRESS_CURRENT = 0;
builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
notificationManager.notify(notificationId, builder.build());

//Track progress
//Normally, this tracking task is the variable PROGRESS._While updating CURRENT and notifications
//Must be done in a worker thread to show progress.
//The method to use is
// builder.setProgress(PROGRESSS_MAX,PROGRESS_CURRENT,fale);
// notificationManager.notify(notifcationId,builder.build());
//When finished, update the notification and remove the progress bar

builder.setContentText("Download complete")
        .setProgress(0,0,false);
notificationManager.notify(notificationId, builder.build());

At the end of the process, the progress should be at its maximum. Developers can hide or remove the progress bar at the end of the process. In this case, please update to the notification that the process is completed. Use setProgress (0,0, false) </ font> to remove the progress bar.

Note:
The progress bar keeps notifications updated, so you usually need to run your code in a background service. </ font>

Use setProgress (0,0, true) </ font> to display the "indeterminate" progress bar (a bar that does not show progress as a percentage). It is the same type of display as the progress bar above (except for the animation progress bar that does not show progress). This progress animation will continue until you call setProgress (0,0, fares) and remove the display. Remember to change the notification text to indicate that the process is complete.

Note:
In order to actually download the file, you need to consider DownloadManager </ font>. This is a class for providing progress information on your download. </ font>

set asystem-wide category abridgement set lock screen bisibility abridgement

Delete notification

Notifications will continue to be displayed until one of the following occurs: ・ The user releases the notification -When the developer generated the notification, the user clicked the notification while calling setAutoCancel () </ font>. -The developer calls the cancel () </ font> method for a specific notification ID. This method also removes ongoing notifications -The developer calls cancelAll () </ font> This method removes all previously issued notifications -When the developer uses setTimeoutAfter () </ font> to generate a notification and sets a timeout, the system will cancel the notification after a certain amount of time has passed. If necessary, you can cancel the notification before a certain timeout has elapsed.

Optimal execution of messaging app

Use the list of best practices for quick references to keep in mind to generate notifications for your messaging and chat apps.

Use MessageingStyle Starting with Android7.0 (API24), we provide special notification style templates for message content. The NotificationCompat.MessagingStyle class </ font> allows you to use different levels of notifications such as titles, additional messages, and looks.

The following generic code demonstrates how to customize notifications using the MessageingStyle class.

python


Notification notification = new Notification.Builder(this, CHANNEL_ID)
        .setStyle(new NotificationCompat.MessagingStyle("Me")
                .setConversationTitle("Team lunch")
                .addMessage("Hi", timestamp1, null) // Pass in null for user.
                .addMessage("What's up?", timestamp2, "Coworker")
                .addMessage("Not much", timestamp3, null)
                .addMessage("How about lunch?", timestamp4, "Coworker"))
        .build();

Since Android8.0 (API26), you can use more folding content forms by using NotificationCompat.MessagingStyle class </ font>. You can also now use the addHistoricMessage () </ font> method, which provides a conversational context by adding the message history to the message notification.

When using NotificationCompat.MessagingStyle </ font> ... -Call MessageingStyle.setConbersationTitle () </ font> to set the title of a chat group of two or more people. A good conversation title might be a group chat group name, or a list of conversation participants, especially if you don't have one. Without a conversation title, the conversation group would be mistaken for a one-on-one conversation group with the most up-to-date comment sender. -Use the MessagingStyle.setData () </ font> method that contains media messages such as images. The image / * pattern MIME type is supported.

Use direct reply Direct Reple allows users to reply inline -After the user makes an inline reply, use MessagingStyle.addMessage () </ font> to update the message style notification. Does not cancel the notification. If you allow notification cancellation, you will be able to make multiple replies from notifications. -By calling Action.WearableExtender.setHintDisplayInlineAction (true) </ font>, you can create an inline reply consistent with Wear OS. -Use addHistoricMessage () </ font> to add message history to notifications to provide context for direct conversation replies.

Enable smart reply -Call setallowGeneratedResponses (true) </ font> in the reply action to enable smart reply. In this case, the notification is passed to the Wear OS device to enable smart replies.

The smart reply response is generated by an "entry on-watch machine learning model" using the context provided by the NotificationCompat.MessageingStyle notification. The data used to generate the response is never uploaded over the Internet.

Add notification metadata -Assign notification metadata so that the system handles app notifications when the device is in silent mode.

Recommended Posts