Reputation: 499
My Android project gives location-based reminders.In a service,I am calculating the distance from the current location to all the locations in the database. If the distance is less than 500m,a notification is given to the user. The problem is that, since the calculation of distance and sending of notifications is being done within the service, the notifications keep coming repeatedly for the same location if the distance is<500m. Ultimately the app has to be force closed. Here is the onLocationChanged method of the service class:
public void onLocationChanged(Location location) {
double lat = location.getLatitude(),lng = location.getLongitude(),dblat = 0,dblng=0;
Location currentlocation = new Location("current Location");
currentlocation.setLatitude(lat);
currentlocation.setLongitude(lng);
int NOTIFICATION_ID = 1;
String ns = Context.NOTIFICATION_SERVICE;
String title,date,today;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
Calendar cal=Calendar.getInstance();
today = String.valueOf(cal.get(Calendar.YEAR)) + "-"
+ String.valueOf(cal.get(Calendar.MONTH)) + "-"
+ String.valueOf(cal.get(Calendar.DAY_OF_MONTH));
SQLiteDatabase database = new SQLiteHelper(getApplicationContext()).getWritableDatabase();
Cursor c = database.rawQuery("select title,reminderdate,latitude,longitude from Reminder where type=1", null);
int icon = R.drawable.ic_launcher;
if(c.getCount()>0)
{ //System.out.println("c not null");
c.moveToFirst();
while(!c.isAfterLast())
{
title=c.getString(0);
date=c.getString(1);
if(date.equals(today))
{
dblat=c.getDouble(2);
dblng=c.getDouble(3);
Location dblocation = new Location("db Location");
dblocation.setLatitude(dblat);
dblocation.setLongitude(dblng);
Double distance = (double) currentlocation.distanceTo(dblocation);
if(distance<500)
//Toast.makeText(this, "distance " + distance, Toast.LENGTH_LONG).show();
{ long when = System.currentTimeMillis();
Notification notification = new Notification(icon,title, when);
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification);
contentView.setImageViewResource(R.id.notification_image, R.drawable.ic_launcher);
contentView.setTextViewText(R.id.notification_title, "My custom notification title");
contentView.setTextViewText(R.id.notification_text, "My custom notification text");
notification.contentView = contentView;
Intent notificationIntent = new Intent(this, ShowReminder.class);
notificationIntent.putExtra("title", title);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;
notification.flags |= Notification.FLAG_NO_CLEAR; //Do not clear the notification
notification.defaults |= Notification.DEFAULT_LIGHTS; // LED
notification.defaults |= Notification.DEFAULT_VIBRATE; //Vibration
notification.defaults |= Notification.DEFAULT_SOUND; // Sound
mNotificationManager.notify(NOTIFICATION_ID, notification);
} }
c.moveToNext();
}}
c.close();
database.close();
}
How can I make only a single notification come only once for a particular location whenever I am near it instead of it coming repeatedly? Any help will be greatly appreciated. Thanks a lot!
Upvotes: 1
Views: 529
Reputation: 2481
You'll have to add some logic to your service to decide more carefully when notifications should be triggered.
For example, you might add a column to your table that tracks whether the user is currently "close enough" (<500 in your example) to a given location to be notified; each time you re-compute distances, if you discover that you are now "close enough" but the column doesn't yet reflect that, you know that the user has only just entered the proximity of that location and it's time to enqueue a notification about it. Make a note in the DB that the user is now close to that location, so that you can suppress redundant notifications about that location. Be sure to clear the "close enough" bit once you leave the proximity.
There will still be some redundant notifications if you're right on the edge of "close enough" so you'll need to add some debouncing, but this should get you on your way.
Upvotes: 1