在 Android 后台服务中使用 LocationServices.FusedLocationApi.requestLocationUpdates...onLocationChanged 从未调用
Posted
技术标签:
【中文标题】在 Android 后台服务中使用 LocationServices.FusedLocationApi.requestLocationUpdates...onLocationChanged 从未调用【英文标题】:Using LocationServices.FusedLocationApi.requestLocationUpdates in an Android background service...onLocationChanged never called 【发布时间】:2016-09-04 08:47:36 【问题描述】:我已经搜索了好几天,不知何故,为什么没有调用 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"/>
【问题讨论】:
你从来没有设置你已经实现的监听器。 请解释一下,据我所知,我已经实现了所有必需的侦听器。 在哪里可以找到解决此问题的方法? @Kit 【参考方案1】:requestLocationUpdates 当前使用了一个挂起的意图,该意图被触发以再次启动服务。这不是调用 OnLocationchanged 回调。尝试将 requestLocationUpdates 与位置侦听器(第三个参数)一起使用。它应该调用 OnLocationchanged。
【讨论】:
这确实会触发 onLocationChanged 但似乎我需要使用 PendingIntent 来确保我的服务在应用程序处于后台时继续运行。看看这个:@ 987654321@ ...话虽如此,我尝试在清单中注册一个广播接收器,并实际实现它,就像我发布的链接所说的那样......但是我没有收到位置更改广播(是的,位置正在改变)。 如果您通过 START_STICKY 实现服务,那么如果服务因内存不足而终止,Android 操作系统将重新启动该服务。因此,请确保在恢复时,requestLocationUpdates 会再次启动。不要担心待处理的意图(不同场景中的用例)。如果一切都好,你可以投票赞成我的回答。 您没有回答问题。侦听器在使用位置侦听器时被触发,它们用于您的应用需要在前台更新位置时。当你想在你的应用程序也在后台接收更新时使用 Pendingintent。 [android 文档]('developers.google.com/android/reference/com/google/android/gms/…, com.google.android.gms.location.LocationRequest, android.app.PendingIntent)')以上是关于在 Android 后台服务中使用 LocationServices.FusedLocationApi.requestLocationUpdates...onLocationChanged 从未调用的主要内容,如果未能解决你的问题,请参考以下文章
如何使用相机在 Android 上的后台服务中拍照? [复制]
在 Android 后台服务中使用 LocationServices.FusedLocationApi.requestLocationUpdates...onLocationChanged 从未调用