Получите информацию о датчике сердечного ритма от WearOS (износ Android) на мобильное устройство через Google Fit.

Моя проблема: я хочу, чтобы данные о сердечном ритме с датчика на моем устройстве Android Wear отправлялись в приложение Android Phone с помощью Google Fit API.

У меня есть Huawei Watch 2 (носимые устройства) и Samsung Galaxy S7 (телефон), которые подключены через приложение WearOS и сопряжены через Bluetooth.

Это почти то же самое, что заданный вопрос здесь , но в моем случае у него нет полезного ответа. К тому же это звучит очевидно.

Что я пробовал до сих пор:

  1. Запустите код на странице датчиков Google Fit здесь на телефоне. Результат: показывает только встроенный датчик ЧСС на задней панели телефона.
  2. Запустите код на странице датчиков Google Fit здесь на носимом устройстве. Результат: E/GoogleFitSensor: failed com.google.android.gms.common.api.ApiException: 17: API: Fitness.SENSORS_CLIENT недоступен на этом устройстве.
  3. Создайте программный датчик, используя код, описанный здесь, Fitness.SensorClient на телефон не может найти услугу на носимом устройстве. Глядя на логарифм носимых устройств, сервис никогда не создается. Я подозреваю, что намерения не работают на разных устройствах.

На странице датчиков Google Fit указано, что они могут перечислять источники данных на устройстве И на сопутствующих устройствах. Что подтверждается следующей картинкой: Google Fit на Android

Я посмотрел на эти вопросы, но не могу найти подходящий ответ.

Код:

public class GoogleFitSensor {

    private Activity mActivity;
    private DataType mRequestedDatatype;
    private int mRequestedDataSource;
    private static final String LOG_TAG = "GoogleFitSensor";
    private static final int GOOGLE_FIT_PERMISSIONS_REQUEST_CODE = 1123;
    private OnSensorResultInterface mOnSensorResultInterface;

    /**
     * Object that handles the connection with google fit devices.
     * @param mActivity The activity from which the requests are called.
     * @param requestedDatatype The requested Datatype (ex. DataType.TYPE_HEART_RATE_BPM)
     * @param requestedDataSource The requested Data Source (ex. DataSource.TYPE_RAW)
     */
    public GoogleFitSensor(Activity mActivity, DataType requestedDatatype, int requestedDataSource, @Nullable OnSensorResultInterface onSensorResultInterface ) {
        this.mActivity = mActivity;
        this.mRequestedDatatype = requestedDatatype;
        this.mOnSensorResultInterface = onSensorResultInterface;
        this.mRequestedDataSource = requestedDataSource;
    }


    public void connectToGoogleFit(){
        FitnessOptions fitnessOptions = FitnessOptions.builder()
                .addDataType(DataType.TYPE_HEART_RATE_BPM)
                .build();

        if (!GoogleSignIn.hasPermissions(GoogleSignIn.getLastSignedInAccount(mActivity), fitnessOptions)) {
            GoogleSignIn.requestPermissions(
                    mActivity, // your mActivity
                    GOOGLE_FIT_PERMISSIONS_REQUEST_CODE,
                    GoogleSignIn.getLastSignedInAccount(mActivity),
                    fitnessOptions);
        } else {
            Dexter.withActivity(mActivity).withPermission("android.permission.BODY_SENSORS").withListener(new PermissionListener() {
                @Override
                public void onPermissionGranted(PermissionGrantedResponse response) {
                    findSensorAndAddListener(mRequestedDatatype, mRequestedDataSource);
                }

                @Override
                public void onPermissionDenied(PermissionDeniedResponse response) {
                    Log.d(LOG_TAG, "Permission Denied.");
                }

                @Override
                public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
                    Log.d(LOG_TAG, "Permission Denied, rationale should be shown.");
                    token.continuePermissionRequest();
                }
            }).check();
        }
    }

    private void findSensorAndAddListener(final DataType dataType, int dataSource) {
        Fitness.getSensorsClient(mActivity, GoogleSignIn.getLastSignedInAccount(mActivity))
                .findDataSources(
                        new DataSourcesRequest.Builder()
                                .setDataTypes(dataType)
                                .setDataSourceTypes(dataSource)
                                .build())
                .addOnSuccessListener(
                        new OnSuccessListener<List<DataSource>>() {
                            @Override
                            public void onSuccess(List<DataSource> dataSources) {
                                for (DataSource dataSource : dataSources) {
                                    Log.i(LOG_TAG, "Data source found: " + dataSource.toString());
                                    Log.i(LOG_TAG, "Data Source type: " + dataSource.getDataType().getName());

                                    // Let's register a listener to receive Activity data!
                                    if (dataSource.getDataType().equals(dataType)) {

                                        Log.i(LOG_TAG, "Data source for HEART RATE found!  Registering.");
                                        registerFitnessDataListener(dataSource, dataType);
                                    }
                                }
                            }
                        })
                .addOnFailureListener(
                        new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Log.e(LOG_TAG, "failed", e);
                            }
                        });
    }

    private void registerFitnessDataListener(DataSource dataSource, DataType type) {
        Fitness.getSensorsClient(mActivity, GoogleSignIn.getLastSignedInAccount(mActivity))
                .add(
                        new SensorRequest.Builder()
                                .setDataSource(dataSource) // Optional but recommended for custom data sets.
                                .setDataType(type) // Can't be omitted.
                                .setSamplingRate(1, TimeUnit.SECONDS)
                                .build(),
                        new OnDataPointListener() {
                            @Override
                            public void onDataPoint(DataPoint dataPoint) {
                                for (Field field : dataPoint.getDataType().getFields()) {
                                    if (mOnSensorResultInterface != null){
                                        mOnSensorResultInterface.onNewResult(dataPoint.getValue(field));
                                    }
                                    Value val = dataPoint.getValue(field);
                                    Log.i(LOG_TAG, "Detected DataPoint field: " + field.getName());
                                    Log.i(LOG_TAG, "Detected DataPoint value: " + val);
                                }
                            }
                        })
                .addOnCompleteListener(
                        new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                if (task.isSuccessful()) {
                                    Log.i(LOG_TAG, "Listener registered!");
                                } else {
                                    Log.e(LOG_TAG, "Listener not registered.", task.getException());
                                }
                            }
                        });
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == GOOGLE_FIT_PERMISSIONS_REQUEST_CODE) {
                findSensorAndAddListener(mRequestedDatatype, mRequestedDataSource);
                }
            }
        }
}

Что мне не хватает? Заранее спасибо!


person genie137    schedule 04.04.2018    source источник
comment
Имея ту же проблему. Все еще выясняю, как это решить, но я думаю, что вот ключ - вам нужно подключиться к Sensors Client - developers.google.com/android/reference/com/google/android/gms/   -  person Георги Ангелов    schedule 09.04.2018
comment
@GeorgiAngelov Я использую SensorsClient, вызывая Fitness.getSensorsClient() в моем методе findSensorsAndAddListener. Все равно не повезло.   -  person genie137    schedule 10.04.2018
comment
Вы когда-нибудь находили решение для этого?   -  person Ben De La Haye    schedule 07.06.2018
comment
Нет, к сожалению, нет. В итоге я использовал клиенты данных/сообщений носимого API и собирал информацию через Sensor Manager. Я все еще хочу знать, если / как это работает, хотя   -  person genie137    schedule 08.06.2018