I want to add step counter to my app.
By now I'm using Google fit
to measure user step count.
The problems I'm facing with is that not all devices has Google Fit
app installed, and even if does - not all users register to app service (as client).
So the desired flow is:
Google fit
app is installed.Google fit
app.Google fit
app, check if user account type support's using fitness services. (recording data such as steps)Basically I want to check if the user using fit app (using all the conditions above), if one fails then it will use the StepCount sensor on device (if exists), If sensor doesn't exist it will use the other sensors the achieve this goal.
Here is the code that I'm using to connect with Google Fit API:
private void buildFitnessClient() {
// Create the Google API Client
mClient = new GoogleApiClient.Builder(getContext())
.addApi(Fitness.HISTORY_API)
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ))
.addConnectionCallbacks(
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.
new getFitnessTask().execute();
}
@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");
}
}
}
)
.addOnConnectionFailedListener(
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
if (getActivity() != null) {
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
getActivity(), 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; activity; "+ getActivity());
if (getActivity() != null) {
authInProgress = true;
result.startResolutionForResult(getActivity(),
REQUEST_OAUTH);
}
} catch (IntentSender.SendIntentException e) {
Log.e(TAG,
"Exception while starting resolution activity", e);
}
}
}
}
)
.build();
}
public void onActivityResult(int requestCode, int resultCode, Intent data){
Log.e(TAG, "onActivityResult requestCode=" + requestCode + ", resultCode=" + resultCode);
if (requestCode == REQUEST_OAUTH) {
authInProgress = false;
if (resultCode == Activity.RESULT_OK) {
Log.e(TAG, "RESULT_OK");
// Make sure the app is not already connected or attempting to connect
if (!mClient.isConnecting() && !mClient.isConnected()) {
mClient.connect();
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Log.e(TAG, "RESULT_CANCELED");
}
}
}
private class getFitnessTask extends AsyncTask<Void, Void, Integer> {
...
}
}
Need your help guys,
Thanks.
You can call getPackageInfo()
on the PackageManager
. If it throws a PackageManager.NameNotFoundException
it means that the app is not installed. If it doesn't throw an exception, google fit is installed
fun fitInstalled(context: Context): Boolean {
val fitPackage = "com.google.android.apps.fitness"
return try {
if (Build.VERSION.SDK_INT >= 33) {
context.packageManager.getPackageInfo(
fitPackage,
PackageManager.PackageInfoFlags.of(PackageManager.GET_ACTIVITIES.toLong())
)
} else {
@Suppress("DEPRECATION")
context.packageManager.getPackageInfo(
fitPackage,
PackageManager.GET_ACTIVITIES
)
}
true
} catch (e: PackageManager.NameNotFoundException) {
false
}
}
Additionally if you target Android 11+, you need to tell Android that you are querying the fit package in your AndroidManifest.xml
:
<manifest ...>
...
<queries>
<package android:name="com.google.android.apps.fitness" />
</queries>
</manifest>
here is kotlin version
fun checkIfFitInstalled(): Boolean {
try {
applicationContext.packageManager.getPackageInfo("com.google.android.apps.fitness", PackageManager.GET_ACTIVITIES)
return true
} catch (e: Exception) {
return false
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With