Ответ 1
Вы определенно пытаетесь сделать это с трудом. Вот некоторые фрагменты нового приложения, над которым я работаю. Он использует Criteria, чтобы все поставщики могли точно и точно получать точность без затрат.
Если ни один провайдер не включен, отображается диалоговое окно, в котором пользователь запрашивает параметры своего местоположения. Если пользователь нажимает ok, на самом деле умышленно запущен Intent, который отправляет их в настройки на своем телефоне. Если есть поставщики, приложение использует последнее последнее известное местоположение от любого из разрешенных поставщиков. Для моего приложения мне просто нужно знать, в какой общей области находится пользователь, и, вероятно, последнее известное местоположение находится из их родной области.
Если провайдеры включены, цикл также запрашивает обновления местоположения как можно быстрее. Это идеально подходит для моего приложения, но вы можете изменить это, чтобы сохранить батарею, модифицируя аргументы метода requestLocationUpdates.
Оптимизация этого кода показывает, что примеры в приложении Android на самом деле не показывают, что все включенные поставщики запускаются одновременно. Все поставщики возвратят отдельные обновления в метод onLocationChanged. В моем приложении я удаляю приемник местоположения после того, как один из поставщиков возвращает местоположение с достаточно хорошей точностью.
Начать обновление местоположения:
void getCurrentLocation() {
List<String> providers = locationManager.getProviders(criteria, true);
if (providers != null) {
Location newestLocation = null;
for (String provider : providers) {
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
if (newestLocation == null) {
newestLocation = location;
} else {
if (location.getTime() > newestLocation.getTime()) {
newestLocation = location;
}
}
locationManager.requestLocationUpdates(provider, 0, 0, this);
}
}
} else {
LocationDialogFragment dialog = new LocationDialogFragment();
dialog.show(getSupportFragmentManager(),
LocationDialogFragment.class.getName());
}
}
Получить обновление местоположения:
@Override
public void onLocationChanged(Location location) {
float bestAccuracy = -1f;
if (location.getAccuracy() != 0.0f
&& (location.getAccuracy() < bestAccuracy) || bestAccuracy == -1f) {
if (location.getAccuracy() < Const.MIN_ACCURACY) {
locationManager.removeUpdates(this);
}
}
bestAccuracy = location.getAccuracy();
}
Диалог настроек местоположения:
public class LocationDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.location_dialog_message)
.setPositiveButton(R.string.location_dialog_positive_button,
new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent settingsIntent = new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(settingsIntent);
}
})
.setNegativeButton(R.string.location_dialog_negative_button,
new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getActivity(),
R.string.no_location_message, Toast.LENGTH_LONG)
.show();
}
});
return builder.create();
}
}