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

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

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

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

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

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

На странице Google Fit Sensors указывается, что она может перечислять источники данных на устройстве И на сопутствующих устройствах. Что подтверждается следующей картинкой: Google Fit On 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);
                }
            }
        }
}

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

0 ответов

Другие вопросы по тегам