Получить местоположение GPS с помощью сервиса в Android
Мне нужно отслеживать местоположение пользователя с помощью фоновой службы, а затем загрузить их и показать путь к пользователю.
используя активность, было довольно легко получить местоположения GPS, но когда я получил это через сервис, я столкнулся с проблемой, поскольку она, похоже, работает только для потоков looper (или что-то в этом роде).
Как я искал в интернете для решения, я обнаружил, что многие люди получили ту же проблему, но я не мог найти рабочее решение. Некоторые люди говорят , что вам нужно использовать prepare->loop->quit, а некоторые говорят, что вам нужно использовать handlerThread, но все же я не могу узнать, как правильно делать такие вещи.
4 ответа:
Я не понимаю, в чем именно заключается проблема с реализацией функции прослушивания местоположения в Службе. Это выглядит довольно похоже на то, что вы делаете в деятельности. Просто определите прослушиватель местоположения и зарегистрируйтесь для обновления местоположения. Вы можете обратиться к следующему коду в качестве примера:
файл манифеста:
<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(); }