Android通知
Andorid通知
需要使用 NotificationCompat.Builder 对象设置通知内容和渠道。
- 小图标,通过 setSmallIcon() 设置。这是所必需的唯一用户可见内容。
- 标题,通过 setContentTitle() 设置。
- 正文文本,通过 setContentText() 设置。
- 通知优先级,通过 setPriority() 设置。优先级确定通知在 Android 7.1 和更低版本上的干扰程度。(对于 Android 8.0 和更高版本,必须设置渠道重要性,如下一节中所示。)
请注意,NotificationCompat.Builder 构造函数要求您提供渠道 ID。这是兼容 Android 8.0(API 级别 26)及更高版本所必需的,但会被较旧版本忽略。
相应通知的Activity一般有两种
- 专用于响应通知的 Activity。用户在正常使用应用时不会无缘无故想导航到这个 Activity,因此该 Activity 会启动一个新任务,而不是添加到应用的现有任务和返回堆栈。
- 应用的常规应用流程中存在的 Activity。在这种情况下,启动 Activity 时应创建返回堆栈,以便保留用户对返回和向上按钮的预期。
以下示例显示了如何创建包含下列内容的通知:
public void createAndUseNotification(Context context) {
Intent intent = new Intent(context, MainActivity.class);
/* intent 中可以存放一些参数 使得用户从通知进入activity的时候 可以进行一些 初始化 */
intent.putExtra("channel", "notification");
TaskStackBuilder builder1 = TaskStackBuilder.create(context);
builder1.addNextIntent(intent);
PendingIntent pendingIntent = builder1.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID);
builder.setSmallIcon(R.drawable.ic_launcher_background) // 通知的小图标 必填
.setContentText("亲,到了填写消费金额的时间了")
.setPriority(NotificationCompat.PRIORITY_DEFAULT) //通知的优先级
.addAction(R.drawable.ic_launcher_background,"确定",pendingIntent)// 设置按钮 最多有三个按钮
.addAction(R.drawable.ic_launcher_background,"取消",pendingIntent)//设置按钮
.setContentIntent(pendingIntent) //设置点按操作,pendingIntent为点击后打开Activity操作
.setAutoCancel(true); //点击后自动消失
Notification notification = builder.build();
NotificationManagerCompat managerCompat = NotificationManagerCompat.from(context);
/*
notify用于显示通知 第一个参数 id 更新或者移除通知 要用到它
managerCompat.cancel(int id)移除通知
managerCompat.notify(id,notification)可以用来移除通知,也可以用来过更新通知,只需传入相同的id,便会进行替换。
*/
managerCompat.notify(1, notification);
}
从 Android 8.1(API 级别 27)开始,应用每秒最多只能发出一次通知提示音。如果应用在一秒内发出了多条通知,这些通知都会按预期显示,但是每秒中只有第一条通知发出提示音。
创建渠道并设置重要性
必须先通过向 createNotificationChannel() 传递 NotificationChannel 的实例在系统中注册应用的通知渠道,然后才能在 Android 8.0 及更高版本上提供通知。由于您必须先创建通知渠道,然后才能在 Android 8.0 及更高版本上发布任何通知,因此应在应用启动时立即执行这段代码。反复调用这段代码是安全的,因为创建现有通知渠道不会执行任何操作。请注意,NotificationChannel 构造函数需要一个 importance,它会使用 NotificationManager 类中的一个常量。此参数确定出现任何属于此渠道的通知时如何打断用户,但您还必须使用 setPriority() 设置优先级,才能支持 Android 7.1 和更低版本。
创建渠道示例
public void createNotificationChannel(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "channel_name";
String description = "channel_description";
int importance = NotificationManager.IMPORTANCE_HIGH;
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 = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
添加操作按钮
一个通知最多可以提供三个操作按钮,让用户能够快速响应,例如暂停提醒,甚至回复短信。但这些操作按钮不应该重复用户在点按通知时执行的操作。
如需添加操作按钮,请调用NotificationCompat.Builder的 addAction()方法。这就像在设置通知的默认点按操作,不同的是不会启动 Activity,而是可以完成各种其他任务,例如启动在后台执行作业的 BroadcastReceiver,这样该操作就不会干扰已经打开的应用。
在 Android 10(API 级别 29)和更高版本中,如果应用不提供自己的通知操作按钮,则平台会自动生成通知操作按钮。如果您不希望应用通知显示任何建议的回复或操作,可以使用 setAllowGeneratedReplies() 和 setAllowSystemGeneratedContextualActions() 选择停用系统生成的回复和操作。
直接添加回复操作
- 创建一个可添加到通知操作的 RemoteInput.Builder 实例。此类的构造函数接受系统用作文本输入键的字符串。之后,手持式设备应用使用该键检索输入的文本。
- 为回复操作创建 PendingIntent。
- 使用 addRemoteInput() 将 RemoteInput 对象附加到操作上
- 对通知应用操作并发出通知。
请调用 RemoteInput.getResultsFromIntent() 并传入 BroadcastReceiver 收到的 Intent:
处理完文本后,必须使用相同的 ID 和标记(如果使用)调用 NotificationManagerCompat.notify() 来更新通知。若要隐藏直接回复界面并向用户确认他们的回复已收到并得到正确处理,则必须完成该操作。
在处理这个新通知时,请使用传递给接收者的 onReceive() 方法的上下文。
您还应通过调用 setRemoteInputHistory() 将回复附加到通知底部。但如果要构建即时通讯应用,应创建消息式通知,并在会话中附加新消息。
RemoteInput.Builder remoteInputBuilder = new RemoteInput.Builder("res");
RemoteInput build = remoteInputBuilder.build();
Intent intent1 = new Intent();
intent1.setAction("aa");
PendingIntent broadcast = PendingIntent.getBroadcast(this, 11, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action reply = new NotificationCompat.Action.Builder(R.drawable.ic_launcher_foreground, "回复", broadcast).addRemoteInput(build).build();
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle resultsFromIntent = RemoteInput.getResultsFromIntent(intent);
if (resultsFromIntent != null) {
Log.d(TAG, "onReceive: " + resultsFromIntent.getString("res"));
Notification notificationCompat = new NotificationCompat.Builder(MainActivity.this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentText("回复成功")
.setAutoCancel(true)
.build();
notificationManager.notify(1,notificationCompat);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
notificationManager.cancel(1);
}
}
}