如何在Android中使Geo Fencing警报更加准确

您好,我正在尝试在Android中添加Geo Fence的function。 我正在使用http://developer.android.com/training/location/geofencing.html来创build和监控Geo Fences。 我使用IntentService警报(input/退出),但对我来说,它不工作。

但是当我离开并回到区域testing它时,它不适合我。 我已打开设备的GPS,但设备未连接到互联网。

任何人都可以帮助我,使其更加准确和完美,没有任何问题。

 public class MainActivity extends Activity implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationClient.OnAddGeofencesResultListener { private LocationClient locationClient; private String TAG = "MainActivity"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); int resp = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (resp == ConnectionResult.SUCCESS) { locationClient = new LocationClient(this, this, this); locationClient.connect(); } } @Override public void onConnected(Bundle bundle) { ArrayList<Store> storeList = getStoreList(); if (null != storeList && storeList.size() > 0) { ArrayList<Geofence> geofenceList = new ArrayList<Geofence>(); for (Store store : storeList) { float radius = (float) store.radius; Geofence geofence = new Geofence.Builder() .setRequestId(store.id) .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT) .setCircularRegion(store.latitude, store.longitude, radius) .setExpirationDuration(Geofence.NEVER_EXPIRE) .build(); geofenceList.add(geofence); } PendingIntent geoFencePendingIntent = PendingIntent.getService(this, 0, new Intent(this, GeofenceIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT); locationClient.addGeofences(geofenceList, geoFencePendingIntent, this); } } @Override public void onDisconnected() { Log.e(TAG, "Disconnected !"); } @Override public void onAddGeofencesResult(int i, String[] strings) { if (LocationStatusCodes.SUCCESS == i) { //todo check geofence status } else { } } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.e(TAG, connectionResult.getErrorCode() + ""); } private ArrayList<Store> getStoreList() { ArrayList<Store> storeList = new ArrayList<Store>(); for (int i = 0; i < 1; i++) { Store store = new Store(); store.id = String.valueOf(i); store.address = "India"; store.latitude = 26.7802187; store.longitude = 75.860322; store.radius = 100.0; storeList.add(store); } return storeList; } public class Store { String id; String address; double latitude; double longitude; double radius; } @Override protected void onDestroy() { super.onDestroy(); if (null != locationClient) { locationClient.disconnect(); } } } 

GeofenceIntentService.java

 public static final String TRANSITION_INTENT_SERVICE = "ReceiveTransitionsIntentService"; public GeofenceIntentService() { super(TRANSITION_INTENT_SERVICE); } @Override protected void onHandleIntent(Intent intent) { if (LocationClient.hasError(intent)) { //todo error process } else { int transitionType = LocationClient.getGeofenceTransition(intent); if (transitionType == Geofence.GEOFENCE_TRANSITION_ENTER || transitionType == Geofence.GEOFENCE_TRANSITION_EXIT) { List<Geofence> triggerList = LocationClient.getTriggeringGeofences(intent); for (Geofence geofence : triggerList) { generateNotification(geofence.getRequestId(), "address you defined"); } } } } private void generateNotification(String locationId, String address) { long when = System.currentTimeMillis(); Intent notifyIntent = new Intent(this, MainActivity.class); notifyIntent.putExtra("id", locationId); notifyIntent.putExtra("address", address); notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.dac_logo) .setContentTitle(locationId) .setContentText(address) .setContentIntent(pendingIntent) .setAutoCancel(true) .setDefaults(Notification.DEFAULT_SOUND) .setWhen(when); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify((int) when, builder.build()); } } 

AndroidManifest.xml中

  <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.demo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" /> <application android:allowBackup="true" android:icon="@drawable/dac_logo" android:label="@string/app_name" > <activity android:name=".MainActivity" android:excludeFromRecents="true" android:label="@string/app_name" android:launchMode="singleTask" android:taskAffinity="" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".GeofenceIntentService" android:exported="false" /> <receiver android:name="com.location.demo.receivers.BootCompleteReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> </application> 

Solutions Collecting From Web of "如何在Android中使Geo Fencing警报更加准确"

我发现GeoFencing从不智能地从GPS硬件中检索位置。 GeoFence API将从操作系统观察到最准确的位置,或者如果没有最近的位置读数可用,它将导致从Wifi / Cellular计算位置。 (这很吸引人,因为蜂窝是非常不准确的,而wifi通常是不可用的)

因此,为了从Geofencing API中获得所有响应或准确的结果,您必须设置Geofences,然后每隔一段时间轮询GPS硬件,甚至不要对收到的结果进行任何处理,以便在表面之下提供有价值的数据到操作系统。

这可能是你的结果不准确的核心。 地理围栏出口不会触发,直到操作系统确定你在围栏外100% – 所以如果一个位置读数的准确度为500米(在使用单元格地理定位时不是不可能),而你的围栏半径为50米, d必须距离围栏点至less550米才能产生退出事件。

TLDR; 每隔一段时间轮询GPS硬件而不做任何处理,您将开始获得更准确的地理围栏。

Android的本地geofencing是令人震惊的不准确和电池密集型。 我build议你使用像Bluedot的Point SDK (精确到10米/ 30英尺)或Gimbal的SDK (精确到50米/ 165英尺)的第三方工具,两者都更加可靠,电池消耗更less。

充分披露:我为Bluedot工作。

我总结了几个关于Android中的Geofencing的StackOverflow线程的最佳实践, 在Github的一个名为Geofencer的示例项目中 。 这可以被用来作为参考来实现GeoFencing到你的应用程序中。 它还允许即时切换到第三方GeoFencing实施。 我希望这对你们中的一些人有帮助!

我也遇到了地理围栏系统出入我的地理围栏的问题,然后我读了这个(官方文档引用):

您的地理围栏内没有可靠的networking连接。 如果没有可靠的数据连接,则可能不会生成警报。 这是因为地理围栏服务取决于networking位置提供者,而这又需要数据连接。

从官方地理围栏文件

如果che设备没有连接到互联网谷歌播放服务(如geofence或activityrecognition)不起作用。