📌  相关文章
📜  对 expo 指纹做出本机反应在 apk 中不起作用 - Javascript (1)

📅  最后修改于: 2023-12-03 14:53:38.244000             🧑  作者: Mango

对 expo 指纹做出本机反应在 apk 中不起作用 - Javascript

问题描述

在使用 expo-local-authentication 进行本机指纹认证时,发现在调试阶段(expo中使用了模拟器)能够正常工作,但在生成apk之后,指纹认证不再起作用。

解决方案

经过研究发现,问题的根本原因在于apk生成后,expo-local-authentication 模块中依赖的一些native库无法正确加载。

为了解决这个问题,需要手动修改apk的gradle配置,添加一些必要的代码。

修改android目录下的 build.gradle

在android目录下,找到build.gradle,并添加以下内容:

project.ext.react = [
    cliPath: "./node_modules/react-native/local-cli/cli.js",
    enableHermes: true
]

def haveExpoModules = hasProperty("expo.modules.packageList")
def includesExpoModules = hasProperty("expo.modules.includes")

android {
    // ...
    defaultConfig {
        // ...
        missingDimensionStrategy 'react-native-camera', 'general'
        manifestPlaceholders = [
            appAuthRedirectScheme: 'exp1234567890'
        ]
    }
    
    packagingOptions {
        pickFirst '**/libc++_shared.so'
    }

    // Add the following block to correctly run the Expo Apk in release mode
    signingConfigs {
        debug {
            storeFile file('debug.keystore')
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            signingConfig signingConfigs.debug
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            applicationVariants.all { variant ->
                if (haveExpoModules && includesExpoModules) {
                    def packageList = project.ext.env.get('EXPO_PACKAGES', '')
                    def packageDirs = packageList.split(':').collect { ":$it" }
                    def includes = includesExpoModules.split(',')
                    def haveIncludes = includes.contains('*') || includes.any { include ->
                        packageDirs.any { dir -> dir.contains(include) }
                    }
                    if (haveIncludes) {
                        variant.resValue 'string', 'app_name', "Expo ${rootProject.name.capitalize()}"
                    }
                }
            }
        }
    }

    // ...
}

这段代码中主要修改了以下内容:

  • 添加了 packagingOptions 配置,设置excluded的 libc++_shared.so 模块,避免加载conflict的库.
  • 修改了 buildTypes 中的debug配置,添加了signing配置.
  • 修改了 buildTypes 中的release配置,添加了 packagingOptions 配置 和 applicationVariants.resValue 配置.
修改 MainActivity.java

MainActivity.java 中添加以下代码:

import expo.modules.LocalAuthenticationPackage;

public class MainActivity extends ReactActivity {
    // ...

    @Override
    protected List<ReactPackage> getPackages() {
        @SuppressWarnings("UnnecessaryLocalVariable")
        List<ReactPackage> packages = new PackageList(this).getPackages();
        // Packages that cannot be autolinked yet can be added manually here, for example:
        // packages.add(new MyReactNativePackage());
        packages.add(new LocalAuthenticationPackage());
        return packages;
    }
}

这段代码主要是配置了 LocalAuthenticationPackage,将其添加到 getPackages 方法中.

执行 expo publishexpo build:android

最后,运行 expo publishexpo build:android 重新构建应用程序,并尝试使用指纹认证。应该可以正常工作了。

结论

在APK版本中,必须手动修改 build.gradle 配置文件和添加 MainActivity.java 中的导入,以确保本机新特性可以正确加载.