Android Wear独立设备Geofence报ApiException:1000问题求助
我之前在Wear OS设备上也踩过类似的Geofence坑,结合你的代码和报错信息,咱们从几个核心方向排查和修复:
一、先明确:Android Wear独立模式是支持Geofence的
华为Watch 2 LTE搭载的是Wear OS 2.0+,官方文档明确支持独立使用Geofence功能,所以问题肯定出在代码适配或设备配置上,而非平台不支持。
二、错误码1000的常见诱因及修复方案
1. 权限缺失或适配不全
Geofence依赖后台定位权限,尤其是Android 10及以上版本,光有ACCESS_FINE_LOCATION还不够,必须申请ACCESS_BACKGROUND_LOCATION:
- 在Manifest中添加权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> - 动态请求权限(必须在Activity中完成,Service无法发起权限请求):
注意:必须等用户授予权限后,再启动你的private static final int LOCATION_PERMISSION_REQUEST_CODE = 1001; // 在MainActivity的onCreate或合适时机调用 private void requestLocationPermissions() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE); } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE); } }GeofencingService。
2. PendingIntent适配Android 12+的Flag问题
你的代码中PendingIntent.getBroadcast只用了FLAG_UPDATE_CURRENT,在Android 12及以上版本,必须明确指定FLAG_MUTABLE或FLAG_IMMUTABLE,否则会导致PendingIntent创建失败,进而触发Geofence错误:
修改getGeofencePendingIntent方法:
private PendingIntent getGeofencePendingIntent() { Intent intent = new Intent(this, GeofenceBroadcastReceiver.class); int flags; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // 若需要在BroadcastReceiver中修改Intent内容用FLAG_MUTABLE,否则用FLAG_IMMUTABLE flags = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE; } else { flags = PendingIntent.FLAG_UPDATE_CURRENT; } return PendingIntent.getBroadcast(this, 0, intent, flags); }
3. 通知渠道未创建(Android 8.0+)
你的showNofification方法没有创建通知渠道,Android 8.0+系统会拒绝显示通知,而你的GeofencingService依赖前台通知保活,系统可能会回收未显示前台通知的服务,导致Geofence无法正常工作:
在showNofification中添加渠道创建逻辑:
private void showNofification() { // 适配Android 8.0+的通知渠道 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel( "GEOFENCE_SERVICE_CHANNEL", "Geofence后台服务", NotificationManager.IMPORTANCE_LOW); mNotificationManager.createNotificationChannel(channel); } Intent appIntent = new Intent(this, MainActivity.class); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, appIntent, Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? PendingIntent.FLAG_IMMUTABLE : 0); Notification notification = new NotificationCompat.Builder(this, "GEOFENCE_SERVICE_CHANNEL") .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(getText(R.string.location_service_title)) .setContentText(getText(R.string.location_service_text)) .setLocalOnly(true) .setOngoing(true) .setContentIntent(contentIntent) .build(); mNotificationManager.notify(NOTIFICATION_ID, notification); }
4. 位置服务模式未设置为高精度
虽然你的FusedLocationClient能正常工作,但Geofence对位置精度要求更高,确保手表的位置服务模式设置为高准确度(同时使用GPS和网络定位):
可以在代码中检查并引导用户设置:
private void checkLocationMode() { LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } }
三、额外建议
- 避免无限重试:你的代码中失败后2秒重试,可能会导致频繁请求,建议添加重试次数限制(比如最多3次)。
- 检查Geofence参数:确保经纬度有效,半径不小于100米(部分设备对最小半径有要求),你的代码中设置的100米是合理的。
按照以上步骤修改后,应该能解决GEOFENCE_NOT_AVAILABLE的问题,建议先测试权限和PendingIntent的适配,这两个是最常见的诱因。
内容的提问来源于stack exchange,提问作者kevingoos

