何日も何日も検索しましたが、どういうわけか onLocationChanged が呼び出されない理由に対する答えがわかりませんでした。私はドキュメントを広範囲に読みましたが、決定的な何かが欠けているに違いありません。場所が変更されたときにバックグラウンドで実行されるサービスが必要なだけで、場所をログに記録したい.
これが私のサービスです...
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.annotation.Nullable;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class BackgroundLocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private final String TAG = ((Object) this).getClass().getSimpleName();
IBinder mBinder = new LocalBinder();
GoogleApiAvailability googleAPI;
PowerManager.WakeLock mWakeLock;
private boolean mInProgress;
private Boolean servicesAvailable = false;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
private Intent mIntentService;
private PendingIntent mPendingIntent;
public class LocalBinder extends Binder {
public BackgroundLocationService getServerInstance() {
return BackgroundLocationService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
googleAPI = GoogleApiAvailability.getInstance();
mInProgress = false;
mIntentService = new Intent(this,BackgroundLocationService.class);
mPendingIntent = PendingIntent.getService(this, 1, mIntentService, PendingIntent.FLAG_UPDATE_CURRENT);
servicesAvailable = servicesConnected();
/*
* Create a new google api client, using the enclosing class to handle callbacks.
*/
buildGoogleApiClient();
}
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode = googleAPI.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
return true;
} else {
return false;
}
}
protected void startLocationUpdates() {
Log.i(TAG, "Started Location Updates");
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mPendingIntent);
}
protected void stopLocationUpdates() {
Log.i(TAG,"Stopped Location Updates");
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mPendingIntent);
}
protected void createLocationRequest() {
Log.i(TAG, "createLocationRequest()");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(1000);
//mLocationRequest.setMaxWaitTime(10000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
PowerManager mgr = (PowerManager) getSystemService(Context.POWER_SERVICE); //*** added this
if (this.mWakeLock == null) {
mWakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "aWakeLock"); //*** added this
}
if (!this.mWakeLock.isHeld()) {
mWakeLock.acquire(); //*** added this
}
if (!servicesAvailable || mGoogleApiClient.isConnected() || mInProgress)
return START_STICKY;
if (!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting() && !mInProgress) {
Log.e(TAG, "Location Client not connected, connecting...");
mInProgress = true;
mGoogleApiClient.connect();
}
Log.e(TAG, "Location Client: onStartCommand");
return START_STICKY;
}
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
if (mGoogleApiClient == null) {
this.mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
createLocationRequest();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onDestroy() {
// Turn off the request flag
this.mInProgress = false;
if (this.mWakeLock != null) {
this.mWakeLock.release();
this.mWakeLock = null;
}
Log.e(TAG, "Location Client: ON DESTROY");
super.onDestroy();
stopLocationUpdates();
}
@Override
public void onConnected(Bundle bundle) {
startLocationUpdates();
}
@Override
public void onLocationChanged(Location location) {
Log.e(TAG, "Location Receiver [Location Changed]: " + location.getLatitude() + ", " + location.getLongitude());
}
@Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "Location Client: ON CONNECTED");
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
mInProgress = false;
Log.e(TAG, "Location Client: ON CONNECTION FAILED");
if (connectionResult.hasResolution()) {
// If no resolution is available, display an error dialog
} else {
}
}
}
こんな感じでサービスを開始するのですが…
Intent BackgroundLocationService = new Intent(this, BackgroundLocationService.class);
startService(BackgroundLocationService);
マニフェストにも次の権限があります...
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>