Im coding an android app for about 4 months now and im currently getting an error on system notifications.
The problem is that im adding proximity alerts from varius interest points, when it aproaches a specific point, it sends a system notification. But now, when im near of more than one point, it sends the correct amount of notifications but they are all the same, woth same title and text, and im passing different information on the intent.
My code is:
MainActivity:
private void addProximityAlert(double latitude, double longitude, String type, int id, String object) {
Intent intent = new Intent(PROX_ALERT_INTENT);
intent.putExtra("type", type);
intent.putExtra("id", id);
intent.putExtra("object", object);
PendingIntent proximityIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
locationManager.addProximityAlert(
latitude, // the latitude of the central point of the alert region
longitude, // the longitude of the central point of the alert region
POINT_RADIUS, // the radius of the central point of the alert region, in meters
PROX_ALERT_EXPIRATION, // time for this proximity alert, in milliseconds, or -1 to indicate no expiration
proximityIntent // will be used to generate an Intent to fire when entry to or exit from the alert region is detected
);
IntentFilter filter = new IntentFilter(PROX_ALERT_INTENT);
registerReceiver(new ProximityReceiver(), filter);
}
Proximity Receiver:
public class ProximityReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String key = LocationManager.KEY_PROXIMITY_ENTERING;
Boolean entering = intent.getBooleanExtra(key, false);
int id = intent.getIntExtra("id", 0);
String type = intent.getStringExtra("type");
String name = intent.getStringExtra("object");
Log.d("NOTIFICATION", "NOME: " + name);
Log.d("NOTIFICATION", "ID: " + id);
Log.d("NOTIFICATION", "TYPE:" + type);
if (entering) {
Log.d(getClass().getSimpleName(), "entering");
}else {
Log.d(getClass().getSimpleName(), "exiting");
}
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(context, InterestPoint_Description.class);
notificationIntent.putExtra("id", id);
notificationIntent.putExtra("type", type);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = createNotification();
notification.setLatestEventInfo(context, "LisbonRoutes", "You are near " + name + ", touch here to check it out!", pendingIntent);
notificationManager.notify(Config.NOTIFICATION_ID, notification);
Config.NOTIFICATION_ID++;
}
private Notification createNotification() {
Notification notification = new Notification();
notification.icon = R.drawable.icon;
notification.when = System.currentTimeMillis();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.defaults |= Notification.DEFAULT_LIGHTS;
notification.ledARGB = Color.WHITE;
notification.ledOnMS = 1500;
notification.ledOffMS = 1500;
return notification;
}
}
I hope i've explained it well :S
Thanks in advance
Your pending intents are overwriting one another because extras do not make them unique.
See http://developer.android.com/reference/android/app/PendingIntent.html
it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen.
Best way to fix this is to set the request code, probably to id
PendingIntent proximityIntent = PendingIntent.getBroadcast(context, id, intent, 0);
Related
I need to Rewrite all the deprecated methods and class.
private void showNotification(Peer peer, int id) {
CharSequence text = getString(id) + " " + peer.getName();
Notification notification = new Notification(R.drawable.notification, text, System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Intent intent = new Intent(this, IPsecToolsActivity.class); //intent.setAction(ACTION_NOTIFICATION);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);
notification.setLatestEventInfo(this, getText(R.string.native_service_label), text, contentIntent); //setLatestEventInfo method has been deprecated
// Send the notification.
mNM.notify(peer.getName(), R.string.notify_peer_up, notification);
}
Note that the Notification is deprecated, too old.
Cannot use setLatestEventInfo method.
I need help rewrite it in alternative way.
The way I rewrite this is as following: Please let me know if I was right or not.
private void showNotification(Peer peer, int id) {
CharSequence text = getString(id) + " " + peer.getName();
Context context = this;
Notification notification = new Notification.Builder(context)
.setContentText(text)
.setSmallIcon(R.drawable.notification)
.setWhen(System.currentTimeMillis())
.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Intent intent = new Intent(this, IPsecToolsActivity.class);
//intent.setAction(ACTION_NOTIFICATION);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
intent, 0);
// Send the notification.
mNM.notify(peer.getName(), R.string.notify_peer_up, notification);
}
I have a repeating notification in a broadcast receiver. I will like to replace the content text dynamically. The notification will show the user a different message the next time the notification is shown. I want to know if its possible. If yes, how ?
below is the class of my broadcast receiver
public class TimeAlarm extends BroadcastReceiver {
NotificationManager nm;
long pattern[] = {500, 500};
private Uri notifsound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
private NotificationCompat.BigTextStyle contentStyle;
#Override
public void onReceive(Context context, Intent intent) {
String msg = "Drivers who sit higher feel as if they're driving slower. " +
"Thus, SUV drivers, who are already piloting the vehicles most prone to " +
"roll, drive faster because they feel like they're creeping along. " +
"So lower your seat to get the sensation of more speed.";
contentStyle = new android.support.v4.app.NotificationCompat.BigTextStyle();
contentStyle.bigText(msg);
contentStyle.setBigContentTitle("Lower Your Seat");
contentStyle.setSummaryText("AutoKit");
NotificationCompat.Builder builder;
builder = (NotificationCompat.Builder) new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("AutoKit")
.setContentText("Tip of the Day")
.setTicker("Daily Tip")
.setStyle(contentStyle)
.setSound(notifsound)
.setAutoCancel(true)
.setVibrate(pattern);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(1, builder.build());
}
}
here is the method is called in my mainactivity and ties the broadcast receiver to an alarm manager
public void setRepeatingAlarm(){ //user receives notifications every 24 hours at 7am
am = (AlarmManager)this.getSystemService(this.ALARM_SERVICE);
Intent intent = new Intent(this, TimeAlarm.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 07);
calendar.set(Calendar.MINUTE, 00);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24, pi);
}
Modify a Notification
To set up a notification so it can be updated, issue it with a notification ID by calling NotificationManager.notify(ID, notification). To update this notification once you've issued it, update or create a NotificationCompat.Builder object, build a Notification object from it, and issue the Notification with the same ID you used previously.
The following snippet demonstrates a notification that is updated to reflect the number of events that have occurred. It stacks the notification, showing a summary:
mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = 1;
mNotifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
numMessages = 0;
// Start of a loop that processes data and then notifies the user
...
mNotifyBuilder.setContentText(currentText)
.setNumber(++numMessages);
// Because the ID remains unchanged, the existing notification is
// updated.
mNotificationManager.notify(
notifyID,
mNotifyBuilder.build());
...
Taken from developer site. please refer, http://developer.android.com/training/notify-user/managing.html
here the changes I made in the broadcast receiver class.
public class TimeAlarm extends BroadcastReceiver {
NotificationManager nm;
long pattern[] = {500, 500};
private Uri notifsound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
private NotificationCompat.BigTextStyle contentStyle;
private List contentTexts, contentTitles;
#Override
public void onReceive(Context context, Intent intent) {
contentTexts = new ArrayList<String>();
contentTitles = new ArrayList<String>();
prepareContentTitles();
prepareContentTexts();
SharedPreferences prefs = context.getSharedPreferences("notification_count", context.MODE_PRIVATE);
int count = prefs.getInt("notification_count", 0);
contentStyle = new android.support.v4.app.NotificationCompat.BigTextStyle();
contentStyle.bigText((CharSequence) contentTexts.get(count));
contentStyle.setBigContentTitle((CharSequence) contentTitles.get(count));
contentStyle.setSummaryText("AutoKit");
NotificationCompat.Builder builder;
builder = (NotificationCompat.Builder) new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("AutoKit")
.setContentText("Tip of the Day")
.setTicker("Daily Tip")
.setStyle(contentStyle)
.setSound(notifsound)
.setAutoCancel(true)
.setVibrate(pattern);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(1, builder.build());
if (count == contentTexts.size() - 1) {
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("notification_count", 0);
editor.commit();
}
else {
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("notification_count", count + 1);
editor.commit();
}
}
public void prepareContentTexts() {
contentTexts.add("Drivers who sit higher feel as if they're driving slower. " +
"Thus, SUV drivers, who are already piloting the vehicles most prone to " +
"roll, drive faster because they feel like they're creeping along. " +
"So lower your seat to get the sensation of more speed.");
contentTexts.add("Manufacturers recommend replacing your blades every three months. " +
"Keep a spare set in your trunk. A product such as Rain Clear can also help " +
"minimize the work of your wipers; spray it onto the glass every few weeks. " +
"In some light rains, it makes the wipers almost unnecessary");
contentTexts.add("At the BMW Performance Driving School, instructor Jim Clark says " +
"these four words over and over: \"Slow in, fast out.\" When taking a corner," +
" you need to scrub as much of that speed as you can while the car is braking" +
" in a straight line, then you can accelerate out of the curve. The converse " +
"is \"Fast in, maybe no out.\"");
}
public void prepareContentTitles() {
contentTitles.add("Lower Your Seat");
contentTitles.add("Rainproof Your Windshield");
contentTitles.add("Maneuver Tight Corners ");
}
}
The notification displays different content texts every time it is fired
Months ago I wrote a code that my Notification worked as bellow :
NotificationManager NotiManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
String MyText = "NotificationText";
Notification mNotification = new Notification(R.mipmap.icon, MyText, System.currentTimeMillis() );
mNotification.flags |= Notification.FLAG_AUTO_CANCEL;
mNotification.defaults |= Notification.DEFAULT_SOUND;
mNotification.defaults |= Notification.DEFAULT_VIBRATE;
String MyNotificationTitle = "AnyText";
String MyNotificationText = "HERE MORE TEXT";
Intent intent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://www.google.com"));
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent StartIntent = PendingIntent.getActivity(context.getApplicationContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
mNotification.setLatestEventInfo(context.getApplicationContext(), MyNotificationTitle, MyNotificationText, StartIntent);
NotiManager.notify(NOTIFY_ME_ID_LOGIN, mNotification);
But now, that I want to make an update it doesn't even let compile the APP because this line :
mNotification.setLatestEventInfo(context.getApplicationContext(), MyNotificationTitle, MyNotificationText, StartIntent);
Is there any way to change the setLatestEventInfo or other way to create a Notification?
Is there any way to change the setLatestEventInfo
You are welcome to lower your compileSdkVersion, though that will introduce its own set of issues.
or other way to create a Notification?
As Blackbelt notes in a comment, NotificationCompat.Builder has been around for ~4 years and is the recommended way to create Notification objects today:
private void raiseNotification(String mimeType, File output,
Exception e) {
NotificationCompat.Builder b=new NotificationCompat.Builder(this);
b.setAutoCancel(true).setDefaults(Notification.DEFAULT_ALL);
if (e == null) {
b.setContentTitle(getString(R.string.download_complete))
.setContentText(getString(R.string.fun))
.setSmallIcon(android.R.drawable.stat_sys_download_done)
.setTicker(getString(R.string.download_complete));
Intent outbound=new Intent(Intent.ACTION_VIEW);
outbound.setDataAndType(Uri.fromFile(output), mimeType);
b.setContentIntent(PendingIntent.getActivity(this, 0, outbound, 0));
}
else {
b.setContentTitle(getString(R.string.exception))
.setContentText(e.getMessage())
.setSmallIcon(android.R.drawable.stat_notify_error)
.setTicker(getString(R.string.exception));
}
NotificationManager mgr=
(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
mgr.notify(NOTIFY_ID, b.build());
}
(from this sample project, which is in this directory of sample projects all showing how to display Notifications)
I'm implementing a notification service and I have problems to receive the messages in Android 2.3. I receive the messages in versions 4.0 and newer but not in 2.3. In logcat appears the following errors:
Could not find class 'com.google.android.gms.ads.internal.b.c', referenced from method com.google.android.gms.ads.internal.n.e.a
.
.
Could not find class 'android.app.Notification$Builder', referenced from method com.google.android.gms.common.l.a
What could be the problem? This is my method to send the notification:
private void sendNotification(String msg) {
MainActivity.notificationClicked = true;
int icon = R.drawable.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
String strMessage = loadPreferences();
String newMessage = "";
if (!strMessage.isEmpty())
newMessage = strMessage + "<br>" + msg;
else
newMessage = msg;
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);
contentView.setImageViewResource(R.id.image, R.drawable.ic_launcher);
contentView.setTextViewText(R.id.text, Html.fromHtml(newMessage));
Notification notification = new Notification(icon, Html.fromHtml(msg), when);
notification.contentView = contentView;
String title = this.getString(R.string.app_name);
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List < ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);
Log.d("current task :", "CURRENT Activity ::" + taskInfo.get(0).topActivity.getClass().getSimpleName());
ComponentName componentInfo = taskInfo.get(0).topActivity;
Intent notificationIntent;
if(!componentInfo.getPackageName().equalsIgnoreCase("com.example.myapp")){
notificationIntent = new Intent(getApplicationContext(),
FirstActivity.class);
} else {
notificationIntent = new Intent(getApplicationContext(),
MainActivity.class);
notificationIntent.putExtra("login", true);
}
notificationIntent.putExtra("message", Html.fromHtml(msg));
oldMessage = newMessage;
savePreferences(getApplicationContext(), oldMessage);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
int notifyID = 1;
PendingIntent intent = PendingIntent.getActivity(this, notifyID,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setLatestEventInfo(this, title, msg, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.contentIntent = intent;
notificationManager.notify(notifyID, notification);
}
When I send the message I receive it in device with Android 4.2 for example but not in devices with Android 2.3. I'm debugging the app with Android 2.3 and I have put a breakpoint in the method onHandleIntent of the IntentService but it never comes. I think that it could be for the errors that appears in logcat.
How can I solve the problem for devices with Android 2.3?
Thanks in advance.
I change Notification to NotificationCompat:
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentIntent(intent);
Notification notification = mBuilder.build();
notification.contentView = contentView;
notificationManager.notify(notifyID, notification);
but the problem persist, in logcat appears the same error
Try this code. I've used this in my project and it runs good. receiverActivity is activity that will open onclick, as I can remember, but I'm not 100% sure of it.
public static void showNotification ( Context context, Class receiverActivityClass, String title, String text, int icon )
{
Intent intent = new Intent( context, receiverActivityClass );
PendingIntent pendingIntent = PendingIntent.getActivity( context, 0, intent, 0 );
// Build notification
Notification notification = new Notification.Builder( context )
.setContentTitle( title )
.setContentText( text )
.setSmallIcon( icon )
.setContentIntent( pendingIntent )
.setAutoCancel( true )
.getNotification();
NotificationManager notificationManager =
( NotificationManager ) context.getSystemService( context.NOTIFICATION_SERVICE );
notificationManager.notify( 0, notification );
}
I am trying to open the browser with a url when the user click on the push notification, i search in stackoverflow and i find this
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent);
but it doesnt work for me, when i put that the notification doesnt appear, i debugged it and it only throw the class file editor no error or anything.
this is the code
public void mostrarNotificacion(Context context, String body,String title, String icon, String url,String superior)
{
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager notManager = (NotificationManager) context.getSystemService(ns);
int icono = R.drawable.mydrawable;
CharSequence textoEstado = superior;
long hora = System.currentTimeMillis();
Notification notif = new Notification(icono, textoEstado, hora);
Context contexto = context.getApplicationContext();
CharSequence titulo = title;
CharSequence descripcion = body;
PendingIntent contIntent;
if(url.equalsIgnoreCase("NULL"))
{
Intent notIntent = new Intent(contexto,MainActivity.class);
contIntent = PendingIntent.getActivity(
contexto, 0, notIntent, 0);
}
else
{
// Intent i = new Intent(Intent.ACTION_VIEW);
//i.setData(Uri.parse(url));
// contIntent = PendingIntent.getActivity(contexto, 0, i, 0);
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent);
}
// notif.setLatestEventInfo(contexto, titulo, descripcion, contIntent);
//AutoCancel:
notif.flags |= Notification.FLAG_AUTO_CANCEL;
//send notif
notManager.notify(1, notif);
}
What you need to do is set a pending intent -
which will be invoked when the user clicks the notification.
(Above you just started an activity...)
Here's a sample code :
private void createNotification(String text, String link){
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this)
.setAutoCancel(true)
.setSmallIcon(R.drawable.app_icon)
.setContentTitle(text);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// pending implicit intent to view url
Intent resultIntent = new Intent(Intent.ACTION_VIEW);
resultIntent.setData(Uri.parse(link));
PendingIntent pending = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder.setContentIntent(pending);
// using the same tag and Id causes the new notification to replace an existing one
mNotificationManager.notify(String.valueOf(System.currentTimeMillis()), PUSH, notificationBuilder.build());
}
Edit 1 :
I changed the answer to use PendingIntent.FLAG_UPDATE_CURRENT for the sample purpose. Thanks Aviv Ben Shabat for the comment.
Edit 2 :
Following Alex Zezekalo's comment, note that opening the notification from the lock screen, assuming chrome is used, will fail as explained in the open issue : https://code.google.com/p/chromium/issues/detail?id=455126 -
Chrome will ignore the intent, and you should be able to find in your logcat -
E/cr_document.CLActivity﹕ Ignoring intent: Intent { act=android.intent.action.VIEW dat=http://google.com/... flg=0x1000c000 cmp=com.android.chrome/com.google.android.apps.chrome.Main (has extras) }