如何获取位置或简单的 id 来提供基于位置的内容?
Posted
技术标签:
【中文标题】如何获取位置或简单的 id 来提供基于位置的内容?【英文标题】:How to get a location or simply an id to provide location based content? 【发布时间】:2019-07-22 03:04:20 【问题描述】:我正在构建一个 android 应用,我希望我的应用提供基于位置的内容。例如,如果我在博物馆附近或其中一个,向我显示有关该博物馆的详细信息。问题是如何识别那个地方。最好的方法是什么?
信标完美地完成了这项工作,它们发出带有 id 的信号,我的应用程序读取 id 并提供相关信息。但是我需要一些时间才能获得一些信标,所以如果有任何类似的技术,请在此处列出。
GPS 技术或 API 没问题,只要它简单而不会过于复杂,因为我只想让我的应用程序验证它已到达某个位置,并在此基础上显示内容。
我有哪些选择?
【问题讨论】:
您可以使用地理定位 API 来了解用户的位置。 【参考方案1】:最简单的选择可能是使用您的手机 gps 位置,而不使用信标。
为此,您需要找到一个博物馆 api 来显示有关最近博物馆的信息。
然后,您可以在Android中使用LocationManager
首先检查是否授予了位置权限:
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
Reactive 方式。
这种方法允许使用 lambdas、链接可观察对象和使用延迟计算来保持代码简洁。一种方法是将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
我们订阅位置更新,以防止位置返回 null,这在传统的非反应式方法中是可能的。使用这个库将 LocationServices.FusedLocationApi 包装在 rxLocation.location()
中:
rxLocationSubscriber = rxLocation.location().updates(locationRequest)
因为下面的fromLocation()
调用属于Maybe<T>
,所以它返回一个Maybe。我们通过toObservable
将其转换为Observable,与支持线程并发的flatMap
一起使用。这个库在rxLocation.geocoding()
中封装了Geocoder API:
.flatMap(location ->
rxLocation.geocoding().fromLocation(location).toObservable())
.subscribe(location ->
// your code implementation for museum api
rxLocationSubscriber.dispose();
);
我认为最直接的方法是概述的第一种方法。
希望这有帮助。
【讨论】:
以上是关于如何获取位置或简单的 id 来提供基于位置的内容?的主要内容,如果未能解决你的问题,请参考以下文章
使用HTML5定位获取当前位置是,会提示***想要获取您的位置,我能否修改***的内容,如果能,要怎样修改?
SwiftUI 中如何获取任意视图触摸位置(全局或局部)的坐标
SwiftUI 中如何获取任意视图触摸位置(全局或局部)的坐标