Google Fit API : Get distance from google fit

为君一笑 提交于 2019-12-02 07:54:53

You need to add one more scope when you instantiate GoogleApiClient.Builder:

".addScope(new Scope(Scopes.FITNESS_LOCATION_READ))"

And you also need to gain Location permission by adding this permission in manifest file:

<manifet>

  ...

  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

  <aplication/>

 </manifest>

and in your activity, add this method:

public void request_location_permission() {

  // If location permission was not granted yet, request it. Otherwise, request nothing and
  // just do what you want.
  if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) !=
    PackageManager.PERMISSION_GRANTED) {

    PermissionUtils.requestPermission(this, LOCATION_PERMISSION_REQUEST_CODE,
      Manifest.permission.ACCESS_FINE_LOCATION, false);

  } else {
    process();
  }
}

PermissionUtils is my own class, you can use it to have a prompt look if you want to see a result first:

public abstract class PermissionUtils {

/**
 * Requests the fine location permission. If a rationale with an additional explanation should
 * be shown to the user, displays a dialog that triggers the request.
 */
public static void requestPermission(AppCompatActivity activity, int requestId,
                                     String permission, boolean finishActivity) {
    if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {

        // Display a dialog with rationale, this dialog wil request permission by itself.
        PermissionUtils.RationaleDialog.newInstance(requestId, finishActivity)
                .show(activity.getSupportFragmentManager(), "dialog");
    } else {

        // Location permission has not been granted yet, request it.
        ActivityCompat.requestPermissions(activity, new String[]{permission}, requestId);
    }
}

/**
 * Checks if the result contains a {@link PackageManager#PERMISSION_GRANTED} result for a
 * permission from a runtime permissions request.
 *
 * @see android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback
 */
public static boolean isPermissionGranted(String[] grantPermissions, int[] grantResults,
                                          String permission) {
    for (int i = 0; i < grantPermissions.length; i++) {
        if (permission.equals(grantPermissions[i])) {
            return grantResults[i] == PackageManager.PERMISSION_GRANTED;
        }
    }
    return false;
}

/**
 * A dialog that displays a permission denied message.
 */
public static class PermissionDeniedDialog extends DialogFragment {

    private static final String ARGUMENT_FINISH_ACTIVITY = "finish";

    private boolean mFinishActivity = false;

    /**
     * Creates a new instance of this dialog and optionally finishes the calling Activity
     * when the 'Ok' button is clicked.
     */
    public static PermissionDeniedDialog newInstance(boolean finishActivity) {
        Bundle arguments = new Bundle();
        arguments.putBoolean(ARGUMENT_FINISH_ACTIVITY, finishActivity);

        PermissionDeniedDialog dialog = new PermissionDeniedDialog();
        dialog.setArguments(arguments);
        return dialog;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        mFinishActivity = getArguments().getBoolean(ARGUMENT_FINISH_ACTIVITY);

        return new AlertDialog.Builder(getActivity())
                .setMessage(R.string.location_permission_denied)
                .setPositiveButton(android.R.string.ok, null)
                .create();
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        if (mFinishActivity) {
            Toast.makeText(getActivity(), R.string.permission_required_toast,
                    Toast.LENGTH_SHORT).show();
            getActivity().finish();
        }
    }
}

/**
 * A dialog that explains the use of the location permission and requests the necessary
 * permission.
 * <p>
 * The activity should implement
 * {@link android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback}
 * to handle permit or denial of this permission request.
 */
public static class RationaleDialog extends DialogFragment {

    private static final String ARGUMENT_PERMISSION_REQUEST_CODE = "requestCode";

    private static final String ARGUMENT_FINISH_ACTIVITY = "finish";

    private boolean mFinishActivity = false;

    /**
     * Creates a new instance of a dialog displaying the rationale for the use of the location
     * permission.
     * <p>
     * The permission is requested after clicking 'ok'.
     *
     * @param requestCode    Id of the request that is used to request the permission. It is
     *                       returned to the
     *                       {@link android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback}.
     * @param finishActivity Whether the calling Activity should be finished if the dialog is
     *                       cancelled.
     */
    public static RationaleDialog newInstance(int requestCode, boolean finishActivity) {
        Bundle arguments = new Bundle();
        arguments.putInt(ARGUMENT_PERMISSION_REQUEST_CODE, requestCode);
        arguments.putBoolean(ARGUMENT_FINISH_ACTIVITY, finishActivity);
        RationaleDialog dialog = new RationaleDialog();
        dialog.setArguments(arguments);
        return dialog;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Bundle arguments = getArguments();
        final int requestCode = arguments.getInt(ARGUMENT_PERMISSION_REQUEST_CODE);
        mFinishActivity = arguments.getBoolean(ARGUMENT_FINISH_ACTIVITY);

        return new AlertDialog.Builder(getActivity())
                .setMessage(R.string.permission_rationale_location)
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // After click on Ok, request the permission.
                        ActivityCompat.requestPermissions(getActivity(),
                                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                requestCode);
                        // Do not finish the Activity while requesting permission.
                        mFinishActivity = false;
                    }
                })
                .setNegativeButton(android.R.string.cancel, null)
                .create();
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        if (mFinishActivity) {
            Toast.makeText(getActivity(),
                    R.string.permission_required_toast,
                    Toast.LENGTH_SHORT)
                    .show();
            getActivity().finish();
        }
    }
}

This is my way to get granted Location permission from user by creating my own Rational dialog, you can do in a different way by searching how to get location permission on google.

Hope this will help,

Mttdat.

Smeet

You have to add the scope as below:

.addScope(new Scope(Scopes.FITNESS_LOCATION_READ))

Try to check the How to Record a Workout guide. After, recording your fitness data, try reading the Working with Datasets guide in order to access the com.google.distance.delta data type which is the distance covered.

Here's the Google Fit repo for actual code samples.

To get distance covered by user, use below code and let me know if any further assistance required. The below code will get current day distance. To get distance for more days we can get list of activities from where we can get distance of more days.

 private double getTodayDistance() {

        PendingResult<DailyTotalResult> result = Fitness.HistoryApi.readDailyTotal(mClient, DataType.TYPE_DISTANCE_DELTA);
        DailyTotalResult totalResult = result.await(1, TimeUnit.DAYS);
        if (totalResult.getStatus().isSuccess()) {
            DataSet totalSet = totalResult.getTotal();
            if (totalSet != null && !totalSet.isEmpty()) {
                return baseActivity.getMiles((totalSet.getDataPoints().get(0).getValue(Field.FIELD_DISTANCE)).asFloat());
            } else {
                android.util.Log.w(TAG, "There was a problem getting the calories.");
                return 0;
            }
        } else {
            return 0;
        }
    }

The answers are deprecated. With the newest api you do it like this:

Your request is fine however, you need those permissions mentioned above. You don't specify scope anymore tho.

Asking for connection:

val FITNESS_OPTIONS: FitnessOptions = FitnessOptions.builder()
        .addDataType(//any other you might need)
        .addDataType(DataType.AGGREGATE_DISTANCE_DELTA, FitnessOptions.ACCESS_READ)
        .build()

GoogleSignIn.requestPermissions(
        activity,
        YOUR_INT_AUTH_CODE_FOR_ON_ACTIVITY_RESULT,
        GoogleSignIn.getLastSignedInAccount(context),
        GoogleFit.FITNESS_OPTIONS)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!