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; } }