Самым простым вариантом может быть использование местоположения GPS на вашем телефоне без маяков.
Для этого вам нужно найти API-интерфейс музея для отображения информации о ближайших музеях.
Затем вы можете использовать LocationManager
в Android, чтобы сначала проверить, предоставлены ли разрешения на местоположение:
private Location getLastKnownLocation() {
Location n = null;
LocationManager mLocationManager = (LocationManager)getApplicationContext().getSystemService(LOCATION_SERVICE);
List<String> locationProviders = mLocationManager.getProviders(true);
for (String provider : locationProviders) {
if(ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)==PackageManager.PERMISSION_GRANTED) {
n = mLocationManager.getLastKnownLocation(provider);
}
}
return n;
}
Затем нам нужно сделать следующее:
Location gps = getLastKnownLocation();
String latitude = Double.toString(gps.getLatitude());
Log.e(“User Location Latitude”, “” + gps.getLatitude());
String longitude = Double.toString(gps.getLongitude());
Log.e(“User Location Longitude”, “” + gps.getLongitude());
Uri baseUri = Uri.parse(“YOUR_API_URL” + latitude + “YOUR_API_URL” + longitude + “YOUR_API_URL”);
Log.e(“Api Query”, “” + baseUri);
Uri.Builder uriBuilder = baseUri.buildUpon();
Другой элегантный способ получить местоположение - реализовать getLastKnownLocation
Реактивный способ.
Этот подход позволяет сделать код лаконичным, используя лямбды, объединяя наблюдаемые и используя отложенные вычисления.Для этого можно объединить библиотеку RxPermissions и библиотеку RxLocation для большей гибкости.
Ниже код для этого поста взят из предоставленных официальных документов обеих библиотек, с некоторыми изменениями, подходящими для этого обсуждения:
final RxPermissions rxPermissions = new RxPermissions(this);
rxLocation = new RxLocation(this);
Как и в обычном нереактивном методе ранее, мы создаемgetLastKnownLocation
:
private void getLastKnownLocation(final String apiSearch) {
compositeDisposable.add(rxPermissions
.request(Manifest.permission.ACCESS_FINE_LOCATION)
.subscribe(granted -> {
if (granted) {
Приведенное ниже lastLocation()
относится к Maybe<T>
, который является ленивой реализацией, представляющей отсроченное вычисление Rx.
Это позволяет onSuccess
, onComplete
& onError
работать как взаимоисключающие события, в отличие от Observable, так что если местоположение недоступно, подписчику не возвращается значение.
Используя эту библиотеку, упаковывает LocationServices.FusedLocationApi в rxLocation.location()
:
rxLocation.location().lastLocation()
.doOnSuccess(location -> {
// Your code implementation for Received Last Known Location: If last known location is already known & exists, to pass the existing last known location into your museum api, to fetch results to your adapter
})
.doOnComplete(() -> {
// Your code implementation for handling the Location Request, then doing a Completing action: This sends a new request to request the latest user location, before subscribing to your museum api, to fetch results to your adapter
})
.doOnError(throwable ->
// Your code implementation to handle any errors thrown: Pops a toast message to prompt user to enable GPS location on phone
})
Следуя документации, мы отправляем запрос на местоположение пользователя:
private void latestLocation(final String apiSearch) {
LocationRequest locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(6000); // 6s
Мыподписаться на обновления местоположения, чтобы предотвратить возвращение местоположения пустым, что возможно при обычном нереактивном методе.При использовании этой библиотеки LocationServices.FusedLocationApi переносится в rxLocation.location()
:
rxLocationSubscriber = rxLocation.location().updates(locationRequest)
Поскольку вызов fromLocation()
ниже относится к Maybe<T>
, он возвращает Maybe.Мы преобразуем его в Observable через toObservable
, чтобы использовать его с flatMap
, который поддерживает параллелизм потоков.Эта библиотека оборачивает Geocoder API в rxLocation.geocoding()
:
.flatMap(location ->
rxLocation.geocoding().fromLocation(location).toObservable())
.subscribe(location -> {
// your code implementation for museum api
rxLocationSubscriber.dispose();
});
}
Я думаю, что самым простым подходом будет первый описанный метод.
Надеюсь, это полезно.