3

My app doesn't find the DataSource associated with the SmartBand 2 bracelet step counter sensor, but if it finds the heart rate sensor y updates events in the onDatapoint method, what could be the problem? I try with

My code is as follows:

    mApiClient = new GoogleApiClient.Builder(this)
            .addApi(Fitness.SENSORS_API)
            .addApi(Fitness.BLE_API)
            .addApi(Fitness.HISTORY_API)
            .addApi(Fitness.RECORDING_API)
            .addScope(new Scope(Scopes.FITNESS_BODY_READ))
            .addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE))
            .addScope(new Scope(Scopes.FITNESS_LOCATION_READ))
            .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();




public void bleScan() {

   final BleScanCallback bleScanCallback = new BleScanCallback() {
        @Override
        public void onDeviceFound(BleDevice device) {
            Log.d(TAG, "BLE Device Found: " + device.getName()+ "MAC Address : " +device.getAddress());
            List<String> profilesSupported= device.getSupportedProfiles();
            for (String profile: profilesSupported)
            {
                Log.d(TAG,"Perfil Soportado : "+profile);
            }
            List<DataType> dataTypes= device.getDataTypes();
            for (DataType dataType: dataTypes)
            {
                Log.d(TAG,"Perfil Soportado : "+dataType);
            }
            //unClaimDevice(device);
            //stopBleScan();//Detener el escaneo de dispositivos
            claimDevice(device);//Bind
        }
        @Override
        public void onScanStopped() {
            Log.d(TAG, "BLE scan stopped");
        }
    };

    StartBleScanRequest request = new StartBleScanRequest.Builder()
            .setTimeoutSecs(60)
            //.setDataTypes(DataType.TYPE_STEP_COUNT_DELTA)
            .setDataTypes(DataType.TYPE_STEP_COUNT_DELTA,DataType.TYPE_HEART_RATE_BPM,DataType.TYPE_ACTIVITY_SAMPLES)
            .setBleScanCallback(bleScanCallback)
            .build();

    Log.d(TAG,"LLAMADA A bleScan");
    PendingResult<Status> result = Fitness.BleApi.startBleScan(mApiClient, request);
    result.setResultCallback(new ResultCallback<Status>() {
        @Override
        public void onResult(Status status) {
            if (!status.isSuccess()) {
                switch (status.getStatusCode()) {
                    case FitnessStatusCodes.DISABLED_BLUETOOTH:
                        Log.d(TAG, "DISABLED_BLUETOOTH");
                    try {
                        status.startResolutionForResult(MainActivity.this, REQUEST_BLUETOOTH);
                    } catch (IntentSender.SendIntentException e) {
                        Log.d(TAG, "SendIntentException: " + e.getMessage());
                    }
                    break;
                }
                Log.d(TAG, "BLE scan unsuccessful");
            } else {
                Log.d(TAG, "ble scan status message: " + status.describeContents());
                Log.d(TAG, "BLE scan successful: " + status.toString());
            }
        }
    });
}

public void claimDevice(BleDevice device) {

    boolean success = false;
    mBleDevice=device;
    stopBleScan();

    //Claim device
    PendingResult<Status> pendingResult = Fitness.BleApi.claimBleDevice(mApiClient, device);
    pendingResult.setResultCallback(new ResultCallback<Status>() {
        @Override
        public void onResult(Status st) {
            if (st.isSuccess()) {
                Log.d(TAG, "Claimed device successfully");
                //dataSourceCall();
            } else {
                Log.d(TAG, "Did not successfully claim device");
            }
        }
    });
}

private void dataSourceCall()
{
    DataSourcesRequest dataSourceRequest = new DataSourcesRequest.Builder()
            .setDataTypes(DataType.TYPE_HEART_RATE_BPM,DataType.TYPE_STEP_COUNT_DELTA)//añadido
            .setDataSourceTypes( DataSource.TYPE_RAW,DataSource.TYPE_DERIVED )
            .build();

    ResultCallback<DataSourcesResult> dataSourcesResultCallback = new ResultCallback<DataSourcesResult>() {
        @Override
        public void onResult(DataSourcesResult dataSourcesResult) {

            for( DataSource dataSource : dataSourcesResult.getDataSources() ) {
                Log.d(TAG,"TOTAL SOURCE : " +dataSource.toString());
                if( DataType.TYPE_HEART_RATE_BPM.equals( dataSource.getDataType() ) ) {
                    registerFitnessDataListener(dataSource, DataType.TYPE_HEART_RATE_BPM);
                    Log.d(TAG,"DATOS HEART RATE BPM : Nombre data source : " + dataSource.getName() +"\nDevice : "+ dataSource.toString());//.getManufacturer() + "Device Model : " +  dataSource.getDevice().getModel());
                }else if (DataType.TYPE_STEP_COUNT_DELTA.equals( dataSource.getDataType()))
                {
                    registerFitnessDataListener(dataSource, DataType.TYPE_STEP_COUNT_DELTA);
                    Log.d(TAG,"DATOS PASOS ACUMULATIVOS : Nombre data source : " + dataSource.getName() +"\nDevice : "+ dataSource.toString());//.getManufacturer() + "Device Model : " +  dataSource.getDevice().getModel());
                }else if (DataType.TYPE_STEP_COUNT_CUMULATIVE.equals( dataSource.getDataType() ))
                {
                    registerFitnessDataListener(dataSource, DataType.TYPE_STEP_COUNT_CUMULATIVE);
                    Log.d(TAG,"DATOS PASOS ADICIONALES : Nombre data source : " + dataSource.getName() +"\nDevice : "+ dataSource.toString());//.getManufacturer() + "Device Model : " +  dataSource.getDevice().getModel());
                }
            }
        }
    };

    Fitness.SensorsApi.findDataSources(mApiClient, dataSourceRequest)
            .setResultCallback(dataSourcesResultCallback);

    suscribeDataFitness();
}

private void registerFitnessDataListener(DataSource dataSource, DataType dataType) {

    final SensorRequest request = new SensorRequest.Builder()
            .setDataSource( dataSource )
            .setDataType( dataType )
            .setSamplingRate( 10, TimeUnit.SECONDS )
            .build();

    Fitness.SensorsApi.add( mApiClient, request, this )
            .setResultCallback(new ResultCallback<Status>() {
                @Override
                public void onResult(Status status) {
                    if (status.isSuccess()) {
                        Log.d(TAG, "GoogleFit SensorApi successfully added - "+request.getDataType() );
                    }
                }
            });

    //Device m =dataSource.getDevice();
    //Log.d(TAG,"Device " + m.toString());
}

Here are the DataSources available for my application:

DataSource{raw:SWR12:Device{SoMC Inc:SWR12:BC:6E:64:FC:13:92::0:1}:SWR12:DataType{com.google.heart_rate.bpm[bpm(f)]}}
DataSource{raw:Generic ANT+ Sensor:Application{com.dsi.ant.plugins.antplus::}:AntPlus.0.120:DataType{com.google.heart_rate.bpm[bpm(f)]}}
DataSource{derived:Application{com.google.android.gms::null}:Device{samsung:SM-N915FY:e6a8bfd5::1:2}:live_step_deltas:DataType{com.google.step_count.delta[steps(i)]}}
DataSource{raw:Device{samsung:SM-N915FY:e6a8bfd5::1:2}:HeartRate Sensor:DataType{com.google.heart_rate.bpm[bpm(f)]}}
DataSource{raw:Generic ANT+ Sensor:Application{com.dsi.ant.plugins.antplus::}:AntPlus.0.124:DataType{com.google.step_count.delta[steps(i)]}}

BLE Device Found: SWR12 MAC Address : BC:6E:64:FC:13:92
Profile Supported: org.bluetooth.profile.heart_rate
Profile Supported : DataType{com.google.heart_rate.bpm[bpm(f)]}

This would be the way to store and read data with Recording_Api and History_Api:

private void suscribeDataFitness(){
    Fitness.RecordingApi.subscribe(mApiClient, DataType.AGGREGATE_HEART_RATE_SUMMARY)
            .setResultCallback(mSubscribeResultCallback);
    Fitness.RecordingApi.subscribe(mApiClient, DataType.TYPE_HEART_RATE_BPM)
            .setResultCallback(mSubscribeResultCallback);
    Fitness.RecordingApi.subscribe(mApiClient, DataType.TYPE_STEP_COUNT_DELTA)
            .setResultCallback(mSubscribeResultCallback);

}


private void readDataFitnessHistory()
{
    // Setting a start and end date using a range of 1 week before this moment.
    Calendar cal = Calendar.getInstance();
    Date now = new Date();
    cal.setTime(now);
    long endTime = cal.getTimeInMillis();

    cal.add(Calendar.DAY_OF_YEAR, -1);
    long startTime = cal.getTimeInMillis();

    java.text.DateFormat dateFormat = getDateInstance();
    Log.d(TAG, "Range Start: " + dateFormat.format(startTime) + " Millis : " + startTime);
    Log.d(TAG, "Range End: " + dateFormat.format(endTime)  + " Millis : " + endTime);

    DataSource ESTIMATED_STEP_DELTAS = new DataSource.Builder()
            .setDataType(DataType.TYPE_STEP_COUNT_DELTA)
            .setType(DataSource.TYPE_DERIVED)
            .setStreamName("estimated_steps")
            .setAppPackageName("com.google.android.gms")
            .build();

    final DataReadRequest readRequest = new DataReadRequest.Builder()

            .read(DataType.TYPE_HEART_RATE_BPM)
            .read(ESTIMATED_STEP_DELTAS)
            .enableServerQueries()
            .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
            .bucketByTime(1, TimeUnit.HOURS)
            .build();


    // Invoke the History API to fetch the data with the query and await the result of
    // the read request.
    DataReadResult dataReadResult =
            Fitness.HistoryApi.readData(mApiClient, readRequest).await(1, TimeUnit.MINUTES);
    DataSet dataSetBPM = dataReadResult.getDataSet(DataType.TYPE_HEART_RATE_BPM);
    DataSet dataSetSteps = dataReadResult.getDataSet(DataType.TYPE_STEP_COUNT_DELTA);
    DataSet dataSetActivity = dataReadResult.getDataSet(DataType.TYPE_ACTIVITY_SAMPLES);
    showDataSet(dataSetBPM);
    showDataSet(dataSetSteps);

}

Thank you in advance.

ja12
  • 351
  • 2
  • 16
  • You might want to read this related [SO post](https://stackoverflow.com/a/39774258/5995040), this will help you re-evaluate your code if it allows your app to sync with data from other devices, and also allows for the passive recording of data on the device. First, you need to read data from the fitness history by [creating a subscription](https://developers.google.com/fit/android/record#subscribe_to_fitness_data) for each fitness data type you'd like to record. Then use `DataReadRequest` (for reading data from Google Fit) instance. – Mr.Rebot Oct 03 '17 at 16:09
  • You can also try the code in the documentation to familiarize your self of the features and functionalities. Hope this helps. – Mr.Rebot Oct 03 '17 at 16:09
  • I already have a subscription (Recording API) implemented in my code and I read with the History API, but I don't register the step counter, since the only datatype associated with SmartBand 2 is com.google.heart_rate.bpm. And I don't know why. The documentation on the wristband reads as follows: "... SmartBand 2 provides the following Public data types to the Google Fitness Store: google.step_count.delta (steps) google.heart_rate.bpm (heart rate in bpm) google.activity.segment (sleeping, walking, running) ..." – ja12 Oct 04 '17 at 06:40

0 Answers0