通过Android中的服务获取GPS位置
我需要使用后台服务来监视用户的位置,然后加载它们并向用户显示path。
使用一个活动,很容易获得GPS位置,但是当我通过一个服务来做到这一点时,我遇到了一个问题,因为它似乎只适用于looper线程(或类似的东西)。
正如我在互联网上search解决scheme,我发现很多人都遇到了同样的问题,但我找不到一个可行的解决scheme。 有人说你需要使用prepare-> loop-> quit,有人说你必须使用handlerThread,但是我仍然不知道如何以适当的方式做这样的事情。
我不明白在服务中实现位置监听function到底是什么问题。 它看起来和你在Activity中做的很相似。 只需定义一个位置监听器并注册位置更新。 你可以参考下面的代码作为例子:
清单文件:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:label="@string/app_name" android:name=".LocationCheckerActivity" > <intent-filter > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyService" android:process=":my_service" /> </application>
服务文件:
import android.app.Service; import android.content.Context; import android.content.Intent; import android.location.Location; import android.location.LocationManager; import android.os.Bundle; import android.os.IBinder; import android.util.Log; public class MyService extends Service { private static final String TAG = "BOOMBOOMTESTGPS"; private LocationManager mLocationManager = null; private static final int LOCATION_INTERVAL = 1000; private static final float LOCATION_DISTANCE = 10f; private class LocationListener implements android.location.LocationListener{ Location mLastLocation; public LocationListener(String provider) { Log.e(TAG, "LocationListener " + provider); mLastLocation = new Location(provider); } @Override public void onLocationChanged(Location location) { Log.e(TAG, "onLocationChanged: " + location); mLastLocation.set(location); } @Override public void onProviderDisabled(String provider) { Log.e(TAG, "onProviderDisabled: " + provider); } @Override public void onProviderEnabled(String provider) { Log.e(TAG, "onProviderEnabled: " + provider); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { Log.e(TAG, "onStatusChanged: " + provider); } } LocationListener[] mLocationListeners = new LocationListener[] { new LocationListener(LocationManager.GPS_PROVIDER), new LocationListener(LocationManager.NETWORK_PROVIDER) }; @Override public IBinder onBind(Intent arg0) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand"); super.onStartCommand(intent, flags, startId); return START_STICKY; } @Override public void onCreate() { Log.e(TAG, "onCreate"); initializeLocationManager(); try { mLocationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, mLocationListeners[1]); } catch (java.lang.SecurityException ex) { Log.i(TAG, "fail to request location update, ignore", ex); } catch (IllegalArgumentException ex) { Log.d(TAG, "network provider does not exist, " + ex.getMessage()); } try { mLocationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, mLocationListeners[0]); } catch (java.lang.SecurityException ex) { Log.i(TAG, "fail to request location update, ignore", ex); } catch (IllegalArgumentException ex) { Log.d(TAG, "gps provider does not exist " + ex.getMessage()); } } @Override public void onDestroy() { Log.e(TAG, "onDestroy"); super.onDestroy(); if (mLocationManager != null) { for (int i = 0; i < mLocationListeners.length; i++) { try { mLocationManager.removeUpdates(mLocationListeners[i]); } catch (Exception ex) { Log.i(TAG, "fail to remove location listners, ignore", ex); } } } } private void initializeLocationManager() { Log.e(TAG, "initializeLocationManager"); if (mLocationManager == null) { mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); } } }
public class GPSService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener { private LocationRequest mLocationRequest; private GoogleApiClient mGoogleApiClient; private static final String LOGSERVICE = "#######"; @Override public void onCreate() { super.onCreate(); buildGoogleApiClient(); Log.i(LOGSERVICE, "onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(LOGSERVICE, "onStartCommand"); if (!mGoogleApiClient.isConnected()) mGoogleApiClient.connect(); return START_STICKY; } @Override public void onConnected(Bundle bundle) { Log.i(LOGSERVICE, "onConnected" + bundle); Location l = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); if (l != null) { Log.i(LOGSERVICE, "lat " + l.getLatitude()); Log.i(LOGSERVICE, "lng " + l.getLongitude()); } startLocationUpdate(); } @Override public void onConnectionSuspended(int i) { Log.i(LOGSERVICE, "onConnectionSuspended " + i); } @Override public void onLocationChanged(Location location) { Log.i(LOGSERVICE, "lat " + location.getLatitude()); Log.i(LOGSERVICE, "lng " + location.getLongitude()); LatLng mLocation = (new LatLng(location.getLatitude(), location.getLongitude())); EventBus.getDefault().post(mLocation); } @Override public void onDestroy() { super.onDestroy(); Log.i(LOGSERVICE, "onDestroy - Estou sendo destruido "); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.i(LOGSERVICE, "onConnectionFailed "); } private void initLocationRequest() { mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(5000); mLocationRequest.setFastestInterval(2000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); } private void startLocationUpdate() { initLocationRequest(); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } private void stopLocationUpdate() { LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); } protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addOnConnectionFailedListener(this) .addConnectionCallbacks(this) .addApi(LocationServices.API) .build(); } }
只是补充,我实现了这种方式,通常在我的服务类
在我的服务
@Override public void onCreate() { mHandler = new Handler(Looper.getMainLooper()); mHandler.post(this); super.onCreate(); } @Override public void onDestroy() { mHandler.removeCallbacks(this); super.onDestroy(); } @Override public void run() { InciarGPSTracker(); }
好吧,我已经通过在服务的onCreate上创build一个处理程序来解决它,并通过那里调用gps函数。