Android多行通知,如Gmail应用程序
我正在尝试创建一个多行通知,就像Gmail应用程序所做的那样,如下图所示(5个通知分组在一个通知下) 我尝试了各种各样的例子,但似乎只能创建单一的通知,如Android多行通知,如Gmail应用程序,android,android-notifications,Android,Android Notifications,我正在尝试创建一个多行通知,就像Gmail应用程序所做的那样,如下图所示(5个通知分组在一个通知下) 我尝试了各种各样的例子,但似乎只能创建单一的通知,如 public void createSingleNotification(String title, String messageText, String tickerttext) { int icon = R.drawable.notification_icon; // icon from resources
public void createSingleNotification(String title, String messageText, String tickerttext) {
int icon = R.drawable.notification_icon; // icon from resources
CharSequence tickerText = tickerttext; // ticker-text
long when = System.currentTimeMillis(); // notification time
Context context = getApplicationContext(); // application Context
CharSequence contentTitle = title; // expanded message title
CharSequence contentText = messageText; // expanded message text
Intent notificationIntent = new Intent(this, MainActivity.class);
Bundle xtra = new Bundle();
xtra.putString("title", title);
xtra.putString("message", messageText);
notificationIntent.putExtras(xtra);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_ONE_SHOT
+ PendingIntent.FLAG_UPDATE_CURRENT);
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notification.defaults |= Notification.DEFAULT_LIGHTS;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.FLAG_AUTO_CANCEL;
notification.flags = Notification.DEFAULT_LIGHTS
| Notification.FLAG_AUTO_CANCEL;
final int HELLO_ID = 0;
mNotificationManager.notify(HELLO_ID, notification);
}
我不知道如何创建可以添加行的通知组。您正在寻找“大视图样式”,如下所示:
相关文件:
bigContentView
完成的,您要使用Builder
来创建该通知)。要更新通知以添加更多数据,只需使用BigTextStyle中的更大字符串或InboxStyle中的更多行再次发布通知(使用相同的ID和标记)。NotificationCompat.Builder mBuilder=new NotificationCompat.Builder(此)
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Event tracker")
.setContentText("Events received")
NotificationCompat.InboxStyle inboxStyle =
new NotificationCompat.InboxStyle();
String[] events = {"line 1","line 2","line 3","line 4","line 5","line 6"};
// Sets a title for the Inbox in expanded layout
inboxStyle.setBigContentTitle("Event tracker details:");
...
// Moves events into the expanded layout
for (int i=0; i < events.length; i++) {
inboxStyle.addLine(events[i]);
}
// Moves the expanded layout object into the notification object.
mBuilder.setStyle(inboxStyle);
...
// Issue the notification here.
.setSmallIcon(R.drawable.notification_图标)
.setContentTitle(“事件跟踪器”)
.setContentText(“收到的事件”)
NotificationCompat.InboxStyle InboxStyle=
新的NotificationCompat.InboxStyle();
字符串[]事件={“第1行”、“第2行”、“第3行”、“第4行”、“第5行”、“第6行”};
//在展开布局中设置收件箱的标题
inboxStyle.setBigContentTitle(“事件跟踪器详细信息:”);
...
//将事件移动到展开的布局中
for(int i=0;i
我知道很久以前就有人问过这个问题,可能很多像我这样的用户也在这里搜索,但我会以这种方式给出完整的通知代码。想象一下这样一个场景:您有一个聊天应用程序,并且希望获得按每个用户分组的通知!由每个用户发出通知。因此,最好的方法是通过唯一的用户id进行通知,因此您必须编写一段代码进行通知,因为如果您的目标是API级别23以下的用户,那么您无法猜测此时会出现多少通知,因为API级别23以下的用户几乎看不到这些通知。那么,当您希望对每个收到通知的用户进行分组并保持逻辑性时,您应该怎么做呢?我做这件事的最好方法是使用带有一些轻微逻辑的共享首选项,让我在代码中添加注释
(这样,您的目标是较低的API,因此KitKat也将处理此逻辑)
模拟通知作为测试的类
/**
* Simple id just for test
*/
private int NOTIFICATION_ID = 1;
private static int value = 0;
Notification.InboxStyle inboxStyle = new Notification.InboxStyle();
private NotificationCompat.Builder mCopat;
private Bitmap bitmap;
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
mCopat = new NotificationCompat.Builder(getApplicationContext());
/**
* Here we create shared preferences.Probably you will create some helper class to access shared preferences from everywhere
*/
sharedPreferences = getSharedPreferences("shared", MODE_PRIVATE);
editor = sharedPreferences.edit();
/**
* I clear this for test purpose.
*/
editor.clear();
editor.commit();
}
public void hey(View view) {
/**
* Add notification,let`s say add 4 notifications with same id which will be grouped as single and after it add the rest which will be grouped as new notification.
*/
int clickedTime = value++;
if (clickedTime == 4) {
NOTIFICATION_ID++;
}
/**
* Here is the important part!We must check whether notification id inserted inside the shared preferences or no.If inserted IT MEANS THAT WE HAVE an notification
* to where we should add this one (add the new one to the existing group in clear way)
*/
if (sharedPreferences.getString(String.valueOf(NOTIFICATION_ID), null) != null) {
Log.d("fsafsafasfa", "hey: " + "not null adding current");
/**
* TAKE A NOTICE YOU MUST NOT CREATE A NEW INSTANCE OF INBOXSTYLE, OTHERWISE, IT WON`T WORK. JUST ADD VALUES TO EXISTING ONE
*/
NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(this);
builder.setContentTitle("Lanes");
builder.setContentText("Notification from Lanes " + value);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setLargeIcon(bitmap);
builder.setAutoCancel(true);
/**
* By this line you actually add an value to the group,if the notification is collapsed the 'Notification from Lanes' text will be displayed and nothing more
* otherwise if it is expanded the actual values (let`s say we have 5 items added to notification group) will be displayed.
*/
inboxStyle.setBigContentTitle("Enter Content Text");
inboxStyle.addLine("hi events " + value);
/**
* This is important too.Send current notification id to the MyBroadcastReceiver which will delete the id from sharedPrefs as soon as the notification is dismissed
* BY USER ACTION! not manually from code.
*/
Intent intent = new Intent(this, MyBroadcastReceiver.class);
intent.putExtra("id", NOTIFICATION_ID);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
/**
* Simply set delete intent.
*/
builder.setDeleteIntent(pendingIntent);
builder.setStyle(inboxStyle);
nManager.notify("App Name", NOTIFICATION_ID, builder.build());
/**
* Add id to shared prefs as KEY so we can delete it later
*/
editor.putString(String.valueOf(NOTIFICATION_ID), "notification");
editor.commit();
} else {
/***
* Here is same logic EXCEPT that you do create an INBOXSTYLE instance so the values are added to actually separate notification which will just be created now!
* The rest logic is as same as above!
*/
/**
* Ok it gone to else,meaning we do no have any active notifications to add to,so just simply create new separate notification
* TAKE A NOTICE to be able to insert new values without old ones you must call new instance of InboxStyle so the old one will not take the place in new separate
* notification.
*/
Log.d("fsafsafasfa", "hey: " + " null adding new");
inboxStyle = new Notification.InboxStyle();
NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(this);
builder.setContentTitle("Lanes");
builder.setContentText("Notification from Lanes " + value);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setLargeIcon(bitmap);
builder.setAutoCancel(true);
inboxStyle.setBigContentTitle("Enter Content Text");
inboxStyle.addLine("hi events " + value);
Intent intent = new Intent(this, MyBroadcastReceiver.class);
intent.putExtra("id", NOTIFICATION_ID);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
builder.setDeleteIntent(pendingIntent);
builder.setStyle(inboxStyle);
nManager.notify("App Name", NOTIFICATION_ID, builder.build());
editor.putString(String.valueOf(NOTIFICATION_ID), "notification");
editor.commit();
}
}
}
用于删除意图的广播接收器。别忘了在你的舱单上添加一个接收人
public class MyBroadcastReceiver extends BroadcastReceiver {
/**
* Receive swipe/dismiss or delete action from user.This will not be triggered if you manually cancel the notification.
* @param context
* @param intent
*/
@Override
public void onReceive(Context context, Intent intent) {
/**
* As soon as received,remove it from shared preferences,meaning the notification no longer available on the tray for user so you do not need to worry.
*/
SharedPreferences sharedPreferences = context.getSharedPreferences("shared", context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(String.valueOf(intent.getExtras().getInt("id")));
editor.commit();
}
}
这里我得到了解决方案:确保创建BrodCast接收器,以便在通知解除时清除阵列堆栈
static ArrayList<String> notifications = new ArrayList<>();
private static void sendNotification(String messageBody,Context cxt) {
//onDismiss Intent
Intent intent = new Intent(cxt, MyBroadcastReceiver.class);
PendingIntent broadcastIntent = PendingIntent.getBroadcast(cxt.getApplicationContext(), 0, intent, 0);
//OnClick Listener
startWFApplication().addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(cxt, 0, startWFApplication(),
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(cxt)
.setSmallIcon(R.drawable.fevicon)
.setContentTitle("Title")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationCompat.InboxStyle inboxStyle =
new NotificationCompat.InboxStyle();
// Sets a title for the Inbox in expanded layout
inboxStyle.setBigContentTitle("Title - Notification");
inboxStyle.setSummaryText("You have "+notifications.size()+" Notifications.");
// Moves events into the expanded layout
notifications.add(messageBody);
for (int i=0; i < notifications.size(); i++) {
inboxStyle.addLine(notifications.get(i));
}
// Moves the expanded layout object into the notification object.
notificationBuilder.setStyle(inboxStyle);
NotificationManager notificationManager =
(NotificationManager) cxt.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
notificationBuilder.setDeleteIntent(broadcastIntent);
}
public static Intent startWFApplication(){
Intent launchIntent = new Intent();
launchIntent.setComponent(new ComponentName("your.package", "Yyour.package.servicename"));
return launchIntent;
}
在舱单上写下:
<receiver
android:name="your.package.MyBroadcastReceiver"
android:exported="false" >
</receiver>
谢谢,很高兴知道它被称为大视图通知。我找到的所有教程都会同时创建一个包含多行的通知。我想要一种用一行创建通知的方法,然后在需要时向其添加更多行。链接以感谢我使用BigTextStyle创建了一个BigView通知。我正在设法更新通知中显示的消息。我知道我可以使用相同的ID更新通知。但是,是否有办法获取通知中当前显示的消息,并将其保存为字符串,我可以在更新通知之前根据需要编辑该字符串。否,您必须自己跟踪该数据。一旦发布了通知对象,您就无法真正获取其内容。谢谢,我存储数据,然后在需要时使用更新的数据创建通知。这可以通过自定义UI实现,因此字符串数组中的事件从何处来?很好的示例!谢谢,很好的例子!谢谢。但我认为当我从recentI中清除应用程序时,通知列表将变为空。当我使用FCM concole发送消息时,上面应用的代码不会像gmail应用程序那样显示通知。它正在工作,谢谢:-),但只在应用程序位于前台时工作,而在应用程序位于后台时不工作。@FirdoshAnsari我认为您需要确定广播接收器是否正常工作。尝试在每次点击服务时放置一些日志,看看是否生成了日志。
<receiver
android:name="your.package.MyBroadcastReceiver"
android:exported="false" >
</receiver>