4

How do I use

requestLocationUpdates(long minTime, float minDistance, Criteria criteria,
                                                           PendingIntent intent) 

In BroadcastReciver so that I can keep getting GPS coordinates.

Do I have to create a separate class for the LocationListener ?

Goal of my project is when I receive BOOT_COMPLETED to start getting GPS lats and longs periodically.

Code I tried is :

public class MobileViaNetReceiver extends BroadcastReceiver {

    LocationManager locmgr = null;
    String android_id;
    DbAdapter_GPS db;

    @Override
    public void onReceive(Context context, Intent intent) {
        if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
            startGPS(context);
        } else {
            Log.i("MobileViaNetReceiver", "Received unexpected intent "
                + intent.toString());
        }
    }

    public void startGPS(Context context) {
        Toast.makeText(context, "Waiting for location...", Toast.LENGTH_SHORT)
                .show();
        db = new DbAdapter_GPS(context);
        db.open();
        android_id = Secure.getString(context.getContentResolver(),
                Secure.ANDROID_ID);
        Log.i("MobileViaNetReceiver", "Android id is _ _ _ _ _ _" + android_id);
        locmgr = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
        locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5,
                onLocationChange);
    }

    LocationListener onLocationChange = new LocationListener() {

        public void onLocationChanged(Location loc) {
            // sets and displays the lat/long when a location is provided
            Log.i("MobileViaNetReceiver", "In onLocationChanged .....");
            String latlong = "Lat: " + loc.getLatitude() + " Long: "
                + loc.getLongitude();
            // Toast.makeText(this, latlong, Toast.LENGTH_SHORT).show();
            Log.i("MobileViaNetReceiver", latlong);
            try {
                db.insertGPSCoordinates(android_id,
                        Double.toString(loc.getLatitude()),
                        Double.toString(loc.getLongitude()));
            } catch (Exception e) {
                Log.i("MobileViaNetReceiver",
                        "db error catch _ _ _ _ " + e.getMessage());
            }
        }

        public void onProviderDisabled(String provider) {}

        public void onProviderEnabled(String provider) {}

        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };    
    //pauses listener while app is inactive
    /*@Override
    public void onPause() {
        super.onPause();
        locmgr.removeUpdates(onLocationChange);
    }

    //reactivates listener when app is resumed
    @Override
    public void onResume() {
        super.onResume();
        locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, onLocationChange);
     }*/
}
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
user533844
  • 2,053
  • 7
  • 36
  • 43

2 Answers2

6

There are two ways of doing this:

  1. Use the method that you are and register a BroadcastReceiver which has an intent filter which matches the Intent that is held within your PendingIntent (2.3+) or, if you are only interested in a single location provider, requestLocationUpdates (String provider, long minTime, float minDistance, PendingIntent intent) (1.5+) instead.
  2. Register a LocaltionListener using the requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener) method of LocationManager.

I think that you are getting a little confused because you can handle the location update using either a BroadcastReceiver or a LocationListener - you don't need both. The method of registering for updates is very similar, but how you receive them is really very different.

A BroadcastReceiver will allow your app / service to be woken even if it is not currently running. Shutting down your service when it is not running will significantly reduce the impact that you have on your users' batteries, and minimise the chance of a Task Killer app from terminating your service.

Whereas a LocationListener will require you to keep your service running otherwise your LocationListener will die when your service shuts down. You risk Task Killer apps killing your service with extreme prejudice if you use this approach.

From your question, I suspect that you need to use the BroadcastReceiver method .

Mark Allison
  • 21,839
  • 8
  • 47
  • 46
  • I guess I am getting confused. I have added the code that tried. What's wrong with that ? – user533844 Oct 26 '11 at 14:24
  • Your `LocationListener` needs to be in a `Service` which must stay alive permanently otherwise you simply will not receive any updates. As I said in my answer, you would be better using the other approach of handling your location updates by registering a `PendingIntent` which will cause a Broadcast to be sent to wake your `BroadcastReceiver` each time a location update occurs. Try reading http://stackoverflow.com/questions/5240246/broadcastreceiver-for-location/5240774#5240774 for more information. – Mark Allison Oct 26 '11 at 14:29
  • I think I am getting what u r saying. I should put GPS code in a class as activity(including locationlistener). In broadcastreceiver, set that intent as pending intent. Am I right ? Do you have an example ? Thanks a ot. – user533844 Oct 26 '11 at 18:04
  • 2
    No, if you're using the `PendingIntent` / `BroadcastReceiver` mechanism you don't need a `LocationListener`. Your `BroadcastReceiver` does two things: 1. On device boot starts everything up. 2. Handles subsequent location updates. There is an example in the link in my previous comment. – Mark Allison Oct 27 '11 at 07:34
3
public class MobileViaNetReceiver extends BroadcastReceiver {

    private static final String TAG = "MobileViaNetReceiver"; // please

    @Override
    public void onReceive(Context context, Intent intent) {
        if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())){
            Log.i(TAG, "Boot : registered for location updates");
            LocationManager lm = (LocationManager) context
                                .getSystemService(Context.LOCATION_SERVICE);
            Intent intent = new Intent(context, this.getClass());
            PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent,
                                        PendingIntent.FLAG_UPDATE_CURRENT);
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000,5,pi);
        } else {
            String locationKey = LocationManager.KEY_LOCATION_CHANGED;
            if (intent.hasExtra(locationKey)) {
                Location loc = (Location) intent.getExtras().get(locationKey);
                Log.i(TAG, "Location Received");
                try {
                    DbAdapter_GPS db = new DbAdapter_GPS(context);//what's this
                    db.open();
                    String android_id = Secure.getString(
                        context.getContentResolver(), Secure.ANDROID_ID);
                    Log.i(TAG, "Android id is :" + android_id);
                    db.insertGPSCoordinates(android_id,
                        Double.toString(loc.getLatitude()),
                        Double.toString(loc.getLongitude()));
                } catch (Exception e) { // NEVER catch generic "Exception"
                    Log.i(TAG, "db error catch :" + e.getMessage());
                }
            }
        }
    }
}
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361