Android Wear OS后台获取计步数据服务息屏后停止运行问题求助
问题根因
- 你使用的是普通后台Service,Android 8.0及以上系统对普通后台Service有严格的生命周期限制,应用退到后台后会被系统快速回收,穿戴设备的省电策略比手机更严格,30秒左右被终止属于正常现象。
- 代码存在严重崩溃隐患:Service中声明的
TextView mTextView从未初始化,onSensorChanged中直接调用setText会触发空指针异常,直接导致Service崩溃退出。 - 没有申请特殊权限对抗系统省电策略:Wear OS息屏后会进入低功耗模式,默认禁止非白名单应用的后台传感器监听、网络请求,即使Service存活也无法正常运行。
- 传感器注册逻辑存在错误:你判断心率传感器存在后,硬编码注册了自定义类型
69680的传感器,一旦传感器类型不匹配,注册失败就无法拿到数据。
修复方案
1. 将普通Service改为前台服务
前台服务会在通知栏显示常驻通知,获得更高的系统优先级,避免被随便回收。
首先在AndroidManifest.xml添加权限:
<!-- 前台服务基础权限 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- Android 12及以上健康相关前台服务权限 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_HEALTH" /> <!-- 通知权限 --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
然后在MyService.java的onStartCommand中添加启动前台服务的代码:
@Override public int onStartCommand(Intent intent, int flags, int startId) { // 先创建通知渠道(Android 8.0及以上要求) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel("step_service_channel", "计步服务", NotificationManager.IMPORTANCE_LOW); NotificationManager manager = getSystemService(NotificationManager.class); manager.createNotificationChannel(channel); } // 构建通知 Notification notification = new NotificationCompat.Builder(this, "step_service_channel") .setContentTitle("计步服务运行中") .setContentText("正在同步运动数据") .setSmallIcon(R.mipmap.ic_launcher) // 替换为你应用的图标 .build(); // 启动前台服务,id不能为0 startForeground(1001, notification); // 原有传感器逻辑,添加容错判断 mSensorManager = (SensorManager)this.getSystemService(Context.SENSOR_SERVICE); mSensor = mSensorManager.getDefaultSensor(69680); if(mSensor != null) { isSensorPresent = true; mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL); } else { isSensorPresent = false; stopSelf(); } return START_STICKY; }
2. 删除Service中无效的UI操作逻辑
Service不能直接操作Activity的UI控件,删除所有和mTextView相关的代码,onSensorChanged修改为:
@Override public void onSensorChanged(SensorEvent event) { HelloData = String.valueOf(event.values[0]); if(!HelloData.contains("0.0")){ postDataUsingVolley(HelloData); } }
如果需要同步数据到前台页面显示,可以用广播、EventBus等组件传递数据给Activity。
3. 申请忽略电池优化权限
在AndroidManifest.xml添加权限:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
在MainActivity中添加代码请求用户授权:
// 在onCreate中调用 private void requestBatteryOptimization() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); if (!pm.isIgnoringBatteryOptimizations(getPackageName())) { Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); intent.setData(Uri.parse("package:" + getPackageName())); startActivity(intent); } } }
4. 其他适配
- 添加唤醒锁权限,避免网络请求时CPU休眠导致请求失败:
<uses-permission android:name="android.permission.WAKE_LOCK" />
- 进入手表系统设置,找到你的应用,开启「后台活动」「始终允许传感器访问」权限。
内容的提问来源于stack exchange,提问作者Bharat Paudyal
相关产品推荐
相关产品推荐

