Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Health 8.0.0] ActivityNotFoundException when requesting for permission #800

Closed
hartmannj opened this issue Sep 1, 2023 · 12 comments · Fixed by #884
Closed

[Health 8.0.0] ActivityNotFoundException when requesting for permission #800

hartmannj opened this issue Sep 1, 2023 · 12 comments · Fixed by #884
Assignees
Labels
bugfix a bug fix

Comments

@hartmannj
Copy link

OS: Android 14
Device: Emulator (Pixel 7 Pro, Android SDK 34 Google Play)

When trying to request for permissions like following:

final types = [HealthDataType.BLOOD_GLUCOSE];
final permissions = [
      HealthDataAccess.READ_WRITE,
];
await healthFactory.requestAuthorization(types, permissions: permissions);

the app crashes with exception:

android.content.ActivityNotFoundException: No Activity found to handle Intent
{act=androidx.activity.result.contract.action.REQUEST_PERMISSIONS (has extras) }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2239)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1878)
at android.app.Activity.startActivityForResult(Activity.java:5589)
at android.app.Activity.startActivityForResult(Activity.java:5547)
at cachet.plugins.health.HealthPlugin.requestAuthorizationHC(HealthPlugin.kt:1542)
at cachet.plugins.health.HealthPlugin.requestAuthorization(HealthPlugin.kt:1233)
at cachet.plugins.health.HealthPlugin.onMethodCall(HealthPlugin.kt:1396)
at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:258)

My AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <queries>
        <package android:name="com.google.android.apps.healthdata" />
        <intent>
            <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
        </intent>
    </queries>

    <uses-permission android:name="android.permission.health.READ_BLOOD_GLUCOSE"/>
    <uses-permission android:name="android.permission.health.WRITE_BLOOD_GLUCOSE"/>

    <application
        android:label="my_app"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <intent-filter>
                <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

The Health Connect app is installed on the emulator. Any idea what I am missing?

@hartmannj hartmannj added the bugfix a bug fix label Sep 1, 2023
@hartmannj
Copy link
Author

It seems to work with emulators using Android SDK 33 Google Play.
This could potentially mean that it will crash on all devices with Android 14, or otherwise it might be a bug in the SDK 34 Google Play emulator image.

@VladyslavValujskyj
Copy link

OS: Android 14
Device: Google Pixel 5 (physical device)

Getting the same exception. It seems to be global SDK 34 problem

@hoffmatteo hoffmatteo self-assigned this Sep 6, 2023
@hoffmatteo
Copy link
Contributor

While I can reproduce this error in the emulator using Android 14, I have not found a way to fix it yet.

Any input is appreciated!

@scalz
Copy link

scalz commented Oct 14, 2023

@hoffmatteo
Hello,
I've not tried yet, but one of my user reported same kind of issue when trying to install my apk on android 14, he gets this:
"App update needed
The Health Connect (Beta) app is being integrated with the Android
system.
[myapp] needs to be updated to continue syncing with
Health Connect.

It seems google did some changes for android14 and HealthConnect is now a part of OS.
https://developer.android.com/health-and-fitness/guides/health-connect/migrate/migrate-from-android-13-to-14

@sviridov
Copy link

sviridov commented Oct 17, 2023

Same issue here. I can reproduce it on a physical device (Pixel 5a) and an emulator with Android 14.

Things that I tried to fix the issue:

      <activity-alias
          android:name="ViewPermissionUsageActivity"
          android:exported="true"
          android:targetActivity=".MainActivity"
          android:permission="android.permission.START_VIEW_PERMISSION_USAGE">
          <intent-filter>
              <action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
              <category android:name="android.intent.category.HEALTH_PERMISSIONS" />
          </intent-filter>
      </activity-alias>

None of it helped so far.

By the way, https://github.com/imdzx/flutter_health_connect has the same issue.

@malik19995
Copy link

Getting the same issue on a physical device, Pixel 6 Pro ever since I upgraded to Android 14.

The same codebase worked well on android 13.

Screenshot 2023-11-02 at 1 56 00 AM

@MitchSchwartz
Copy link

Same issue here Pixel 6A since upgrade to Android 14:

Failed to handle method call android.content.ActivityNotFoundException: No Activity found to handle Intent { act=androidx.activity.result.contract.action.REQUEST_PERMISSIONS (has extras) }
                                                                                                    	at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2239)
                                                                                                    	at android.app.Instrumentation.execStartActivity(Instrumentation.java:1878)
                                                                                                    	at android.app.Activity.startActivityForResult(Activity.java:5615)
                                                                                                    	at android.app.Activity.startActivityForResult(Activity.java:5573)
                                                                                                    	at cachet.plugins.health.HealthPlugin.requestAuthorizationHC(HealthPlugin.kt:1542)
                                                                                                    	at cachet.plugins.health.HealthPlugin.requestAuthorization(HealthPlugin.kt:1233)
                                                                                                    	at cachet.plugins.health.HealthPlugin.onMethodCall(HealthPlugin.kt:1396)
                                                                                                    	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:258)
                                                                                                    	at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
                                                                                                    	at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:322)
                                                                                                    	at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
                                                                                                    	at android.os.Handler.handleCallback(Handler.java:958)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:205)
                                                                                                    	at android.os.Looper.loop(Looper.java:294)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8194)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

 An error occurred: PlatformException(error, No Activity found to handle Intent { act=androidx.activity.result.contract.action.REQUEST_PERMISSIONS (has extras) }, null, android.content.ActivityNotFoundException: No Activity found to handle Intent { act=androidx.activity.result.contract.action.REQUEST_PERMISSIONS (has extras) }
                                                                                                    	at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2239)
                                                                                                    	at android.app.Instrumentation.execStartActivity(Instrumentation.java:1878)
                                                                                                    	at android.app.Activity.startActivityForResult(Activity.java:5615)
                                                                                                    	at android.app.Activity.startActivityForResult(Activity.java:5573)
                                                                                                    	at cachet.plugins.health.HealthPlugin.requestAuthorizationHC(HealthPlugin.kt:1542)
                                                                                                    	at cachet.plugins.health.HealthPlugin.requestAuthorization(HealthPlugin.kt:1233)
                                                                                                    	at cachet.plugins.health.HealthPlugin.onMethodCall(HealthPlugin.kt:1396)
                                                                                                    	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:258)
                                                                                                    	at io.flutter.embedding.engine.dart.DartMessenger.invo
2023-11-06 10:19:35.119 22022-22022 FLUTTER_HEALTH          I  Access Denied (to Health Connect)!

@chadpav
Copy link
Contributor

chadpav commented Nov 13, 2023

Checking in here on some progress I've made.

First, we know this was working before in Android SDK 33. In Android SDK 34, the health connect framework is built into the OS. I thought maybe they changed the name of the activity. So I started from the idea that I was implementing Health Connect as a native Android developer.

Here is the relevant developer page for implementing health connect in Android:
https://developer.android.com/health-and-fitness/guides/health-connect/develop/get-started

Note that it does require additional permissions in the manifest for Android SDK 34. So I added that to my app and it still has the same exception. We will need to update this plugin with those details though.

            <!-- Health Connect Android 14, create an activity alias to show the rationale
       of Health Connect permissions once users click the privacy policy link. -->
            <intent-filter>
                <action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
                <category android:name="android.intent.category.HEALTH_PERMISSIONS" />
            </intent-filter>

These permissions are actually there to give the Health Connect app a way to link back to the privacy policy of your app. For a minute, I thought maybe the "no activity found" error might be referring to HC not being able to find the privacy policy activity.

Next, I found their code sample and verified that on the same Android 34 test device I am able to request permissions successfully. This means that we have a working code sample that shows how to request permissions. So we should be able to just update the HealthPlugin.kt file on L1540-1543 to open the activity the same way.

https://github.com/android/health-samples/tree/main/health-connect/HealthConnectSample

Here is where I'm stuck... I'm not a native Android guy. I came from iOS and work on Flutter apps now. I can read the code but, geez, there seem to be multiple ways to open an activity in Android. The code sample from Google looks like it uses Jetpack Compose and a bunch of libraries and code patterns to open the HC activity. It's completely different to how this plugin works so I haven't been able to adapt the code. It also feels like Jetpack Compose might be heavy handed for a Flutter app that has minimal native code.

I'm hoping by sharing this info someone with more Android native experience can help out.

@eliasteeny
Copy link
Contributor

Check #834, it is an attempted fix for this issue. Any changes or improvements are welcome.

@dariosalvi78
Copy link

dariosalvi78 commented Nov 20, 2023

hello, working on a Cordova plugin, using Java, so not the same environment but I get exactly the same issue on SDK 34, physical device. If you manage to solve it, please inform what was causing the problem and how you fixed it. You will make many people happy!

@dariosalvi78
Copy link

OK I have the answer now. In Android 14 the use of startActivityForResult has been completely phased out and you have to use the new workflow, with registerForActivityResult. This was solved by @eliasteeny in his commit and also solved my problem (or at least learning about it).

@Alejandroem
Copy link

Check #834, it is an attempted fix for this issue. Any changes or improvements are welcome.

If you use this solution as a freezed package on the pubspec yaml you can make this error go away.

You can read a bit more in here #834 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugfix a bug fix
Projects
None yet
Development

Successfully merging a pull request may close this issue.