expo: Pedometer Module: Android - watchStepCount does not update - Permission is not being requested correctly.

Summary

Expected behaviour:

Value of stepCount should increase when device is physically moved. Walking with the device in a short distance (e.g., around a 15m^2 room) should trigger the step count to update as per its subscription.

Actual behaviour:

Permission will state granted. However, stepCount will not increase. Calling Pedometer.requestPermissionAsync() will return granted.

Additional notes:

It seems like the only solution people have come up with is ejecting from Expo. I believe this is a worst-case scenario, and at the very least Expo docs should be updated to reflect incompatibility with Android.

Managed or bare workflow? If you have ios/ or android/ directories in your project, the answer is bare!

managed

What platform(s) does this occur on?

Android

SDK Version (managed workflow only)

44

Environment

Run expo start Or view through provided snack.

Reproducible demo

https://snack.expo.dev/@humaan/android-pedometer-expo-sdk44

Run this snack on your physical device, or make a new project using the code for a very simple repro.

This is the code ripped straight from the documentation (minus the styles) and removed getStepCount as it is documented as not supported.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 32 (7 by maintainers)

Commits related to this issue

Most upvoted comments

Any updates to this? Pedometer.requestPermissionsAsync() is still returning granted but Pedometer.watchStepCount() is not going up

So in short we cannot have this in managed app right ? that is a bummer . it would be nice to have Permissions like as an expo module so developers could stay in their expo go zone .

Further updates from testing, since I am using eas build over the classic expo build which gives me access to the config-plugins.

Specifically, referring to this section of the documentation, https://docs.expo.dev/guides/config-plugins/#modifying-the-androidmanifestxml

I managed to modify the AndroidManifest.xml to include the required permission tag (<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />) in the resulting Android build/package.

With that, I can now see the corresponding permission in the application settings, and manually enable it for my application. This results in the pedometer working as intended. a91d5b90-e923-48d5-bf86-60db121eeb29

However, as originally mentioned by @lqze. On the implementation level, Pedometer.requestPermissionAsync() does not seem to prompt the user for runtime permission as it should, and just returns granted even when the permission is denied on the application level.

@NicKZ-gene did you rebuild your application? If yes, I can suggest the following: check the full list of permissions for your APK file - if it does not contain android.permission.ACTIVITY_RECOGNITION and com.google.android.gms.permission.ACTIVITY_RECOGNITION, then most likely the problem lies in the plugin or how it is connected to Expo.

Ok so the solution is working fine for me (thanks @JohnBerd and @Jleeowl for the inspiration), I’m using Expo Managed SDK 46 and @expo-config-plugin. I did not make tests on a wide set of Android devices.

Create a new file where you want in your project folder architecture. I have it directly in the root folder. Name it “something.plugin.js” (I named it android-manifest.plugin.js). And fill it with this :

const { withAndroidManifest } = require('@expo/config-plugins');

module.exports = function androiManifestPlugin(config) {
  return withAndroidManifest(config, async (configProps) => {
    const androidManifest = configProps.modResults.manifest;

    androidManifest.$ = {
      ...androidManifest.$,
      'xmlns:tools': 'http://schemas.android.com/tools',
    };

    const activityPerm1 = { $: { 'android:name': 'android.permission.ACTIVITY_RECOGNITION' } };
    const activityPerm2 = { $: { 'android:name': 'com.google.android.gms.permission.ACTIVITY_RECOGNITION' } };

    androidManifest['uses-permission'].push(activityPerm1);
    androidManifest['uses-permission'].push(activityPerm2);

    return configProps;
  });
};

Finally, just add this in your app.config.js or app.json in the plugin area :

plugins: [
      './android-manifest.plugin.js',
    ],

Build your app and enjoy. You can now use following lib to check if Activity Recognition is granted or not, and if not then request it : import { PermissionsAndroid } from 'react-native'; OR import GoogleFit from 'react-native-google-fit'; OR anything else

Adding on, upon inspection of the AndroidManifest.xml of the generated android installation package. It seems to be missing its corresponding manifest tag <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />.

Still not working.

Docs should be updated at the very least.

Update:

After further testing, I am 99.99% certain this is to do with Android’s ACTIVITY_RECOGNITION permission not being permitted, as a result of it not being requested.

There is no prompt for this permission to come up during the lifecycle of attempting to access the Pedometer this way.

Similar to Issue#13131, by ejecting from expo and using a third-party permissions module, I am able to successfully get a request/prompt/dialog window for Activity Recognition from the application.

Using pedometer from expo-sensor then works once permission has been granted from the dialogue window.