Android Studio中如何在onResume生命周期回调中获取步数而非onSensorChanged方法中?
在onResume中获取步数而非onSensorChanged的实现方案
没问题,我来帮你搞定这个需求!要在onResume生命周期回调里直接获取步数,而不是依赖onSensorChanged的实时回调,核心是利用Android原生的**计步器传感器(TYPE_STEP_COUNTER)**的累计特性——它会返回设备开机以来的总步数,我们只需要在onResume时临时注册传感器监听器,拿到数据后立即注销就好。下面是具体的实现步骤和代码示例:
1. 先处理权限声明
首先要在AndroidManifest.xml里添加必要的权限,不同Android版本要求不一样:
<!-- Android 9(API 28)及以下版本需要 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Android 10(API 29)及以上版本需要 --> <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
2. 初始化传感器相关对象
在Activity的onCreate方法里初始化传感器管理器和计步传感器,同时定义一个只执行一次的监听器——拿到步数就注销自己:
private SensorManager sensorManager; private Sensor stepCounterSensor; private SensorEventListener stepCounterListener; private long totalStepCount = 0; // 存储累计步数 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取系统传感器服务 sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); // 获取计步器传感器 stepCounterSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER); // 初始化监听器:只获取一次步数就注销 stepCounterListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_STEP_COUNTER) { // 拿到设备开机以来的累计步数 totalStepCount = (long) event.values[0]; Log.d("StepTracker", "当前累计步数:" + totalStepCount); // 完成获取后立即注销监听器,避免不必要的资源消耗 sensorManager.unregisterListener(this); // 这里可以把步数展示到UI上,比如更新TextView // textView.setText("累计步数:" + totalStepCount); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // 精度变化的处理,一般不需要额外操作 } }; }
3. 在onResume中注册监听器获取步数
每次Activity回到前台(onResume触发)时,我们检查权限,然后注册监听器——因为监听器拿到数据就会注销,所以每次onResume都会触发一次步数获取:
@Override protected void onResume() { super.onResume(); // 检查权限是否已授予 boolean hasPermission = false; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { hasPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_GRANTED; } else { hasPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED; } if (hasPermission) { if (stepCounterSensor != null) { // 注册监听器,使用UI延迟级别即可,不需要高频更新 sensorManager.registerListener(stepCounterListener, stepCounterSensor, SensorManager.SENSOR_DELAY_UI); } else { // 设备不支持计步传感器 Toast.makeText(this, "当前设备不支持计步功能", Toast.LENGTH_SHORT).show(); } } else { // 申请必要的权限 String[] permissions = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ? new String[]{Manifest.permission.ACTIVITY_RECOGNITION} : new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}; ActivityCompat.requestPermissions(this, permissions, 1001); } }
4. 处理权限申请结果
用户授权后,我们需要再次注册监听器来获取步数:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 1001) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限通过,立即注册监听器获取步数 if (stepCounterSensor != null) { sensorManager.registerListener(stepCounterListener, stepCounterSensor, SensorManager.SENSOR_DELAY_UI); } } else { Toast.makeText(this, "需要授予权限才能获取步数", Toast.LENGTH_SHORT).show(); } } }
额外说明
TYPE_STEP_COUNTER返回的是设备开机以来的总步数,如果需要统计应用启动后的步数,可以在第一次获取时保存初始值,之后每次onResume拿到的步数减去初始值就是增量。- 如果设备不支持
TYPE_STEP_COUNTER,可以考虑使用TYPE_STEP_DETECTOR,但它只能检测每一步的动作,需要自己累计步数,这种方式就没法在onResume直接获取历史步数了。 - 如果你需要更精准的历史步数或者跨设备同步的功能,可以考虑集成Google Fit API,但这需要依赖Google服务框架,适合有更高需求的场景。
内容的提问来源于stack exchange,提问作者Stefano
相关产品推荐
相关产品推荐

