I'm trying to get location from a background service. I'm starting the service from an Activity using the following code.
Intent serviceIntent = new Intent(this, LocationService.class);
startService(serviceIntent);
public class LocationService extends Service {
private Thread t;
Looper threadLooper = null;
public int onStartCommand(Intent intent, int flags, int startId){
Log.i("Imp", "Inside service.");
new LooperThread().start();
return Service.START_NOT_STICKY;
}
private void logLocation(String lat, String lng){
//write to database.
}
class LooperThread extends Thread {
public void run() {
Log.i("Imp", "inside thread");
Looper.prepare();
Context context = getApplicationContext();
String svcName = Context.LOCATION_SERVICE;
LocationManager locationManager = (LocationManager) context.getSystemService(svcName);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setPowerRequirement(Criteria.POWER_HIGH);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setSpeedRequired(false);
criteria.setCostAllowed(false);
Log.i("Imp", "Regestring event.");
locationManager.requestSingleUpdate(criteria, locationListener, Looper.myLooper());
Log.i("Imp", "event reg.");
Looper.loop();
stopSelf();
}
}
final LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.i("Imp", "Inside event");
if(location != null){
String lat = Double.toString(location.getLatitude());
String lng = Double.toString(location.getLongitude());
Log.i("Imp", "Lat " + lat);
Log.i("Imp", "lng " + lng);
logLocation(lat, lng);
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
}
event reg.
The recommended method is to use Location API from Google Play service.
Add the google play service dependency.
compile 'com.google.android.gms:play-services:+'
And the following code.
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class FusedLocationProvider implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
com.google.android.gms.location.LocationListener,
ArchitectViewHolderInterface.ILocationProvider {
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private LocationListener listener;
private String TAG = "FusedLocationProvider";
public FusedLocationProvider(Context ctx, LocationListener locationListener){
mGoogleApiClient = new GoogleApiClient.Builder(ctx)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
Log.i(TAG, "Connecting...");
this.listener = locationListener;
}
@Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "onConnected");
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(1000); // Update location every second
try{
if(mGoogleApiClient.isConnected()) {
Log.i(TAG, "requestLocationUpdates");
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}catch (SecurityException se){
Log.i(TAG, se.toString());
}catch (Exception e){
Log.i(TAG, e.toString());
}
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "onConnectionSuspended");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "onConnectionFailed");
}
@Override
public void onLocationChanged(Location recentLoc) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Log.i(TAG, Double.toString(recentLoc.getLongitude()));
listener.onLocationChanged(recentLoc);
}
public void onPause() {
Log.i(TAG, "onPause");
if(mGoogleApiClient.isConnected()) {
Log.i(TAG, "removeLocationUpdates");
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
}
@Override
public void onResume() {
Log.i(TAG, "onResume");
try{
if(mGoogleApiClient.isConnected()){
Log.i(TAG, "requestLocationUpdates");
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}catch (SecurityException se){
Log.i(TAG, se.toString());
}catch (Exception e){
Log.i(TAG, e.toString());
}
}
public void onStop(){
Log.i(TAG, "onStop");
if(mGoogleApiClient.isConnected()) {
Log.i(TAG, "disconnect");
mGoogleApiClient.disconnect();
}
}
}
And the following the permissions in the android manifest file.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_GPS" />