0

Package used https://pub.dev/packages/local_auth/versions Code implemented exactly as in the example. https://pub.dev/packages/local_auth#-example-tab-

Error Description: I/flutter ( 7978): PlatformException(no_fragment_activity, local_auth plugin requires activity to be a FragmentActivity., null)

Here is the screen shot of final result. Error occurs on pressing the third button "Authenticate". It changes to "Cancel", and throws the above error to the console for "no_fragment_activity".

Example code screen

FlutterDev008
  • 79
  • 3
  • 9

2 Answers2

2

I've just built the local_auth sample and it works (vers. 0.6.3.4). Here after the steps I've done:

  1. create a new flutter app:

    flutter create -a java -t app --project-name mywallet mywallet

Note, I'm using the java language.

  1. add the dependency to local_auth:
dependencies:
  local_auth: ^0.6.3+4
  1. copy the main.dart class from the: local_auth page

  2. modify the MainActivity.java in this manner:

MainActivity.java

package com.example.mywallet;
import android.os.Bundle;
import io.flutter.app.FlutterFragmentActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;
import android.os.Bundle; 
import io.flutter.app.FlutterFragmentActivity;
import io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin;
import io.flutter.plugins.localauth.LocalAuthPlugin;

@SuppressWarnings("deprecation")
public class MainActivity extends FlutterFragmentActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
 
  FlutterAndroidLifecyclePlugin.registerWith(
        registrarFor(
            "io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin"));
    LocalAuthPlugin.registerWith(registrarFor("io.flutter.plugins.localauth.LocalAuthPlugin"));
    

  }
}

Then, modify the android manifest in order to allow the flutter fragment to start:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.mywallet">
    <uses-permission android:name="android.permission.USE_FINGERPRINT"/>

    <application android:name="io.flutter.app.FlutterApplication" android:label="local_auth_example" android:icon="@mipmap/ic_launcher">
      <activity android:name="io.flutter.embedding.android.FlutterFragmentActivity"
                android:launchMode="singleTop"
                android:theme="@style/Theme.AppCompat.Light"
                android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
                android:hardwareAccelerated="true"
                android:windowSoftInputMode="adjustResize">
          <intent-filter>
              <action android:name="android.intent.action.MAIN"/>
              <category android:name="android.intent.category.LAUNCHER"/>
          </intent-filter>
      </activity>
      <activity
          android:name=".MainActivity"
          android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
          android:hardwareAccelerated="true"
          android:windowSoftInputMode="adjustResize">
      </activity>
      <meta-data android:name="flutterEmbedding" android:value="2"/>
  </application>
</manifest>

Now, the app is working if you are building it in debug mode, unfortunately in release mode it will take the following exception:

E/AndroidRuntime(27487): FATAL EXCEPTION: main
E/AndroidRuntime(27487): Process: com.example.mywallet, PID: 27487
E/AndroidRuntime(27487): java.lang.IllegalAccessError: Interface androidx.lifecycle.b implemented by class io.flutter.plugins.localauth.AuthenticationHelper is inaccessible (declaration of 'io.flutter.plugins.localauth.AuthenticationHelper' appears in /data/app/com.example.mywallet-t-m1EbOiZo85yTCgTK9tWw==/base.apk)
E/AndroidRuntime(27487):        at io.flutter.plugins.GeneratedPluginRegistrant.registerWith(Unknown Source:16)
E/AndroidRuntime(27487):        at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(27487):        at io.flutter.embedding.engine.h.g.a.a(Unknown Source:25)
E/AndroidRuntime(27487):        at io.flutter.embedding.android.FlutterFragmentActivity.g(Unknown Source:0)

In order to avoid this issue, you can add the file:

proguard-rules.pro

in android/app/src with the following line:

  -keep class androidx.lifecycle.DefaultLifecycleObserver

Now it works!

Here after my flutter doctor:

~/Projects/mywallet$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, 1.25.0-5.0.pre.93, on Linux, locale it_IT.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.0-rc4)
[✓] Chrome - develop for the web
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio (version 4.0)
[✓] IntelliJ IDEA Community Edition (version 2020.2)
[✓] VS Code (version 1.51.1)
[✓] Connected device (4 available)

• No issues found!

The simple app was tested on Samsung (with knox) in release mode and on the emulator :

~/Projects/mywallet$ flutter devices
4 connected devices:

SM A307FN (mobile)                 • RF8M9278QSF   • android-arm64  • Android 10 (API 29)
Android SDK built for x86 (mobile) • emulator-5554 • android-x86    • Android 10 (API 29) (emulator)
Linux (desktop)                    • linux         • linux-x64      • Linux
Chrome (web)                       • chrome        • web-javascript • Google Chrome 87.0.4280.88
Dharman
  • 30,962
  • 25
  • 85
  • 135
Mike
  • 335
  • 1
  • 8
0

You just forgot to change from FlutterActivity to FlutterFragmentActivity.

This step is present at the README of local_auth package, in the section Android Integration

Note that local_auth plugin requires the use of a FragmentActivity as opposed to Activity. This can be easily done by switching to use FlutterFragmentActivity as opposed to FlutterActivity in your manifest (or your own Activity class if you are extending the base class).

siega
  • 2,508
  • 1
  • 19
  • 22
  • I added the permissions part per the readme in my AndroidManifest.xml but there is no part that says FlutterActivity. Is it a different file? Can you elaborate? Thanks! – FlutterDev008 Jun 04 '20 at 22:27
  • I suppose you have to change FlutterActivity to FlutterFragmentActivity in your MainActivity.java. Something like this import android.os.Bundle; import io.flutter.app.FlutterFragmentActivity; import io.flutter.plugins.GeneratedPluginRegistrant; public class MainActivity extends FlutterFragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); } } – ArghArgh Jun 04 '20 at 23:11
  • I cannot find MainActivity.java under the android>app>src>main>java> :(. While "main" folder has the AndroidManifest.xml file. Maybe I have to enable view permissions. – FlutterDev008 Jun 04 '20 at 23:30
  • Found the MainActivity.java. I had to RIGHT CLICK on android folder, and OPEN with "Flutter" menu item and SELECT "open android module with android studio". – FlutterDev008 Jun 04 '20 at 23:59
  • Seems to be more than switching FlutterActivity with FlutterFragmentActivity. https://github.com/flutter/plugins/blob/52696881a2a984dd5197e20193492d757b302925/packages/local_auth/example/android/app/src/main/java/io/flutter/plugins/localauthexample/MainActivity.java#L8 – FlutterDev008 Jun 05 '20 at 00:04