问题
what I am trying to do is have a proximity alert service which triggers a notification ONLY ONCE when you step inside the radius (without stopping the service). my code triggers notifications every time you step inside the radius and every time you step outside the radius. i've been trying with booleans and with removeProximityAlert, but no success. any ideas?
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class ProximityService extends Service {
private String PROX_ALERT_INTENT = "com.example.proximityalert";
private BroadcastReceiver locationReminderReceiver;
private LocationManager locationManager;
private PendingIntent proximityIntent;
@override
public void onCreate() {
locationReminderReceiver = new ProximityIntentReceiver();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
double lat = 55.586568;
double lng = 13.0459;
float radius = 1000;
long expiration = -1;
IntentFilter filter = new IntentFilter(PROX_ALERT_INTENT);
registerReceiver(locationReminderReceiver, filter);
Intent intent = new Intent(PROX_ALERT_INTENT);
intent.putExtra("alert", "Test Zone");
proximityIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
locationManager.addProximityAlert(lat, lng, radius, expiration, proximityIntent);
}
@override
public void onDestroy() {
Toast.makeText(this, "Proximity Service Stopped", Toast.LENGTH_LONG).show();
try {
unregisterReceiver(locationReminderReceiver);
} catch (IllegalArgumentException e) {
Log.d("receiver", e.toString());
}
}
@override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Proximity Service Started", Toast.LENGTH_LONG).show();
}
@override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
public class ProximityIntentReceiver extends BroadcastReceiver {
private static final int NOTIFICATION_ID = 1000;
@suppressWarnings("deprecation")
@override
public void onReceive(Context arg0, Intent arg1) {
String place = arg1.getExtras().getString("alert");
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent pendingIntent = PendingIntent.getActivity(arg0, 0, arg1, 0);
Notification notification = createNotification();
notification.setLatestEventInfo(arg0, "Entering Proximity!", "You are approaching a " + place + " marker.", pendingIntent);
notificationManager.notify(NOTIFICATION_ID, notification);
locationManager.removeProximityAlert(proximityIntent);
}
private Notification createNotification() {
Notification notification = new Notification();
notification.icon = R.drawable.ic_launcher;
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_SOUND;
return notification;
}
}
}
回答1:
You should remove the proximity alert after it fires and not recreate it again (save some flag, as a variable or, if you use sqlite, in your db).
Removing alerts is a bit tricky, there are 2 steps to take and both will produce the intended result of not (apparently) "firing":
Unregister your receiver
You may save a receiver (or array of receivers) and
unregister
it directly:for (ProximityReceiver proximityReceiverLocal:proximityReceiverArray) { context.unregisterReceiver(proximityReceiverLocal); proximityReceiverArray.remove(proximityReceiverLocal); // clear pile }
Remove alerts
Note: You cannot save an alert as an object, you must recreate your
PendingIntent
and submit it to itsremoveProximityAlert
method. The pending intent must have the same intent (i.e. sameaction name
) and the same pending intent id:public void removeProximityAlert(int pendingIntentIdIn, String intentActionNameIn) { Intent intent = new Intent(intentActionNameIn); PendingIntent pendingIntent = PendingIntent.getBroadcast(context , pendingIntentIdIn, intent, 0); locationManager.removeProximityAlert(pendingIntent); }
If you remove one and not the other, you will achieve your intended goal of nothing occurring when you enter the POI's radius, but you will be wasting precious battery life and memory.
来源:https://stackoverflow.com/questions/16471025/android-remove-proximity-alert-after-notification