Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you want to listen to frequent location updates in the background (e.g., every second), you should be running your code inside a <code>Service</code>:</p> <p><a href="http://developer.android.com/reference/android/app/Service.html" rel="noreferrer">http://developer.android.com/reference/android/app/Service.html</a></p> <p>Activities can be ended by the Android platform at any point in time in which they are not in the foreground.</p> <p>When using a Service, I would recommend having the Service implement the LocationListener directly, and not a Thread inside the Service. For example, use:</p> <pre><code>public class LocListener extends Service implements com.google.android.gms.location.LocationListener, ...{ </code></pre> <p>I've used this design of implementing the LocationListener directly on the Service with the <code>LocationClient</code> and fused location provider in my <a href="https://play.google.com/store/apps/details?id=com.gpsbenchmark.android" rel="noreferrer">GPS Benchmark app</a> and I can confirm that this works even when the screen is off and the app is running in the background.</p> <p>If you want to listen to occasional location updates in the background (e.g., every minute) using the fused location provider, a better design is to use PendingIntents, using the <code>LocationClient.requestLocationUpdates(Location Request, PendingIntent callbackIntent)</code> method:</p> <p><a href="https://developer.android.com/reference/com/google/android/gms/location/LocationClient.html#requestLocationUpdates(com.google.android.gms.location.LocationRequest,%20android.app.PendingIntent)" rel="noreferrer">https://developer.android.com/reference/com/google/android/gms/location/LocationClient.html#requestLocationUpdates(com.google.android.gms.location.LocationRequest,%20android.app.PendingIntent)</a></p> <p>From the above Android doc:</p> <blockquote> <p>This method is suited for the background use cases, more specifically for receiving location updates, even when the app has been killed by the system. In order to do so, use a PendingIntent for a started service. For foreground use cases, the LocationListener version of the method is recommended, see requestLocationUpdates(LocationRequest, LocationListener).</p> <p>Any previous LocationRequests registered on this PendingIntent will be replaced.</p> <p>Location updates are sent with a key of KEY_LOCATION_CHANGED and a Location value on the intent.</p> </blockquote> <p>See the Activity Recognition example for a more detailed description of using <code>PendingIntents</code> to get updates while running in the background:</p> <p><a href="https://developer.android.com/training/location/activity-recognition.html" rel="noreferrer">https://developer.android.com/training/location/activity-recognition.html</a></p> <p>Modified excerpts from this documentation are below, changed by me to be specific to location updates.</p> <p>First declare the Intent:</p> <pre><code>public class MainActivity extends FragmentActivity implements ConnectionCallbacks, OnConnectionFailedListener { ... ... /* * Store the PendingIntent used to send location updates * back to the app */ private PendingIntent mLocationPendingIntent; // Store the current location client private LocationClient mLocationClient; ... } </code></pre> <p>Request updates as you currently are, but this time pass in the pending intent:</p> <pre><code>/* * Create the PendingIntent that Location Services uses * to send location updates back to this app. */ Intent intent = new Intent( mContext, LocationIntentService.class); ... //Set up LocationRequest with desired parameter here ... /* * Request a PendingIntent that starts the IntentService. */ mLocationPendingIntent = PendingIntent.getService(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); /* * Request location updates */ mLocationClient.requestLocationUpdates(mLocationRequest, callbackIntent); </code></pre> <blockquote> <p>Handle Location Updates</p> <p>To handle the Intent that Location Services sends for each update interval, define an IntentService and its required method onHandleIntent(). Location Services sends out ... updates as Intent objects, using the the PendingIntent you provided when you called requestLocationUpdates(). Since you provided an explicit intent for the PendingIntent, the only component that receives the intent is the IntentService you're defining.</p> <p>Define the class and the required method onHandleIntent():</p> </blockquote> <pre><code>/** * Service that receives Location updates. It receives * updates in the background, even if the main Activity is not visible. */ public class LocationIntentService extends IntentService { ... /** * Called when a new location update is available. */ @Override protected void onHandleIntent(Intent intent) { Bundle b = intent.getExtras(); Location loc = (Location) b.get(LocationClient.KEY_LOCATION_CHANGED); Log.d(TAG, "Updated location: " + loc.toString()); } ... } </code></pre> <p>IMPORTANT - to be as efficient as possible, your code in <code>onHandleIntent()</code> should return as quickly as possible to allow the IntentService to shut down. From IntentService docs:</p> <p><a href="http://developer.android.com/reference/android/app/IntentService.html#onHandleIntent(android.content.Intent)" rel="noreferrer">http://developer.android.com/reference/android/app/IntentService.html#onHandleIntent(android.content.Intent)</a></p> <blockquote> <p>This method is invoked on the worker thread with a request to process. Only one Intent is processed at a time, but the processing happens on a worker thread that runs independently from other application logic. So, if this code takes a long time, it will hold up other requests to the same IntentService, but it will not hold up anything else. When all requests have been handled, the IntentService stops itself, so you should not call stopSelf().</p> </blockquote> <p>My understanding of the <code>IntentService</code> design is that you can spawn Threads inside <code>onHandleIntent()</code> to avoid blocking other location updates via platform calls to <code>onHandleIntent()</code>, just be aware that the Service will continue to run until all the running threads terminate.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. COI have used `Service` and I am using `LocationListener` also.you can have a look at this implementation `https://github.com/commonsguy/cwac-locpoll/blob/master/src/com/commonsware/cwac/locpoll/LocationPollerService.java` ,As posted in question I am trying to build similar library and I have implemented `PollerThread` differently according to my requirement because of new Location API.
      singulars
    2. COThe LocationClient was implemented with the goal of moving developers away from managing their own wakelocks and services in the background, to make location tracking more efficient. The idea of the fused location provider is for the application to specify a general balance for accuracy/energy, and then let the fused provider take care of low-level process management to obtain the samples. The app should only need to listen for updates. Unless the Android team says otherwise, this "bug" may be by design, or at least not an area they've heavily tested, expecting devs to use PendingIntents.
      singulars
    3. COI am agreed with the idea of fused location provider but in case of tracking the locations in `background` mode, devs have to write service to get frequent updates and that service should hold the wakelock to keep the CPU awake.so ultimately devs have to manage these things at their own.and that is what I am doing.In short,It is not acceptable behavior that new Fused Location API can provide frequent location updates only in `foreground` mode.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload