Android捆绑通知
在本教程中,我们将在Android应用程序中实现捆绑通知。
我们已经看到并实现了针对Android Nougat的直接回复。
如果您不了解通知和待定意图,请先阅读本教程,然后再继续。
Android捆绑通知
当垂直堆积过多的通知时,Android捆绑通知非常方便。
捆绑的通知将它们全部折叠到一个通知中,并在组通知上设置了组摘要。
这使我们免于滚动浏览所有通知。
另外,如果您一次收到许多单个通知,则捆绑的通知不会发出多个嘈杂的通知声音,而是会发出单个通知声音。
捆绑通知的格式为:
- 1摘要通知
- N个随附的单一通知
我们可以为每个通知设置单独的音调。
每个捆绑通知都将具有相同的组密钥。
添加新通知后,它会与匹配的组密钥合并到捆绑包中。
我们可以为每个通知单击添加单独的操作,也可以为捆绑通知单击添加单独的操作。
捆绑通知可以不带任何附带的通知而存在。
创建捆绑通知
捆绑通知是通过以下方式定义的。
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel groupChannel = new NotificationChannel("bundle_channel_id", "bundle_channel_name", NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(groupChannel);
}
NotificationCompat.Builder summaryNotificationBuilder = new NotificationCompat.Builder(this, "bundle_channel_id")
.setGroup(bundle_notification_id)
.setGroupSummary(true)
.setContentTitle("Bundled Notification. " + bundleNotificationId)
.setContentText("Content Text for bundle notification")
.setSmallIcon(R.mipmap.ic_launcher);
notificationManager.notify(bundleNotificationId, summaryNotificationBuilder.build());
捆绑通知必须将setGroupSummary()设置为true。
必须在包中包含的所有通知中设置在setGroup()方法中设置的组密钥。
注意:从Android Oreo开始,需要定义bundle_channel_id。
我们已经在另一本教程中详细讨论了通知渠道。
我们已将捆绑包通知渠道的重要性设置为"低",以避免捆绑包同时发出声音和发出单个通知。
我们将为单个通知创建一个单独的渠道。
在示例应用程序中,我们将实现捆绑通知功能。
我们将使用一个按钮创建一个新的捆绑包,并使用另一个按钮在当前的捆绑包中添加新的单一通知。
点击通知后,我们将取消该通知并将其ID显示在Toast中。
在本教程中,我们将不再关注后端的推送通知。
我们的目标是仅了解捆绑通知功能。
Android捆绑通知项目结构
单一活动应用程序。
Android捆绑通知代码
下面给出了" activity_main.xml"布局类的代码。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.theitroad.bundlednotificationsexample.MainActivity">
<Button
android:id="@+id/btnBundleNotification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Bundle Notification"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
<Button
android:id="@+id/btnSingleNotification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Notification to Bundle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnBundleNotification"
</android.support.constraint.ConstraintLayout>
下面给出了MainActivity.java类的代码。
package com.theitroad.bundlednotificationsexample;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button btnBundleNotification, btnSingleNotification;
NotificationManager notificationManager;
int bundleNotificationId = 100;
int singleNotificationId = 100;
NotificationCompat.Builder summaryNotificationBuilder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
btnBundleNotification = findViewById(R.id.btnBundleNotification);
btnSingleNotification = findViewById(R.id.btnSingleNotification);
btnBundleNotification.setOnClickListener(this);
btnSingleNotification.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnBundleNotification:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel groupChannel = new NotificationChannel("bundle_channel_id", "bundle_channel_name", NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(groupChannel);
}
bundleNotificationId += 100;
singleNotificationId = bundleNotificationId;
String bundle_notification_id = "bundle_notification_" + bundleNotificationId;
Intent resultIntent = new Intent(this, MainActivity.class);
resultIntent.putExtra("notification", "Summary Notification Clicked");
resultIntent.putExtra("notification_id", bundleNotificationId);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
summaryNotificationBuilder = new NotificationCompat.Builder(this, "bundle_channel_id")
.setGroup(bundle_notification_id)
.setGroupSummary(true)
.setContentTitle("Bundled Notification. " + bundleNotificationId)
.setContentText("Content Text for bundle notification")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(resultPendingIntent);
notificationManager.notify(bundleNotificationId, summaryNotificationBuilder.build());
break;
case R.id.btnSingleNotification:
bundle_notification_id = "bundle_notification_" + bundleNotificationId;
resultIntent = new Intent(this, MainActivity.class);
resultIntent.putExtra("notification", "Summary Notification Clicked");
resultIntent.putExtra("notification_id", bundleNotificationId);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//We need to update the bundle notification every time a new notification comes up.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
if (notificationManager.getNotificationChannels().size() < 2) {
NotificationChannel groupChannel = new NotificationChannel("bundle_channel_id", "bundle_channel_name", NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(groupChannel);
NotificationChannel channel = new NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
}
summaryNotificationBuilder = new NotificationCompat.Builder(this, "bundle_channel_id")
.setGroup(bundle_notification_id)
.setGroupSummary(true)
.setContentTitle("Bundled Notification " + bundleNotificationId)
.setContentText("Content Text for group summary")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(resultPendingIntent);
if (singleNotificationId == bundleNotificationId)
singleNotificationId = bundleNotificationId + 1;
else
singleNotificationId++;
resultIntent = new Intent(this, MainActivity.class);
resultIntent.putExtra("notification", "Single notification clicked");
resultIntent.putExtra("notification_id", singleNotificationId);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notification = new NotificationCompat.Builder(this, "channel_id")
.setGroup(bundle_notification_id)
.setContentTitle("New Notification " + singleNotificationId)
.setContentText("Content for the notification")
.setSmallIcon(R.mipmap.ic_launcher)
.setGroupSummary(false)
.setContentIntent(resultPendingIntent);
notificationManager.notify(singleNotificationId, notification.build());
notificationManager.notify(bundleNotificationId, summaryNotificationBuilder.build());
break;
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Bundle extras = intent.getExtras();
if (extras != null) {
int notification_id = extras.getInt("notification_id");
Toast.makeText(getApplicationContext(), "Notification with ID " + notification_id + " is cancelled", Toast.LENGTH_LONG).show();
notificationManager.cancel(notification_id);
}
}
}
btnSingleNotification在当前捆绑通知中添加一个通知。
如果当前的捆绑包通知不存在,它将首先创建一个。btnBundleNotification创建一个新的Bundle Notification,并通过增加ID来更新组密钥。
我们最初设置了一个等于" singleNotificationId"的" bundleNotificationId"。
每次创建新的包通知时,我们都会将
bundleNotificationId增加100。每次在包通知中创建单个通知时,我们都会在当前bundleNotificationId上将" singleNotificationId"增加1。
我们为捆绑通知和单一通知创建了单独的渠道。
通知点击会触发onNewIntent。
它从意图数据中获取通知ID,并取消相应的通知。
Android捆绑通知应用程序输出
让我们看看上面代码的输出。
请注意,在上面的输出中,单击任何通知只会取消最后添加的通知。
为什么?
由于PendingIntent将数据更新为最新数据,因此我们将每个PendingIntent的请求代码都设为0。
因此,它仅返回最新数据。
我们需要为每个通知设置不同的请求代码。
让我们将请求代码设置为" bundleNotificationId"(用于捆绑包通知)和" singleNotificationId"(用于单个通知)。
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnBundleNotification:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel groupChannel = new NotificationChannel("bundle_channel_id", "bundle_channel_name", NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(groupChannel);
}
bundleNotificationId += 100;
singleNotificationId = bundleNotificationId;
String bundle_notification_id = "bundle_notification_" + bundleNotificationId;
Intent resultIntent = new Intent(this, MainActivity.class);
resultIntent.putExtra("notification", "Summary Notification Clicked");
resultIntent.putExtra("notification_id", bundleNotificationId);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, bundleNotificationId, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
summaryNotificationBuilder = new NotificationCompat.Builder(this, "bundle_channel_id")
.setGroup(bundle_notification_id)
.setGroupSummary(true)
.setContentTitle("Bundled Notification. " + bundleNotificationId)
.setContentText("Content Text for bundle notification")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(resultPendingIntent);
notificationManager.notify(bundleNotificationId, summaryNotificationBuilder.build());
break;
case R.id.btnSingleNotification:
bundle_notification_id = "bundle_notification_" + bundleNotificationId;
resultIntent = new Intent(this, MainActivity.class);
resultIntent.putExtra("notification", "Summary Notification Clicked");
resultIntent.putExtra("notification_id", bundleNotificationId);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
resultPendingIntent = PendingIntent.getActivity(this, bundleNotificationId, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//We need to update the bundle notification every time a new notification comes up.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
if (notificationManager.getNotificationChannels().size() < 2) {
NotificationChannel groupChannel = new NotificationChannel("bundle_channel_id", "bundle_channel_name", NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(groupChannel);
NotificationChannel channel = new NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
}
summaryNotificationBuilder = new NotificationCompat.Builder(this, "bundle_channel_id")
.setGroup(bundle_notification_id)
.setGroupSummary(true)
.setContentTitle("Bundled Notification " + bundleNotificationId)
.setContentText("Content Text for group summary")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(resultPendingIntent);
if (singleNotificationId == bundleNotificationId)
singleNotificationId = bundleNotificationId + 1;
else
singleNotificationId++;
resultIntent = new Intent(this, MainActivity.class);
resultIntent.putExtra("notification", "Single notification clicked");
resultIntent.putExtra("notification_id", singleNotificationId);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
resultPendingIntent = PendingIntent.getActivity(this, singleNotificationId, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT); //singleNotificationId is set as the request code.
NotificationCompat.Builder notification = new NotificationCompat.Builder(this, "channel_id")
.setGroup(bundle_notification_id)
.setContentTitle("New Notification " + singleNotificationId)
.setContentText("Content for the notification")
.setSmallIcon(R.mipmap.ic_launcher)
.setGroupSummary(false)
.setContentIntent(resultPendingIntent);
notificationManager.notify(singleNotificationId, notification.build());
notificationManager.notify(bundleNotificationId, summaryNotificationBuilder.build());
break;
}
}

