Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter : local_auth: ^0.6.1 : PlatformException(error, You need to use a Theme.AppCompat theme (or descendant) with this activity., null)

Tags:

flutter

dart

I have problem integrated my app using package Local Auth, I already Follow documentation about configurated Packages to My App. In the documentation it's said :

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).

But the problem show up after i edited MainActivity.kt :

package id.zeffry.debt_diary

import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant

import android.os.Build
import android.view.ViewTreeObserver
import android.view.WindowManager
class MainActivity: FlutterFragmentActivity() {
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);
    }
}

Log

I/flutter (22608): PlatformException(error, You need to use a Theme.AppCompat theme (or descendant) with this activity., null)

Source Code From Documentation :

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:local_auth/local_auth.dart';

//? Testing Local Auth( Finger Print , Face Recognition, etc)
class TestingPage extends StatefulWidget {
  static const routeNamed = "/testing-page";

  @override
  _TestingPageState createState() => _TestingPageState();
}

class _TestingPageState extends State<TestingPage> {
  final LocalAuthentication auth = LocalAuthentication();

  bool _canCheckBiometrics;

  List<BiometricType> _availableBiometrics;

  String _authorized = 'Not Authorized';

  bool _isAuthenticating = false;

  Future<void> _checkBiometrics() async {
    bool canCheckBiometrics;
    try {
      canCheckBiometrics = await auth.canCheckBiometrics;
    } on PlatformException catch (e) {
      print(e);
    }
    if (!mounted) return;

    setState(() {
      _canCheckBiometrics = canCheckBiometrics;
    });
  }

  Future<void> _getAvailableBiometrics() async {
    List<BiometricType> availableBiometrics;
    try {
      availableBiometrics = await auth.getAvailableBiometrics();
    } on PlatformException catch (e) {
      print(e);
    }
    if (!mounted) return;

    setState(() {
      _availableBiometrics = availableBiometrics;
    });
  }

  Future<void> _authenticate() async {
    bool authenticated = false;
    try {
      setState(() {
        _isAuthenticating = true;
        _authorized = 'Authenticating';
      });
      authenticated = await auth.authenticateWithBiometrics(
          localizedReason: 'Scan your fingerprint to authenticate',
          useErrorDialogs: true,
          stickyAuth: true);
      setState(() {
        _isAuthenticating = false;
        _authorized = 'Authenticating';
      });
    } on PlatformException catch (e) {
      print(e);
    }
    if (!mounted) return;

    final String message = authenticated ? 'Authorized' : 'Not Authorized';
    setState(() {
      _authorized = message;
    });
  }

  void _cancelAuthentication() {
    auth.stopAuthentication();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ConstrainedBox(
        constraints: const BoxConstraints.expand(),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            Text('Can check biometrics: $_canCheckBiometrics\n'),
            RaisedButton(
              child: const Text('Check biometrics'),
              onPressed: _checkBiometrics,
            ),
            Text('Available biometrics: $_availableBiometrics\n'),
            RaisedButton(
              child: const Text('Get available biometrics'),
              onPressed: _getAvailableBiometrics,
            ),
            Text('Current State: $_authorized\n'),
            RaisedButton(
              child: Text(_isAuthenticating ? 'Cancel' : 'Authenticate'),
              onPressed:
                  _isAuthenticating ? _cancelAuthentication : _authenticate,
            )
          ],
        ),
      ),
    );
  }
}

Update Error From Real Device :

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
    at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:686)
    at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:649)
    at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:542)
    at androidx.appcompat.app.AppCompatDialog.setContentView(AppCompatDialog.java:95)
    at androidx.appcompat.app.AlertController.installContent(AlertController.java:232)
    at androidx.appcompat.app.AlertDialog.onCreate(AlertDialog.java:279)
    at android.app.Dialog.dispatchOnCreate(Dialog.java:389)
    at android.app.Dialog.show(Dialog.java:293)
    at androidx.fragment.app.DialogFragment.onStart(DialogFragment.java:486)
    at androidx.fragment.app.Fragment.performStart(Fragment.java:2627)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:915)
    at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
    at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
    at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2076)
    at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1866)
    at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1821)
    at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
    at androidx.fragment.app.FragmentManagerImpl.executePendingTransactions(FragmentManagerImpl.java:183)
    at androidx.biometric.BiometricPrompt.authenticateInternal(BiometricPrompt.java:749)
    at androidx.biometric.BiometricPrompt.authenticate(BiometricPrompt.java:658)
    at io.flutter.plugins.localauth.AuthenticationHelper$1.run(AuthenticationHelper.java:182)
    at android.os.Handler.handleCallback(Handler.java:754)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:165)
    at android.app.ActivityThread.main(ActivityThread.java:6375)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)

like image 571
Zeffry Reynando Avatar asked Dec 22 '19 04:12

Zeffry Reynando


3 Answers

If you receive this error:

Exception has occurred. PlatformException (PlatformException(error, You need to use a Theme.AppCompat theme (or descendant) with this activity., null))

Then you need to do this:

  1. Go to android > app > src > main > res > values > style.xml

  2. Change the

<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">

to

<style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar">

For more information regarding setting MainActivity.kt in Kotlin; visit here: https://gist.github.com/akifarhan/f70a2c777651f2ea61a15eb92a5939c1

like image 96
akifarhan Avatar answered Oct 23 '22 07:10

akifarhan


Once you change the theme to AppCompat there is an issue with the view shown btw splash screen and first widget(which is usually same as you splash screen). Now there is a small pop btw both images, which is super annoying and I had to remove this super feature and remain with same ugly logic as on iOS and see white screen btw splash theme and first widget :(

 <meta-data
            android:name="io.flutter.embedding.android.SplashScreenDrawable"
            android:resource="@drawable/launch_background"
            />
like image 32
Galeen Avatar answered Oct 23 '22 07:10

Galeen


Change

<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">

in android folder in file res/style.xml to

<style name="LaunchTheme" parent="@android:style/Theme.AppCompat.Black.NoTitleBar">
like image 1
Misha Babec Avatar answered Oct 23 '22 05:10

Misha Babec