新的 Android 地理围栏 API - 示例代码在位置时不会发出警报/通知
Posted
技术标签:
【中文标题】新的 Android 地理围栏 API - 示例代码在位置时不会发出警报/通知【英文标题】:New Android Geofence Api - Sample code does not alert/notify when at location 【发布时间】:2013-05-17 13:13:33 【问题描述】:我需要了解地理围栏指南随附的示例代码,如下所示:
https://developer.android.com/training/location/geofencing.html
我运行了代码,发现地理围栏已正确创建,但我真正想要的是一种在我开车前往这些地理围栏位置时获得警报的方法。现在,当我经过那些地理围栏点时,什么也没有发生(ReceiveTransitionsIntentService 没有被调用),没有任何通知。
我是否还必须收听定期位置更新并将 lat/lng 手动传递给上述代码以指示我当前的位置?当我向 LocationClient 添加地理围栏时,我认为这应该是自动的,但我想还有更多。
我还尝试将 LocationRequest 注册到 LocationClient 实例,但仍然没有警报:
mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(LocationUtils.UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setFastestInterval(LocationUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS);
mLocationClient.requestLocationUpdates(mLocationRequest, (LocationListener)mActivity);
如何将 Geofence api 与位置跟踪集成?
【问题讨论】:
地理围栏的半径是多少?您是否在地理围栏半径内开始驾驶?仅当您以设置的半径转换地理围栏时才会出现通知,而不是当您“越过”地理围栏点时。 我已将半径设置为 500m,我确实通过该地理围栏进行了过渡,但没有收到通知。我将半径增加到 2000m,但仍然没有调用 ReceiveTransitionsIntentService。 运行示例代码时我注意到的一件事是,当我已经在地理围栏内并将地理围栏添加到 LocationClient 时,会发生通知。但是,如果我在添加地理围栏时在外面,然后我开车进入地理围栏,那么什么都不会发生,它纯粹是无线电静默。 这很紧急,谁能帮忙? 你是怎么解决的? 【参考方案1】:我也有问题。确保在将服务添加到 AndroidManifest 时正确定义了路径。我还必须将导出的值更改为 true。
<application>
...
<service
android:name=".ReceiveTransitionsIntentService"
android:exported="true" >
</service>
...
</application>
您还需要在 Manifest 中添加元数据标签以指定您的 google gms 版本。
<application>
...
<meta-data
android:name="com.google.android.gms.version"
android:value="4242000" />
...
</application>
我创建了一个更简单的 Google 示例版本,带有代码和更多解释,here。希望对您有所帮助!
【讨论】:
【参考方案2】:不幸的是,这似乎是预期的行为。地理围栏 API 设置为侦听设备上的自动位置更新。当您在某个位置定居时,这通常会起作用,但正如您所说,如果您正在开车穿过围栏,或者您有一个半径只有几米的围栏,您可能会错过它。据说该 API 会自动检查您的行为(步行、驾驶等)并更频繁地更新,但情况似乎并非如此。
您会注意到,如果您打开 Google 地图并跟踪您的位置,栅栏就会正确触发。
因此,您可以假设唯一真正的解决方案是设置您自己的服务,该服务以定义的时间间隔(Google 建议 20 秒 https://www.youtube.com/watch?v=Bte_GHuxUGc)轮询位置,然后强制以这些时间间隔进行位置广播。如果地理围栏位于此位置,则会自动触发它们。
【讨论】:
【参考方案3】:一些快速说明:确保您选择了正确的过渡。您可能需要同时设置入口和出口过渡。
地理围栏的代码 sn-p 不显示通知。这是故意的;通知并不总是对转换的最佳响应。示例应用程序会显示一个通知,如果您下载该示例,您可以看到它。
定位服务会尽力识别您的位置。
还请记住,您必须请求 ACCESS_FINE_LOCATION。
您不会在后台“进程”中找到有关地理围栏跟踪(或与位置相关的任何其他内容)的任何具体信息。所有这些都在 Google Play 服务中。
【讨论】:
【参考方案4】:@andrewmolo 我尝试时遇到了同样的问题。 您应该为您的项目设置正确的构建路径和库。当我设置如下时,它对我有用。
-
转到项目的属性 > Android > 选择 Google API。
属性 > Java 构建路径 > 库。
确保你有
1. android-support-v4.jar
2. Google APIs
3. google-play-services_lib.jar
4. google-play-services.jar
此外,为了进行排序和导出,您应该在底部位置选择 Google API,并选择所有其他。
【讨论】:
【参考方案5】:示例代码也有一些问题。这对我有用。
latitude = sharedPreferences.getFloat("storeAddress_lat", -1);
longitude = sharedPreferences.getFloat("storeAddress_lng", -1);
final ArrayList<Geofence> list = new ArrayList<Geofence>();
Builder builder = new Geofence.Builder();
builder.setRequestId("near_store_geofence");
builder.setCircularRegion(latitude, longitude, 50);
builder.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER);
builder.setExpirationDuration(Geofence.NEVER_EXPIRE);
list.add(builder.build());
builder = new Geofence.Builder();
builder.setRequestId("leave_store_geofence");
builder.setCircularRegion(latitude, longitude, 50);
builder.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT);
builder.setExpirationDuration(Geofence.NEVER_EXPIRE);
list.add(builder.build());
final GooglePlayServicesClient.ConnectionCallbacks connectionCallbacks = new GooglePlayServicesClient.ConnectionCallbacks()
@Override
public void onConnected(Bundle connectionHint)
Log.i("GEOFENCE","onConnected");
// Create an explicit Intent
Intent intent = new Intent(getBaseContext(), ReceiveTransitionsIntentService.class);
/*
* Return the PendingIntent
*/
PendingIntent pendingIntent = PendingIntent.getService(
getBaseContext(),
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
locationClient.addGeofences(list,pendingIntent, new OnAddGeofencesResultListener()public void onAddGeofencesResult(int statusCode, String[] geofenceRequestIds)
Log.i("GEOFENCE","onAddGeofencesResult");
);
LocationRequest locationrequest = LocationRequest.create();
locationrequest.setPriority(locationrequest.PRIORITY_HIGH_ACCURACY);
locationrequest.setInterval(5000);
locationClient.requestLocationUpdates(locationrequest, new LocationListener()
@Override
public void onLocationChanged(Location location)
// TODO Auto-generated method stub
);
@Override
public void onDisconnected()
Log.i("GEOFENCE","onDisconnected");
;
GooglePlayServicesClient.OnConnectionFailedListener onConnectionFailedListener = new GooglePlayServicesClient.OnConnectionFailedListener()
@Override
public void onConnectionFailed(ConnectionResult result)
Log.i("GEOFENCE","onConnectionFailed");
;
locationClient = new LocationClient(getBaseContext(), connectionCallbacks, onConnectionFailedListener);
locationClient.connect();
【讨论】:
【参考方案6】:地理围栏 API 永远不会启用 GPS(这太糟糕了,我需要响应式地理围栏该死的,而且不关心功耗)。文档中的任何地方也没有提到这一点。此外,如果没有 GPS,由于 wifi/cell 缺乏准确性,您不可能希望拥有更小的地理围栏。
您必须使用 null 处理程序单独轮询 GPS,以便提供给该 null 处理程序的有价值的位置也提供给地理围栏 API,从而可靠地触发您的地理围栏。
【讨论】:
【参考方案7】:请注意,该示例包含一个错误,该错误将使您的围栏在 12 分钟后过期,而不是预期的 12 小时... 修复更改
private static final long SECONDS_PER_HOUR = 60;
到
private static final long SECONDS_PER_HOUR = 60*60;
在 MainActivity 中
【讨论】:
以上是关于新的 Android 地理围栏 API - 示例代码在位置时不会发出警报/通知的主要内容,如果未能解决你的问题,请参考以下文章
使用新的 Android API 跟踪 100 多个同步地理围栏
在 Android 12/API 31 中,地理围栏不适用于 IMMUTABLE 未决意图。为啥?
地理围栏(Android 示例应用程序)java.lang.ClassNotFoundException MainActivity