Android:如何从可穿戴设备获取Google Fit数据?

use*_*180 18 android android-sensors google-fit-sdk google-fit wear-os

我遵循此处描述的相同步骤 (Google Fit客户端连接部分工作正常).

    final DataType dataType=TYPE_STEP_COUNT_DELTA;
    DataSourcesRequest requestData = new DataSourcesRequest.Builder()
            .setDataTypes(dataType)  // At least one datatype must be specified.
            .build();
    Fitness.SensorsApi.findDataSources(mClient, requestData)
            .setResultCallback(new ResultCallback<DataSourcesResult>() {
                @Override
                public void onResult(DataSourcesResult dataSourcesResult) {
                    Log.i(TAG, "Result: " + dataSourcesResult.getDataSources().size() + " sources "
                            + dataSourcesResult.getStatus().toString());
                    for (DataSource dataSource : dataSourcesResult.getDataSources()) {
                        Log.i(TAG, "Data source found: " + dataSource.toString());
                        Log.i(TAG, "Data Source type: " + dataSource.getDataType().getName());
                    }
                }
            });
Run Code Online (Sandbox Code Playgroud)

当我要求数据源时,我只得到一个结果就是智能手机.如果我添加一个监听器,那么我真的得到数据,所以它正在工作.

不过它也可以通过手机与Android Wear智能手表Gear Live和Android Wear应用程序连接.Google Fit已安装在两者中,但我想从智能手表获取数据.

在我阅读的官方指南中

Sensors API提供对Android设备上可用传感器以及可穿戴设备等配套设备中可用传感器的原始传感器数据流的访问 .

这段代码在智能手机上运行,​​所以我认为从同伴智能手表中获取数据源是正确的.但它就像我的手机应用程序看不见.难道我做错了什么?

编辑:

public class MainActivity extends AppCompatActivity {

private final static String TAG = "main_mobile";
private static final int REQUEST_OAUTH = 1;
private final static String DATE_FORMAT = "yyyy.MM.dd HH:mm:ss";
private static final String AUTH_PENDING = "auth_state_pending";
private boolean authInProgress = false;

private GoogleApiClient mClient = null;
private final static DataType dataType = TYPE_STEP_COUNT_DELTA;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState != null) {
        authInProgress = savedInstanceState.getBoolean(AUTH_PENDING);
    }
    mClient = new GoogleApiClient.Builder(this)
            .addApi(Fitness.SENSORS_API)
            .addApi(Fitness.RECORDING_API)
            .addApi(Fitness.HISTORY_API)
            .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
            .addConnectionCallbacks(connectionCallbacks)
            .addOnConnectionFailedListener(connectionFailCallbacks)
            .build();
}

private void initFitness() {
    DataSourcesRequest requestData = new DataSourcesRequest.Builder()
            .setDataTypes(dataType)
            .build();
    Fitness.SensorsApi.findDataSources(mClient, requestData)
            .setResultCallback(new ResultCallback<DataSourcesResult>() {
                @Override
                public void onResult(DataSourcesResult dataSourcesResult) {
                    Log.i(TAG, "Result: " + dataSourcesResult.getDataSources().size() + " sources " + dataSourcesResult.getStatus().toString());
                    for (DataSource dataSource : dataSourcesResult.getDataSources()) {
                        Log.i(TAG, "\nData source found: \n\t" + dataSource.toString() + "\n\tType: " + dataSource.getDataType().getName());
                    }
                }
            });
}

@Override
protected void onStart() {
    super.onStart();
    Log.i(TAG, "Connecting...");
    mClient.connect();
}

@Override
protected void onStop() {
    super.onStop();
    if (mClient.isConnected()) {
        mClient.disconnect();
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(AUTH_PENDING, authInProgress);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_OAUTH) {
        authInProgress = false;
        if (resultCode == RESULT_OK) {
            // Make sure the app is not already connected or attempting to connect
            if (!mClient.isConnecting() && !mClient.isConnected()) {
                mClient.connect();
            }
        }
    }
}

GoogleApiClient.ConnectionCallbacks connectionCallbacks = new GoogleApiClient.ConnectionCallbacks() {
    @Override
    public void onConnected(Bundle bundle) {
        Log.i(TAG, "Connected!!!");
        // Now you can make calls to the Fitness APIs.
        // Put application specific code here.
        initFitness();
    }

    @Override
    public void onConnectionSuspended(int i) {
        // If your connection to the sensor gets lost at some point,
        // you'll be able to determine the reason and react to it here.
        if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
            Log.i(TAG, "Connection lost.  Cause: Network Lost.");
        } else if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
            Log.i(TAG, "Connection lost.  Reason: Service Disconnected");
        }
    }
};

GoogleApiClient.OnConnectionFailedListener connectionFailCallbacks = new GoogleApiClient.OnConnectionFailedListener() {
    // Called whenever the API client fails to connect.
    @Override
    public void onConnectionFailed(ConnectionResult result) {
        Log.i(TAG, "Connection failed. Cause: " + result.toString());
        if (!result.hasResolution()) {
            // Show the localized error dialog
            GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), MainActivity.this, 0).show();
            return;
        }
        // The failure has a resolution. Resolve it.
        // Called typically when the app is not yet authorized, and an
        // authorization dialog is displayed to the user.
        if (!authInProgress) {
            try {
                Log.i(TAG, "Attempting to resolve failed connection");
                authInProgress = true;
                result.startResolutionForResult(MainActivity.this, REQUEST_OAUTH);
            } catch (IntentSender.SendIntentException e) {
                Log.e(TAG, "Exception while starting resolution activity", e);
            }
        }
    }
};
}
Run Code Online (Sandbox Code Playgroud)

ser*_*inc 8

我没有尝试过任何这个.

好像三星Gear Live传感器不支持开箱即用,但您可以通过软件传感器使其工作:

你的装备

正如在这个SO回答中所说的,

Samsung Gear Live手表不会将自己宣传为BLE心率监测器,因此无法通过普通的蓝牙低功耗API或基于它构建的Google Fit API 提供心率数据.

支持的传感器

官方文档中所述,

Google Fit支持移动设备上的传感器和与设备配对的蓝牙低功耗传感器.Google Fit允许开发人员实施对其他传感器的支持,并将其作为Android应用中的软件传感器公开.Google Fit支持的传感器可作为数据源对象用于Android应用.

可能解决方案

似乎可以实现其他软件传感器.

(复制的模板位于帖子的底部,因为它很长).

您将获得关于可穿戴设备的数据,从传感器 - 三星 - 齿轮现场获取心率.

模板(来自https://developers.google.com/fit/android/new-sensors)

将其添加到您的清单文件:

<service android:name="com.example.MySensorService"
         android:process=":sensor">
  <intent-filter>
    <action android:name="com.google.android.gms.fitness.service.FitnessSensorService"/>
    <!-- include at least one mimeType filter for the supported data types -->
    <data android:mimeType="vnd.google.fitness.data_type/com.google.heart_rate.bpm"/>
  </intent-filter>
</service>
Run Code Online (Sandbox Code Playgroud)

并且充实了这个Service:

import com.google.android.gms.common.*;
import com.google.android.gms.common.api.*;
import com.google.android.gms.fitness.*;
import com.google.android.gms.fitness.data.*;
import com.google.android.gms.fitness.service.*;
...

public class MySensorService extends FitnessSensorService {

    @Override
    public void onCreate() {
        super.onCreate();
        // 1. Initialize your software sensor(s).
        // 2. Create DataSource representations of your software sensor(s).
        // 3. Initialize some data structure to keep track of a registration for each sensor.
    }

    @Override
    protected List<DataSource> onFindDataSources(List<DataType> dataTypes) {
        // 1. Find which of your software sensors provide the data types requested.
        // 2. Return those as a list of DataSource objects.
    }

    @Override
    protected boolean onRegister(FitnessSensorServiceRequest request) {
        // 1. Determine which sensor to register with request.getDataSource().
        // 2. If a registration for this sensor already exists, replace it with this one.
        // 3. Keep (or update) a reference to the request object.
        // 4. Configure your sensor according to the request parameters.
        // 5. When the sensor has new data, deliver it to the platform by calling
        //    request.getDispatcher().publish(List<DataPoint> dataPoints)
    }

    @Override
    protected boolean onUnregister(DataSource dataSource) {
        // 1. Configure this sensor to stop delivering data to the platform
        // 2. Discard the reference to the registration request object
    }

}
Run Code Online (Sandbox Code Playgroud)

  • ...支持不受支持的设备的库可能对社区有帮助...(提示;-)) (3认同)
  • 大概.那个说不在**stackoverflow.com/6864712/android-alarmmanager-not-waking-phone-up工作的人是@ianhanniballake,他正在"全职担任谷歌的Android开发者倡导者".这使得三个(你,另一个OP和@ian ......)对抗一个. (2认同)