如何实现从Galaxy Watch 4提取步数并在Android应用中展示?
问题排查与修复方案
核心问题分析
你的代码存在两个关键问题导致认证后无任何反应:
- Google登录配置与Fitness权限未关联:单独创建的
FitnessOptions未附加到GoogleSignInOptions中,登录流程未请求Google Fit的必要权限,后续API访问也会因权限缺失失效。 - 登录结果处理不完整:仅判断
resultCode == RESULT_OK,未正确解析登录返回的账户信息,也未验证Fit权限是否授予,导致后续逻辑无法触发。
修复步骤
1. 关联FitnessOptions到GoogleSignInOptions
先配置Fitness权限,再将其作为扩展添加到登录配置中,确保登录时同步请求Fit权限:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 先配置Fitness Options fitnessOptions = FitnessOptions.builder() .addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ) .addDataType(DataType.TYPE_ACTIVITY_SEGMENT, FitnessOptions.ACCESS_READ) .build(); // 配置Google Sign-In,附加Fitness权限扩展 GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .addExtension(fitnessOptions) // 关键:关联Fit权限 .build(); googleSignInClient = GoogleSignIn.getClient(this, gso); Button authButton = findViewById(R.id.auth_button); authButton.setOnClickListener(v -> signIn()); }
2. 完善登录结果处理
在onActivityResult中解析账户信息,验证权限后再执行API访问:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == GOOGLE_FIT_PERMISSIONS_REQUEST_CODE) { Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data); try { GoogleSignInAccount account = task.getResult(ApiException.class); // 检查是否已获取Fit权限 if (GoogleSignIn.hasPermissions(account, fitnessOptions)) { Toast.makeText(this, "认证成功", Toast.LENGTH_SHORT).show(); Log.d(TAG, "Authentication successful"); accessGoogleFitApi(); } else { // 未授权则重新请求权限 GoogleSignIn.requestPermissions( this, GOOGLE_FIT_PERMISSIONS_REQUEST_CODE, account, fitnessOptions); } } catch (ApiException e) { Log.d(TAG, "认证失败: " + e.getStatusCode()); Toast.makeText(this, "认证失败", Toast.LENGTH_SHORT).show(); } } }
3. 优化API访问逻辑
直接使用已登录账户,简化数据处理流程:
private void accessGoogleFitApi() { GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this); if (account == null) { Log.d(TAG, "未找到已登录账户"); return; } // 读取最近7天的步数数据,按天分组 DataReadRequest request = new DataReadRequest.Builder() .read(DataType.TYPE_STEP_COUNT_DELTA) .setTimeRange(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7), System.currentTimeMillis(), TimeUnit.MILLISECONDS) .bucketByTime(1, TimeUnit.DAYS) .build(); Fitness.getHistoryClient(this, account) .readData(request) .addOnSuccessListener(dataReadResponse -> { if (!dataReadResponse.getBuckets().isEmpty()) { for (Bucket bucket : dataReadResponse.getBuckets()) { for (DataSet dataSet : bucket.getDataSets()) { processStepData(dataSet); } } } else { for (DataSet dataSet : dataReadResponse.getDataSets()) { processStepData(dataSet); } } }) .addOnFailureListener(e -> Log.e(TAG, "读取步数失败", e)); } // 提取数据处理逻辑 private void processStepData(DataSet dataSet) { for (DataPoint dataPoint : dataSet.getDataPoints()) { int stepCount = dataPoint.getValue(Field.FIELD_STEPS).asInt(); String timeRange = dataPoint.getStartTime(TimeUnit.MILLISECONDS) + " 至 " + dataPoint.getEndTime(TimeUnit.MILLISECONDS); Log.d(TAG, "步数: " + stepCount + ",时间范围: " + timeRange); // 此处可添加UI更新代码,展示步数数据 } }
4. 补充依赖与权限
确保build.gradle(Module)中添加依赖:
dependencies { implementation 'com.google.android.gms:play-services-auth:20.7.0' implementation 'com.google.android.gms:play-services-fitness:21.1.0' }
AndroidManifest.xml中添加必要权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
额外注意事项
- 测试设备需安装Google Fit应用,且Galaxy Watch 4已同步步数数据到该应用。
- 若仍无数据返回,检查时间范围是否合理(避免使用从时间戳1开始的范围)。
- 使用已关联Galaxy Watch 4的真实Google账户进行测试。
内容的提问来源于stack exchange,提问作者kiv..
相关产品推荐
相关产品推荐

