Hi i want to show all the notification in a single view .. and want to update number of notification in status bar ... its updating all info but showing number always 1.. please tell me how to solve it...
#Override
public void onReceive(Context context, Intent intent)
{
//Random randGen = new Random();
//int notify_id = randGen.nextInt();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Activity.NOTIFICATION_SERVICE);
String title = intent.getStringExtra(TableUtils.KEY_TITLE);
String occasion = intent.getStringExtra(TableUtils.KEY_OCCASION);
Notification notification =
new Notification(R.drawable.icon, "Love Cardz" ,
System.currentTimeMillis());
// notification.vibrate = new long[]{100,250,300,330,390,420,500};
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.number+=1;
Intent intent1 = new Intent(context, ThemesBrowserActivity.class);
PendingIntent activity =
PendingIntent.getActivity(context, 1 , intent1,
PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(context, occasion, title, activity);
notificationManager.notify(1, notification);
}
You have to keep track of the count. You could extend the Application class:
public class AppName extends Application {
private static int pendingNotificationsCount = 0;
#Override
public void onCreate() {
super.onCreate();
}
public static int getPendingNotificationsCount() {
return pendingNotificationsCount;
}
public static void setPendingNotificationsCount(int pendingNotifications) {
pendingNotificationsCount = pendingNotifications;
}
}
And you should modify the onReceive:
#Override
public void onReceive(Context context, Intent intent) {
...
int pendingNotificationsCount = AppName.getPendingNotificationsCount() + 1;
AppName.setPendingNotificationsCount(pendingNotificationsCount);
notification.number = pendingNotificationsCount;
...
}
And you could reset the count when the user open the notification:
AppName.setPendingNotificationsCount(0);
This is my code, and it works. I have only tested on old Android versions thou. I suspect on newer versions the "number" badge has been made invisible, but I haven't had the chance to test it.
void notifyMsgReceived(String senderName, int count) {
int titleResId;
String expandedText, sender;
// Get the sender for the ticker text
// i.e. "Message from <sender name>"
if (senderName != null && TextUtils.isGraphic(senderName)) {
sender = senderName;
}
else {
// Use "unknown" if the sender is unidentifiable.
sender = getString(R.string.unknown);
}
// Display the first line of the notification:
// 1 new message: call name
// more than 1 new message: <number of messages> + " new messages"
if (count == 1) {
titleResId = R.string.notif_oneMsgReceivedTitle;
expandedText = sender;
}
else {
titleResId = R.string.notif_missedCallsTitle;
expandedText = getString(R.string.notif_messagesReceivedTitle, count);
}
// Create the target intent
final Intent intent = new Intent(this, TargetActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
final PendingIntent pendingIntent =
PendingIntent.getActivity(this, REQUEST_CODE_MSG_RECEIVED, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Build the notification
Notification notif = new Notification(
R.drawable.ic_notif_msg_received, // icon
getString(R.string.notif_msgReceivedTicker, sender), // tickerText
System.currentTimeMillis()); // when
notif.setLatestEventInfo(this, getText(titleResId), expandedText, pendingIntent);
notif.number = count;
notif.flags = Notification.FLAG_AUTO_CANCEL;
// Show the notification
mNotificationMgr.notify(NOTIF_MSG_RECEIVED, notif);
}
It is also easy to update the notification later on: you just have to call the method again with new values. The number will be displayed in the notification icon badge if and only if it was greater than zero when the notification was created.
Similarily, the number badge won't be hidden (the number will, thou) if you set the number to a number that is less than 1. Maybe clearing the notification before re-showing it could fix it.
You have to keep track of the count. The increment that you're trying to perform on notif.number isn't working, since that state is unavailable (i.e. notif.number is always 0, then you increment it to 1). Keep track of number somewhere in your app(shared preferences, perhaps), and increment and store it there, then when you build the notification, set
notif.number = myStoredValueForWhatShouldShowInNumber;
Give that a try.
Related
I was wondering how to implement the onClickListener for an android notification. I am trying to implement sendText() in the notification instead of sending the user to the main activity:
public class AlertReceiver extends BroadcastReceiver {
Context mContext;
String number;
String messageList;
String name;
#Override
public void onReceive(Context context, Intent intent) {
mContext = context;
name = intent.getStringExtra("name");
messageList = intent.getStringExtra("messageList");
number = intent.getStringExtra("number");
createNotification(context, "times up " + name, "5 seconds passed!", "alert");
}
public void createNotification(Context context, String message, String messageText, String messageAlert){
PendingIntent notificIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context).setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(message)
.setTicker(messageText)
.setContentText(messageAlert);
mBuilder.setContentIntent(notificIntent);
mBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
public void sendText(){
//Turn string of all messages into an ArrayList in order to get one specific message at random
ArrayList<String> messagesArrayList = null;
try {
messagesArrayList = Utility.getArrayListFromJSONString(messageList);
} catch (JSONException e) {
e.printStackTrace();
}
Random rand = new Random();
//todo the following may cause a bug if there are no messages in list
int n = rand.nextInt(messagesArrayList.size());
String message = messagesArrayList.get(n);
try {
//send text message
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(number, null, message, null, null);
Toast.makeText(mContext, "Message Sent",
Toast.LENGTH_SHORT).show();
} catch (Exception ex) {
//If text message wasn't sent attempt to send text another way (through the user's text messaging app)
// Most likely due to text message permissions not being accepted by user
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("smsto:" + number)); // This ensures only SMS apps respond
intent.putExtra("sms_body", message);
if (intent.resolveActivity(mContext.getPackageManager()) != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
}
}
}
Note the following information is not really necessary. It is mainly because stackoverflow thinks my code to text ratio is too low but also may help clarify a little bit:
The sendText() is basically a method that tries to send a pre-made text message without opening up a new activity. However, if permissions aren't there then it will open up the new activity using an intent. So in an effort to minimize amount of screens coming up and make it easiest on the user I tried to do it using the sendtext method.
Instead of creating a pendingIntent to start an Activity, you can create a pendingIntent to fire a Broadcast receiver as shown below
PendingIntent intent = PendingIntent.getBroadcast(context, 0, new Intent(context, SendTextReceiver.class), 0);
so when you click notification, it will invoke your BroadCast receiver SendTextReceiver and do your sendText logic inside it, so by this way you dont have to always start an activity and your logic will be done without an activity
If you don't want to send the user to an Activity, then you can fire a service: PendingIntent.getService(...) when user clicks on the notification and do the job to send the text there.
Try this:
public class AlarmReceiver extends BroadcastReceiver {
private static final int MY_NOTIFICATION_ID=1;
NotificationManager notificationManager;
Notification myNotification;
#Override
public void onReceive(Context context, Intent intent) {
// here DoSomething is your service name that you want to start
Intent myIntent = new Intent(context, DoSomething.class);
PendingIntent pendingIntent = PendingIntent.getService(
context,
0,
myIntent,
0);
myNotification = new NotificationCompat.Builder(context)
.setContentTitle("Exercise of Notification!")
.setContentText("Do Something...")
.setTicker("Notification!")
.setWhen(System.currentTimeMillis())
.setContentIntent(pendingIntent)
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher)
.build();
notificationManager =
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(MY_NOTIFICATION_ID, myNotification);
}
}
I'm delivering a notification which has 2 action buttons namely "Accept" and "Reject".
I'm following this Github repo.
When user clicks "Accept", certain conditions are checked and the logic is performed accordingly.
UPDATE 2.0 - The problem is that upon clicking "Accept" button, operation is happening successfully but the notification isn't disappearing from the status bar because the id generating here: m = (new Random()).nextInt(10000); is different from here: actionIntent.putExtra("id", NotificationARBroadcastReceiver.m); every single time!
Here's the code for notification:
Intent notificationIntent = new Intent(getBaseContext(), NotificationARBroadcastReceiver.class);
notificationIntent.putExtra(NotificationARBroadcastReceiver.NOTIFICATION, getNotificationNewRequestService());
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), m, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 0, pendingIntent);
Here's getNotificationNewRequestService():
private Notification getNotificationNewRequestService() {
mBuilder =
new NotificationCompat.Builder(getBaseContext())
.setSmallIcon(R.mipmap.app_icon_1)
.setContentTitle("Title")
.setContentText("text...");
Intent resultIntent = new Intent(getBaseContext(), Profile.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
getBaseContext(),
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
// for action button
Intent actionIntent = new Intent(getBaseContext(), MyBroadcastSender.class);
actionIntent.putExtra("id", NotificationARBroadcastReceiver.m);
PendingIntent actionPendingIntent = PendingIntent
.getBroadcast(getBaseContext(),
0, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setAutoCancel(true);
mBuilder.setContentIntent(resultPendingIntent);
mBuilder.addAction(R.drawable.ic_accepted_request_black_24dp, "Accept", actionPendingIntent);
mBuilder.addAction(R.drawable.ic_close_black_24dp, "Reject", null);
return mBuilder.build();
}
Here's NotificationARBroadcastReceiver.java file:
public class NotificationARBroadcastReceiver extends BroadcastReceiver {
public static String NOTIFICATION = "notification";
public static NotificationManager mNotifyMgr;
public static int m;
#Override
public void onReceive(Context context, Intent intent) {
m = (new Random()).nextInt(10000);
Log.d("mMain", String.valueOf(m));
mNotifyMgr =
(NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
mNotifyMgr.notify(m, notification);
}
}
Here's MyBroadcastSender.java file:
public class MyBroadcastSender extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Broadcast Received by MyBroadcastSender.", Toast.LENGTH_SHORT).show();
int id = intent.getIntExtra("id", 1);
// send back to your class
Intent newIntent = new Intent();
newIntent.setAction(context.getString(R.string.broadcast_id));
newIntent.putExtra("id1", id);
context.sendBroadcast(newIntent);
context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
Toast.makeText(context, "Broadcast sent back.", Toast.LENGTH_SHORT).show();
}
}
and here's MyBroadcastReceiver.java file:
// BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
public MyBroadcastReceiver(){
super();
}
#Override public void onReceive(Context context, Intent intent) {
int id2 = intent.getIntExtra("id1", 1);
if (intent.getAction() != null && intent.getAction().equals(getString(R.string.broadcast_id))) {
NotificationARBroadcastReceiver.mNotifyMgr.cancel(id2);
Intent intent1 = new Intent(MyService.this, MainActivity.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent1);
Toast.makeText(context, "Broadcast received by MyBroadcastReceiver. Now, you can perform actions.",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Intent is null.", Toast.LENGTH_SHORT).show();
}
}
}
In getNotificationNewRequestService(), I'm putting notification id as an extra in "id", then in MyBroadcastSender.java, I'm getting this extra as int id = intent.getIntExtra("id", 1); and then putting again as newIntent.putExtra("id1", id); and then finally getting it in MyBroadcastReceiver.java as int id2 = intent.getIntExtra("id1", 1); and trying to remove the notification using it as NotificationARBroadcastReceiver.mNotifyMgr.cancel(id2);.
Sorry for this much code, I've to upload it all as they all are necessary.
What I want is to know how to deliver the same notification id from NotificationARBroadcastReceiver.java (which is a separate java file) to MyBroadcastReceiver(which is an inner class in MyService.java)?
Update 1.0- this is what happened when I printed out the values of m, mMain, id, id1:
D/m: 0
D/mMain: 9994
D/id: 0
D/id1: 0
Assuming getNotificationService() == getNotificationNewRequestService() Looks like the NotificationARBroadcastReceiver isn't called before the notfication is built and displayed.
You would do better to generate the notification id where you create the notification and just add it to the intent there as well you don't need to make.
So call getNotificationNewRequestService() from NotificationARBroadcastReceiver.recieve() and make sure the notification ids match up.
Edit:
move:
m = (new Random()).nextInt(10000);
before:
actionIntent.putExtra("id", NotificationARBroadcastReceiver.m); // this will be 'm'
Result:
int m = (new Random()).nextInt(10000);
Intent actionIntent = new Intent(getBaseContext(), MyBroadcastSender.class);
actionIntent.putExtra("id", m);
Log.d(getClass().getSimpleName(), "Notification Id is : " + m);
then, you can check what values are in id, id1 and id2. Don't forget to call .notify() with same Id you got from m.
You can, also, create getRandomNotificationId() and getLastGeneratedNotificationId() methods. Whenever you generate an Id, store it in public static integer variable, so that you can access it throughout the class.
Problem might be that you are accessing m from NotificationARBroadcastReceiver before initializing it. So, it will definitely be 0. And, you mentioned something about println error, are you using System.out.println()?
Before Edit:
As seen on your new edit, try closing notification before starting it:
m = (...);
// some code here
mNotifyMgr.cancel(m);
mNotifyMgr.notify(m, notification);
and see if your issue gets resolved.
i'm building a notification that is launched with a toggle button:
toggleLigar.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(toggleLigar.isChecked()){
NotificationUtil.cancelaAll(TelaCriaDesp.this);
CharSequence tickerText = "Despertador ativado!";
CharSequence title = "Você não vai perder seu ponto!";
CharSequence message = "O despertador " + despertador.getNomeDesp() + " está ativo!";
Intent intent = new Intent(TelaCriaDesp.this, TelaCriaDesp.class);
NotificationUtil.criaNotification(TelaCriaDesp.this, tickerText, title, message,
despertador.getDesp_id(), intent);
} else {
NotificationUtil.cancelaNotification(TelaCriaDesp.this, despertador.getDesp_id());
}
}
});
now i want to assign the toggle button in ON or OFF according to the notification state, if it's active (being displayed) it's ON, inactive OFF... I have tried this:
public static boolean testaNotification(int id, Context context){
Intent intent = new Intent(context, TelaCriaDesp.class);
//intent.setAction(Intent.);
PendingIntent teste = PendingIntent.getActivity(context, id, intent,
PendingIntent.FLAG_NO_CREATE);
return teste != null;
}
but it's not working, it always returns NULL...
here's my notification creation:
public class NotificationUtil {
#SuppressWarnings("deprecation")
public static void criaNotification(Context context, CharSequence tickerText, CharSequence title,
CharSequence message, int id, Intent intent){
PendingIntent aoSelecionar = PendingIntent.getActivity(context, 0, intent, 0);
Notification notification = null;
int apiLevel = Build.VERSION.SDK_INT;
if(apiLevel >= 11){
Builder montaNotification = new Notification.Builder(context)
.setContentTitle(tickerText)
.setContentText(message)
.setSmallIcon(R.drawable.icon)
.setContentIntent(aoSelecionar);
//montaNotification.setAutoCancel(true);
montaNotification.setOngoing(true);
if(apiLevel >= 17){
notification = montaNotification.build();
} else {
notification = montaNotification.getNotification();
}
} else {
notification = new Notification(R.drawable.icon, tickerText, System.currentTimeMillis());
notification.setLatestEventInfo(context, title, message, aoSelecionar);
//notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
}
NotificationManager manager = (NotificationManager)
context.getSystemService(Activity.NOTIFICATION_SERVICE);
manager.notify(id, notification);
}
From API 23 and up you can use NotificationManager method getActiveNotifications(). This returns a list of active notifications launched by your app in a form of an array.
So to check if a particular notification is active, you can just iterate over the elements of this array and compare notification ids/tags.
Read more on this method here:
NotificationManager.getActiveNotifications()
You cannot. You must track it manually, if You need.
In fact Notification is meant only to notify a user about some event. If you need to check if the notification is present - then, in fact, You need to check if the event (which the notification is about) is still valid.
In the case You described, You may persist information in the local database when creating a notification.
Add a contentIntent to the notification to be able to mark the database item appropriately when a user dismisses notification by clicking it.
Then when You need to test if the notification exists, just look for a valid row in the local database.
If You only have one simple notification of given type, You can just persist a boolean flag in a preference file without need for local database to use.
My problem is when I send more than one notification (from the server to the phone via c2dm), I receive all of them with all their information.
I see that I have two icons with notifications. When I click one of them is with my information (I clicked on it, I getActivity), the other is like untrue... didn't start the activity.
I read something about PendingIntent, that start activity once, but I do not know what to do.
I need to get every notification, not only the last (it's not like update).
private void incomingTestp(JSONObject json, Context context) throws JSONException {
Intent intent = new Intent(context, TestpViewActivity.class);
Testp testp = Testp.fromJSON(json);
TestpServiceUtil.save(testp);
intent.putExtra("testpId", testp.getTestpId());
sendNotification("New Testp", "update", intent, testp.getTestpId(), context);
}
private void incomingTestr(JSONObject json, Context context) throws JSONException {
Intent intent = new Intent(context, TestrViewActivity.class);
Testr Testr = Testr.fromJSON(json);
TestrServiceUtil.save(testr);
intent.putExtra("testrId", testr.getTestrId());
sendNotification("New Testr", "update", intent, report.getTestrId(), context);
}
private void sendNotification(String title, String description, Intent intent, long id, Context context) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.icon, title, System.currentTimeMillis());
intent.putExtra("force", true);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context.getApplicationContext(), title, description, PendingIntent.getActivity(context, requestCode++, intent, Intent.FLAG_ACTIVITY_NEW_TASK));
notification.vibrate = new long[] { 0, 200, 100 };
//notification.defaults |= Notification.DEFAULT_SOUND;
notificationManager.notify("Test", (int) id, notification);
}
I give you a little more information to know how i call this method.
try: PendingIntent.getActivity(context, requestCode++, intent, 0);
from my service I send (with "ongoing" ID = 0) ongoing notification and it seems that there is no way of clearing it from code. if I send other notifications to the same ID (0), icon and intents
will update :/
I dont know if this is a bug in API 7 but it just dont make sens to me.
when I sent notification with Notification.FLAG_ONLY_ALERT_ONCE with different ID(ex. 1) then it is classified as simple notification and I could easily clear it from expanded menu or from code. BUT just by sending same notification to previous ID (0) it is classified as ongoing and I cannot cancel it anyhow!
I also tried to save reference to "ongoing" notification and then re-notify it with other PendingIntent and/or flags but it has no effect!
my current code of the service
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d(TAG, "start notification");
startStatusBarNotification();
//do other stuff
// We want this service to continue running until it is explicitly stopped, so return sticky.
return START_STICKY;
}
private void startStatusBarNotification()
{
Log.d(TAG, "startStatusBarNotification.");
final int icon = R.drawable.stbar_icon_fail;
final long when = System.currentTimeMillis();
final Notification notification = new Notification(icon, getString(R.string.notify_title), when);
final Intent notificationIntent = new Intent(this, MyActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
notification.setLatestEventInfo(this, getString(R.string.notify_title), expandText, contentIntent);
notification.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE;//| Notification.FLAG_NO_CLEAR
Log.d(TAG, "notify send.");
final NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(SERVICE_ONGOING_NOTIFICATION_ID, notification);//ID = 0
}
#Override
public void onDestroy()
{
Log.d(TAG, "clear status bar notification.");
cancelNotification();
super.onDestroy();
}
private void cancelNotification()
{
final int icon = R.drawable.stbar_icon_exit;
final long when = System.currentTimeMillis();
final Notification notification = new Notification(icon, getString(R.string.notify_title), when);
final PendingIntent contentIntent = PendingIntent.getActivity(this, 0, null, PendingIntent.FLAG_CANCEL_CURRENT);
notification.setLatestEventInfo(this, getString(R.string.notify_stopping_title), getString(R.string.notify_stopping_text), contentIntent);
notification.flags = Notification.FLAG_AUTO_CANCEL;
final NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(SERVICE_ONGOING_NOTIFICATION_ID); //NOTHING HAPPENS
mNotificationManager.notify(SERVICE_ONGOING_NOTIFICATION_ID, notification); //ID = 0 but if this was changed to 1 cancel notification can be cleared :/
}
I can see "exit" icon so onDestroy and cancelNotification are called, i have no idea what im doing wrong
It does not appear that you can successfully cancel ongoing notifications with ID 0: you will probably have to use a non-zero notification id.
The core notification manager service code is here, which doesn't appear to have a specific restriction on the choice of notification ID but everyone else who uses ONGOING notifications (for example, the Phone application) uses non-zero IDs.