7

I am thinking about having two separate alarms to gather a user's location data every hour, one that goes off every 59 minutes to "connect" the client and a second to actually get the location and then subsequently disconnect the client.

In terms of battery life, is there anything else I should consider doing if getting the user's location will be the primary drain of the app? Or, is there a different approach to having two alarms? I originally only had a single alarm, but performing a (!mLocationClient.isConnected) then connect check does not give the client enough time to connect.

Thanks for your insight.

The two alarms would go off something like this:

private int PERIODIC_UPDATE = 60000*60;  //gets location and disconnects every hour
private int PERIODIC_RECONNECTION_UPDATE = 60000*59;  //connects 1 minute before getLocation call

    Timer toReconnect = new Timer();
    toReconnect.schedule(new TimerTask() {

        @Override
        public void run() {
            mLocationClient.connect();
        }
    }, 5000, PERIODIC_RECONNECTION_UPDATE);

    Timer theTimer = new Timer(); 
    theTimer.schedule(new TimerTask(){
        @Override
        public void run() {
            try {
                if(!mLocationClient.isConnected()) {
                    mLocationClient.connect();
                    //This will not have much affect because cannot so quickly, will remove. 
                }

                Location theLocation = mLocationClient.getLastLocation();
                if(theLocation!=null) {
                    checkPostLocation(theLocation); 

                    mLocationClient.disconnect();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }   
        }}, 5000, PERIODIC_UPDATE);
NumenorForLife
  • 1,736
  • 8
  • 27
  • 55
  • The most battery effiect way is to disable all Messenger Apps, and leave the display off. Then you can record GPS once a seconds for more than 8 hours. – AlexWien Jun 17 '13 at 16:32
  • @jsc123 Note that using the Fused Location Provider with "getLastLocation()" does not guarantee a GPS location - you may get a location that's primarily based off of sensors, WiFi, or cellular connection. Also, you're not necessarily forcing a new location, so you may get the same location you got last time if no other app, including Google Services, has requested an updated location. – Sean Barbeau Jun 17 '13 at 19:34
  • @SeanBarbeau, wouldn't my implementation be best if I am always trying to get the most accurate location periodically, even though it is a larger drain? – NumenorForLife Jun 17 '13 at 22:41
  • "Best" is very subjective depending on your app's purpose - you really need to figure out exactly why you want to track the user and what accuracy and energy drain is appropriate. Then, match this to the priorities I list in my answer for the fused location provider. – Sean Barbeau Jun 18 '13 at 02:58

2 Answers2

4

See the "Receiving Location Updates" section on the Android developer docs for a detailed discussion of this topic with the new Fused LocationProvider:

http://developer.android.com/training/location/receive-location-updates.html

This gives you the option to register an Intent with a LocationListener to the Fused LocationProvider that is automatically triggered by the internal Google Services framework when it is considered "efficient" to do so. I would trust that this framework has a much greater potential to optimize power usage, since it has a lot more knowledge of what else is going on in the system vs. an app-registered Timer.

Here are your options for registering a listener with different power priority levels, which will result in different levels of battery drain, as listed in the above docs:

  • PRIORITY_BALANCED_POWER_ACCURACY - Used with setPriority(int) to request "block" level accuracy. Block level accuracy is considered to be about 100 meter accuracy. Using a coarse accuracy such as this often consumes less power.
  • PRIORITY_HIGH_ACCURACY - Used with setPriority(int) to request the most accurate locations available. This will return the finest location available (and the greatest potential for energy drain).
  • PRIORITY_NO_POWER - Used with setPriority(int) to request the best accuracy possible with zero additional power consumption. No locations will be returned unless a different client has requested location updates in which case this request will act as a passive listener to those locations.
Sean Barbeau
  • 11,496
  • 8
  • 58
  • 111
2

Do you actually need to track the user?

If it's just about UI, then use getLastKnownLocation(PASSIVE_PROVIDER) and you should get something semi-accurate assuming they used location services on their phone somewhere else.

If you need to actually triangulate the user, realize the different providers use different battery. Passive < Network < GPS.

The more you locate the user, the more battery with GPS taking the most battery and time.

Start the service by intent one a schedule, 1 hour or whatever, only one service necessary. Only live for a maximum of 1 minute (or less), listen on all Location providers. After the minute or accuracy is good enough, you save the result and shut down the service.

HaMMeReD
  • 2,440
  • 22
  • 29
  • Hi HaMMeReD, thanks for your suggestions. I would like to use GPS to be as precise as possible. Thus, does the above code make sense? To save battery, I disconnect immediately after using the location. Wouldn't this save battery life, because instead of having the connection continually, I only have it for about 1 minute. – NumenorForLife Jun 17 '13 at 17:28
  • Yeah, just disconnect after you triangulate, but assume the GPS might not lock on in a minute, so you might want to use the other providers in the case that gps fails. – HaMMeReD Jun 18 '13 at 23:44
  • Note that if want to specify providers you can't use the LocationClient and Google Play Services, or the code in your question - you'll have to use the original Android Location API. LocationClient uses the fused provider, and only returns locations with getProvider() = "fused" – Sean Barbeau Jun 26 '13 at 02:59