2014-12-11 2 views
0

Мое приложение имеет виджет и отображает информацию в зависимости от местоположения устройства.Android Хорошая практика использования LocationListener в IntentService?

Я хотел бы получить место с помощью IntentService, потому что он разрушает себя после того, как дело сделано, однако алгоритм выполняет метод и заканчивается

@Override 
protected void onHandleIntent(Intent intent) 

. поэтому некогда слушать некоторые места и давать информацию обратно.

можно ли позволить LocationListener подождать, пока

@Override 
public void onLocationChanged(Location location) { 

не называется?

как правильно использовать лупер в методе

LocationManager.requestLocationUpdates(

?

здесь весь код IntentService:

public class GetLocation extends IntentService { 
public GetLocation() { 
    super("GetLocation"); 
    // TODO Auto-generated constructor stub 
} 

private static final String TAG = "GetLocation"; 
private LocationManager mLocationManager = null; 
private static final int LOCATION_INTERVAL = 1000; 
private static final float LOCATION_DISTANCE = 10f; 
private ResultReceiver resultReceiver; 
public static final String RECEIVER = "receiver"; 
public static final String GPS = "gps"; 
private int result = Activity.RESULT_CANCELED; 
public static String RESULT = "result"; 
Location mLastLocation; 

private class LocationListener implements android.location.LocationListener { 

    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); 
     result = Activity.RESULT_OK; 
     publishResults(new double[] { mLastLocation.getLatitude(), 
       mLastLocation.getLongitude() }, result); 

    } 

    @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 
protected void onHandleIntent(Intent intent) { 
    // TODO Auto-generated method stub 
    Log.e(TAG, "onHandleIntent"); 
    resultReceiver = intent.getParcelableExtra(RECEIVER); 

    initializeLocationManager(); 
    try { 
     mLocationManager.requestLocationUpdates(
       LocationManager.NETWORK_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, "network 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]); 
       Log.i(TAG, "remove location listners"); 
      } 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); 
    } 
} 

private void publishResults(double[] gps, int result) { 

    Bundle bundle = new Bundle(); 
    bundle.putDoubleArray(GPS, gps); 
    bundle.putInt(RESULT, result); 
    resultReceiver.send(Activity.RESULT_OK, bundle); 
} 
} 

EDIT:

Я хотел бы добавить окончательный код для службы, которая дает координаты к приемнику:

Однако, работает только поставщик gps, сеть игнорируется на устройстве (все активировано в настройках)

public class LocationGetter extends Service { 

private static final String TAG = "LocationGetter"; 
private LocationManager mLocationManager = null; 
private static final int LOCATION_INTERVAL = 1000; 
private static final float LOCATION_DISTANCE = 10f; 
private ResultReceiver resultReceiver; 
public static final String RECEIVER = "receiver"; 
public static final String GPS = "gps"; 
private int result = Activity.RESULT_CANCELED; 
public static String RESULT = "result"; 
Location mLastLocation; 

@Override 
public IBinder onBind(Intent intent) { 
    // TODO Auto-generated method stub 
    return null; 
} 

@Override 
public void onCreate() { 
    // TODO Auto-generated method stub 
    super.onCreate(); 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    // TODO Auto-generated method stub 

    Log.e(TAG, "onStartCommand"); 
    resultReceiver = intent.getParcelableExtra(RECEIVER); 

    initializeLocationManager(); 
    try { 
     mLocationManager.requestLocationUpdates(
       LocationManager.NETWORK_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, "network provider does not exist, " + ex.getMessage()); 
    } 

    return super.onStartCommand(intent, flags, startId); 
} 

private class LocationListener implements android.location.LocationListener { 

    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); 
     result = Activity.RESULT_OK; 
     publishResults(new double[] { mLastLocation.getLatitude(), 
       mLastLocation.getLongitude() }, result); 

    } 

    @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) }; 

private void initializeLocationManager() { 
    Log.e(TAG, "initializeLocationManager"); 
    if (mLocationManager == null) { 
     mLocationManager = (LocationManager) getApplicationContext() 
       .getSystemService(Context.LOCATION_SERVICE); 
    } 
} 

private void publishResults(double[] gps, int result) { 

    Bundle bundle = new Bundle(); 
    bundle.putDoubleArray(GPS, gps); 
    bundle.putInt(RESULT, result); 
    resultReceiver.send(Activity.RESULT_OK, bundle); 
} 
} 
+2

«Я хотел бы получить местоположение с помощью IntentService, потому что он уничтожает себя после выполнения задания» - сделайте это самостоятельно в регулярной «службе», вызвав 'stopSelf()', когда ваша 'Сервис' получил свое местоположение. IMHO, «IntentService» не является хорошим решением для этого случая использования. – CommonsWare

ответ

0

Вы выбрали неправильный путь - вы должны использовать Службу для прослушивания обновлений местоположения, потому что Служба не будет закрыта после ее выполнения.

Другой способ - подписать какой-либо компонент службы на обновления местоположения через AndroidManifest.xml, указав правильный IntentFilter. В этой ситуации это может быть IntentService, поскольку будет выполнен только его метод OnReceive().

+0

Спасибо за ответ. Второй метод потребляет больше батареи? Так как я хотел бы обновлять только каждые 30 минут? – user1616685

+0

Вообще - да. он будет запускать вашу службу при каждом обновлении. Но вы можете настроить его «отключено», и в коде вы можете использовать PackageManager, чтобы включить его, когда это необходимо. –

+0

спасибо, но я попробую сначала с Сервисом (1-й метод). Я обновил ответ, кажется, что только провайдер gps запускает onLocationChanged .... – user1616685

Смежные вопросы