Android: Как получить данные Google Fit с носимого устройства?
Я следую тем же шагам, описанным здесь (часть подключения клиента 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());
}
}
});
когда я прошу источники данных, я получаю только один результат, который является смартфоном. Если я добавляю слушателя, я действительно получаю данные, поэтому он работает.
однако он также подключен к Android Wear smartwatch Gear Live с приложением Android Wear на телефоне. Google Fit установлен в обоих из них, но я хотел бы получить данные из умные часы.
в официальном руководстве я прочитал
API датчиков обеспечивает доступ к сырцовым потокам данных датчика от доступные датчики на устройстве Android и с датчиков доступных в сопутствующие устройства, такие как носимые.
этот код работает на смартфоне, поэтому я думаю, что было бы правильно ожидать источников данных от companion smartwatch тоже. Но это как невидимый для моего приложения телефона. Я делаю что-то не так?
EDIT:
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: nt" + dataSource.toString() + "ntType: " + 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);
}
}
}
};
}
1 ответов
Я не пробовал ничего из этого.
похоже, что датчики Samsung Gear Live не поддерживаются из коробки, но вы можете заставить его работать через датчики программного обеспечения:
Ваш Gear Live
как говорится в это так ответ,
Samsung Gear Live watch не рекламирует себя как BLE сердце монитор скорости и поэтому не делает сердце данные по тарифа доступно через обычный Bluetooth API низкой энергии или Google Fit API, который построен на нем.
Поддерживаемые Датчики
как говорится в официальные документы,
Google Fit включает в себя поддержку датчиков на мобильном устройстве и Bluetooth датчики низкой энергии в паре с устройством. Google Fit позволяет разработчики реализуют поддержку других датчиков и выставляют их как программное обеспечение датчики в Приложения для Android. Датчики, поддерживаемые Google Fit доступно для приложений Android в качестве объектов источника данных.
возможно решение
представляется возможным внедрение дополнительных программных датчиков.
(скопированный шаблон для этого находится в нижней части сообщения, потому что он длинный).
вы получите данные о носимом следующем get-heart-rate-from-sensor-samsung-gear-live.
шаблон (от 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>
и плоть этого Service
out:
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 } }