ArghArgh
ArghArgh

Reputation: 373

Flutter [local_auth] Doesn't work on Android <28

I'm trying to work with local_auth, updating from 0.4.0 to 0.6.2

I followed the instructions, changing the FlutterActivity to FlutterFragmentActivity in my MainActivity.java

( according with this guide https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects and with this thread https://github.com/flutter/flutter/issues/57678)

In this way

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

public class MainActivity extends FlutterFragmentActivity {
    @Override
    public void configureFlutterEngine(FlutterEngine flutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);
    }
}

I also changed my style.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="LaunchTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/launch_background</item>
    </style>
</resources>

and my AndroidManifest.xml

<application
        android:icon="@mipmap/ic_launcher"
        android:allowBackup="false"
        android:fullBackupContent="false"
        android:label="XXX">
        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
            android:hardwareAccelerated="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:windowSoftInputMode="adjustResize">
            <!-- This keeps the window background of the activity showing
                 until Flutter renders its first frame. It can be removed if
                 there is no splash screen (such as the default splash screen
                 defined in @style/LaunchTheme). -->

            <meta-data
                android:name="io.flutter.embedding.android.SplashScreenDrawable"
                android:resource="@drawable/launch_background" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <intent-filter>
                <action android:name="FLUTTER_NOTIFICATION_CLICK"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>
        <activity android:name="com.apptreesoftware.barcodescan.BarcodeScannerActivity"/>

        <provider
            android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
            android:authorities="${applicationId}.flutter_downloader.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

It works on Android 28 and higher, but not on older versions.


When I run on android 27 I got this error

I/zygote (10611): Rejecting re-init on previously-failed class java.lang.Class: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/core/widget/TintableCompoundDrawablesView; I/zygote (10611): (Throwable with no stack trace) I/zygote (10611): Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.core.widget.TintableCompoundDrawablesView" on path: DexPathList[[zip file "/data/app/it.xxx.flutter.xxx-bwyNjP_RiFiWr_SW3gO7MQ==/base.apk"],nativeLibraryDirectories=[/data/app/it.xxx.flutter.xxx-bwyNjP_RiFiWr_SW3gO7MQ==/lib/x86, /data/app/it.xxx.flutter.xxx-bwyNjP_RiFiWr_SW3gO7MQ==/base.apk!/lib/x86, /system/lib, /vendor/lib]] I/zygote (10611): (Throwable with no stack trace) I/zygote (10611): E/MethodChannel#plugins.flutter.io/local_auth(10611): Failed to handle method call E/MethodChannel#plugins.flutter.io/local_auth(10611): android.view.InflateException: Binary XML file line #26: Binary XML file line #45: Error inflating class androidx.appcompat.widget.DialogTitle E/MethodChannel#plugins.flutter.io/local_auth(10611): Caused by: android.view.InflateException: Binary XML file line #45: Error inflating class androidx.appcompat.widget.DialogTitle E/MethodChannel#plugins.flutter.io/local_auth(10611): Caused by: java.lang.ClassNotFoundException: androidx.appcompat.widget.DialogTitle E/MethodChannel#plugins.flutter.io/local_auth(10611): at java.lang.VMClassLoader.findLoadedClass(Native Method) E/MethodChannel#plugins.flutter.io/local_auth(10611): at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:738) E/MethodChannel#plugins.flutter.io/local_auth(10611): at java.lang.ClassLoader.loadClass(ClassLoader.java:363) E/MethodChannel#plugins.flutter.io/local_auth(10611): at java.lang.ClassLoader.loadClass(ClassLoader.java:312) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.createView(LayoutInflater.java:606) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:790) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.rInflate(LayoutInflater.java:863) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.rInflate(LayoutInflater.java:866) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.parseInclude(LayoutInflater.java:995) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.rInflate(LayoutInflater.java:859) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.inflate(LayoutInflater.java:515) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.inflate(LayoutInflater.java:423) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.inflate(LayoutInflater.java:374) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:555) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.appcompat.app.AppCompatDialog.setContentView(AppCompatDialog.java:95) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.appcompat.app.AlertController.installContent(AlertController.java:232) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.appcompat.app.AlertDialog.onCreate(AlertDialog.java:279) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.app.Dialog.dispatchOnCreate(Dialog.java:403) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.app.Dialog.show(Dialog.java:302) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.fragment.app.DialogFragment.onStart(DialogFragment.java:486) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.fragment.app.Fragment.performStart(Fragment.java:2632) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:915) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.fragment.app.FragmentManagerImpl.executePendingTransactions(FragmentManagerImpl.java:183) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.biometric.BiometricPrompt.authenticateInternal(BiometricPrompt.java:749) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.biometric.BiometricPrompt.authenticate(BiometricPrompt.java:658) E/MethodChannel#plugins.flutter.io/local_auth(10611): at io.flutter.plugins.localauth.AuthenticationHelper.authenticate(AuthenticationHelper.java:103) E/MethodChannel#plugins.flutter.io/local_auth(10611): at io.flutter.plugins.localauth.LocalAuthPlugin.onMethodCall(LocalAuthPlugin.java:120) E/MethodChannel#plugins.flutter.io/local_auth(10611): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:226) E/MethodChannel#plugins.flutter.io/local_auth(10611): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85) E/MethodChannel#plugins.flutter.io/local_auth(10611): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:631) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.os.MessageQueue.nativePollOnce(Native Method) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.os.MessageQueue.next(MessageQueue.java:325) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.os.Looper.loop(Looper.java:142) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.app.ActivityThread.main(ActivityThread.java:6494) E/MethodChannel#plugins.flutter.io/local_auth(10611): at java.lang.reflect.Method.invoke(Native Method) E/MethodChannel#plugins.flutter.io/local_auth(10611): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) E/MethodChannel#plugins.flutter.io/local_auth(10611): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) E/MethodChannel#plugins.flutter.io/local_auth(10611): Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/core/widget/TintableCompoundDrawablesView; E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.appcompat.app.AppCompatDelegateImpl.createView(AppCompatDelegateImpl.java:1383) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.appcompat.app.AppCompatDelegateImpl.onCreateView(AppCompatDelegateImpl.java:1457) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:772) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.inflate(LayoutInflater.java:492) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.inflate(LayoutInflater.java:423) E/MethodChannel#plugins.flutter.io/local_auth(10611): at android.view.LayoutInflater.inflate(LayoutInflater.java:374) E/MethodChannel#plugins.flutter.io/local_auth(10611): at com.android.internal.policy.DecorView.onResourcesLoaded(DecorView.java:1933) E/MethodChannel#plugins.flutter.io/local_auth(10611): at com.android.internal.policy.PhoneWindow.generateLayout(PhoneWindow.java:2586) E/MethodChannel#plugins.flutter.io/local_auth(10611): at com.android.internal.policy.PhoneWindow.installDecor(PhoneWindow.java:2659) E/MethodChannel#plugins.flutter.io/local_auth(10611): at com.android.internal.policy.PhoneWindow.getDecorView(PhoneWindow.java:2067) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:717) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:659) E/MethodChannel#plugins.flutter.io/local_auth(10611): at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:552) E/MethodChannel#plugins.flutter.io/local_auth(10611): ... 30 more E/MethodChannel#plugins.flutter.io/local_auth(10611): Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.core.widget.TintableCompoundDrawablesView" on path: DexPathList[[zip file "/data/app/it.xxx.flutter.xxx-bwyNjP_RiFiWr_SW3gO7MQ==/base.apk"],nativeLibraryDirectories=[/data/app/it.xxx.flutter.xxx-bwyNjP_RiFiWr_SW3gO7MQ==/lib/x86, /data/app/it.xxx.flutter.xxx-bwyNjP_RiFiWr_SW3gO7MQ==/base.apk!/lib/x86, /system/lib, /vendor/lib]] E/MethodChannel#plugins.flutter.io/local_auth(10611): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125) E/MethodChannel#plugins.flutter.io/local_auth(10611): at java.lang.ClassLoader.loadClass(ClassLoader.java:379) E/MethodChannel#plugins.flutter.io/local_auth(10611): at java.lang.ClassLoader.loadClass(ClassLoader.java:312)

E/MethodChannel#plugins.flutter.io/local_auth(10611): ... 44 more


That's my conf

[✓] Flutter: is fully installed. (Channel stable, v1.17.3, on Mac OS X 10.15.5 19F101, locale en-IT)
[✓] Android toolchain - develop for Android devices: is fully installed. (Android SDK version 29.0.3)
[✓] Xcode - develop for iOS and macOS: is fully installed. (Xcode 11.5)
[✓] Android Studio: is fully installed. (version 3.6)
[✓] VS Code: is fully installed. (version 1.45.1)
[✓] Connected device: is fully installed. (1 available)

Any suggestions will be appreciated

Upvotes: 1

Views: 2614

Answers (3)

Komolafe Ezekiel dare
Komolafe Ezekiel dare

Reputation: 115

I solve my issue...

i removed

if (
    details.requested.group == 'com.android.support'
    && !details.requested.name.contains('multidex')
) {
    details.useVersion "27.1.1"
}
if (
    details.requested.group == 'androidx.core'
    && !details.requested.name.contains('androidx')
) {
    details.useVersion "1.0.1"
}
if (requested.group == "androidx" && !requested.name.startsWith("multidex")) {
    details.useVersion "${targetSdk}.+"
}

from android/build.gradle

and it work

Upvotes: 0

Nicol&#242; Bozzato
Nicol&#242; Bozzato

Reputation: 86

I'm probably late, but today I had the same problem and for me was useful to follow this solution

https://github.com/hnvn/flutter_image_cropper/issues/78

Remove these parts

if (details.requested.group == 'com.android.support'
&& !details.requested.name.contains('multidex') ) {
details.useVersion "27.1.1"
}
if (details.requested.group == 'androidx.core'
&& !details.requested.name.contains('androidx') ) {
details.useVersion "1.0.1"
}
if (requested.group == "androidx") {
if (!requested.name.startsWith("multidex")) {
details.useVersion "${targetSdk}.+"
}

from Android/build.gradle

Upvotes: 0

Iaroslav Siniugin
Iaroslav Siniugin

Reputation: 1046

For me helps:

Activity

import io.flutter.embedding.android.FlutterActivity

class MainActivity: FlutterActivity() { }

Manifest

<!-- io.flutter.app.FlutterApplication is an android.app.Application that
     calls FlutterMain.startInitialization(this); in its onCreate method.
     In most cases you can leave this as-is, but you if you want to provide
     additional functionality it is fine to subclass or reimplement
     FlutterApplication and put your custom class here. -->

<application
    android:name="io.flutter.app.FlutterApplication"
    android:label="your label"
    android:icon="@mipmap/ic_launcher">

    <meta-data
        android:name="flutterEmbedding"
        android:value="2" />

    <activity
        android:name=".MainActivity"
        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">
        <!-- This keeps the window background of the activity showing
             until Flutter renders its first frame. It can be removed if
             there is no splash screen (such as the default splash screen
             defined in @style/LaunchTheme). -->

        <meta-data
            android:name="io.flutter.embedding.android.NormalTheme"
            android:resource="@style/NormalTheme"
            />

        <meta-data
            android:name="io.flutter.embedding.android.SplashScreenDrawable"
            android:resource="@drawable/launch_background"
            />

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <intent-filter>
            <action android:name="FLUTTER_NOTIFICATION_CLICK" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
   
</application>
<uses-permission android:name="android.permission.INTERNET" />


<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

<!-- The Agora SDK requires Bluetooth permissions in case users are using Bluetooth devices.-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />

Upvotes: 0

Related Questions