0

I would like to use Android's LocationManager and the addProximityAlert method to setup proximity alerts. For this, I've created a small application that shows a crosshair on top of a map, plus a text field for the proximity alert name and a button to trigger the addition of the alert.

Unfortunately, the BroadcastReceiver that should receive the proximity alerts is not triggered. I've tested the intent alone (not wrapped via a PendingIntent) and that works. Also, I see that once a proximity alert is set, the GPS / location icon appears in the notification bar.

I've found information about proximity alerts a bit confusing - some are telling the alerts cannot be used if the activity is no longer in the foreground. I think it should work, so I assume something else is wrong.

1 Adding a Proximity alert

        GeoPoint geo = mapView.getMapCenter();
        Toast.makeText(this, geo.toString(), Toast.LENGTH_LONG).show();
        Log.d("demo", "Current center location is: " + geo);

        PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, getLocationAlertIntent(), 0);
        locationManager.addProximityAlert(geo.getLatitudeE6()/1E6, geo.getLongitudeE6()/1E6, 1000f, 8*60*60*1000, pIntent);

The intent itself is here:

    private Intent getLocationAlertIntent()
{
    Intent intent = new Intent("com.hybris.proxi.LOCATION_ALERT");
    intent.putExtra("date", new Date().toString());
    intent.putExtra("name", locationName.getEditableText().toString());
    return intent;
}

I created a receiver which is supposed to receive the location alerts, registered in AndroidManifest.xml:

        <receiver android:name=".LocationAlertReceiver">
         <intent-filter>
            <action android:name="com.hybris.proxi.LOCATION_ALERT" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

The implementation itself is hopefully straightforward. It is supposed to show a notification (and I checked that via directly sending an intent with a test button).

public class LocationAlertReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context ctx, Intent intent) {
    Log.d("demo", "Received Intent!");

    String dateString = intent.getStringExtra("date");
    String locationName = intent.getStringExtra("name");

    boolean isEntering = intent.getBooleanExtra(LocationManager.KEY_PROXIMITY_ENTERING, false);

    NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);

     Notification notification = new Notification.Builder(ctx)
     .setContentTitle("LocAlert: " + locationName)
            .setContentText(dateString + "|enter: " + isEntering)
            .setSmallIcon(R.drawable.ic_stat_loc_notification)
     .build();

     notificationManager.notify(randomInteger(), notification);
}

private int randomInteger()
{
    Random rand = new Random(System.currentTimeMillis());
    return rand.nextInt(1000);

}

A few things that I am not 100% sure of, maybe this triggers something in you:

  • I assume it is OK to register a proximity alert using a pending intent like I do and the Activity that created the proximity alert can later be closed.
  • Converting from the Map via getCenter returns a GeoPoint with lat/lon as int values. I thnk I am correctly converting them the the double values expected by addProximityAlert by dividing by 1E6
    • The distance from the center is relatively large - 1000m - I assume that is a nice value.
    • Examples that I've found online used broadcast receivers registered programmatically. this is not what I want to do. but the book Android 4 Profession Dev by Reto Meier mentions that registering the broadcast receiver in xml is also fine.

Any help greatly appreciated!!

Sven Haiges
  • 2,636
  • 5
  • 42
  • 54
  • No one has answered yet and I switched to a background service which is called by a broadcast receiver in a regular fashion (plus implements a wake lock, so the service can really finish its work). My impression is that proximity alerts using the locationManager do work, but only in the foreground and only if the receiver is registered in the app programmatically. I was not able to make this work consistently... Poor implementation, would need to be documented. – Sven Haiges Oct 12 '12 at 08:12

1 Answers1

0

I ran into the same issue. Setting target class of the intent explicitly helped in my case. In your case it should look the following:

private Intent getLocationAlertIntent()
{
    Intent intent = new Intent(context, LocationAlertReceiver.class);
    intent.setAction("com.hybris.proxi.LOCATION_ALERT"); //not sure if this is needed
    intent.putExtra("date", new Date().toString());
    intent.putExtra("name", locationName.getEditableText().toString());
    return intent;
}
Andrii Chernenko
  • 9,873
  • 7
  • 71
  • 89