Android 如何获取已安装包的 lib 文件夹的路径

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2603648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:30:50  来源:igfitidea点击:

How to get the path to the lib folder for an installed package

androidandroid-ndk

提问by Zardos

Shared libraries .so files are placed in lib/armeabi in an apk file.

共享库 .so 文件放置在 apk 文件中的 lib/armeabi 中。

I have read after installation the libs gets extracted to /data/data/application_package/lib

我在安装后阅读了 libs 被提取到 /data/data/application_package/lib

How can I get the exact path to this directory in my application at run time? Is this directory readable by the application? Or is only executeable access allowed? If it is readable - Is this still true for copy protected applications?

如何在运行时获取应用程序中此目录的确切路径?应用程序是否可以读取该目录?还是只允许可执行访问?如果它是可读的 - 这对于受复制保护的应用程序是否仍然正确?

采纳答案by Ralph L?we

You can get the exact path with:

您可以通过以下方式获取确切路径:

String libraryPath = getContext().getApplicationInfo().dataDir + "/lib";

The directory and its files are readable by the application.

该目录及其文件可由应用程序读取。

The unix permissions are set to rwxr-x--x. So applications with the same group can read the files.

unix 权限设置为rwxr-x--x. 因此具有相同组的应用程序可以读取文件。

回答by Crossle Song

Added in API level 9

在 API 级别 9 中添加

getContext().getApplicationInfo().nativeLibraryDir;

getContext().getApplicationInfo().nativeLibraryDir;

回答by jhasse

And if you're using a native activity and C++:

如果您使用本机活动和 C++:

void ANativeActivity_onCreate(ANativeActivity* app, void*, size_t) {
    const jclass contextClass = app->env->GetObjectClass(app->clazz);
    const jmethodID getApplicationContextMethod =
        app->env->GetMethodID(contextClass, "getApplicationContext", "()Landroid/content/Context;");
    const jobject contextObject =
        app->env->CallObjectMethod(app->clazz, getApplicationContextMethod);
    const jmethodID getApplicationInfoMethod = app->env->GetMethodID(
        contextClass, "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;");
    const jobject applicationInfoObject =
        app->env->CallObjectMethod(contextObject, getApplicationInfoMethod);
    const jfieldID nativeLibraryDirField = app->env->GetFieldID(
        app->env->GetObjectClass(applicationInfoObject), "nativeLibraryDir", "Ljava/lang/String;");
    const jobject nativeLibraryDirObject =
        app->env->GetObjectField(applicationInfoObject, nativeLibraryDirField);
    const jmethodID getBytesMethod = app->env->GetMethodID(
        app->env->GetObjectClass(nativeLibraryDirObject), "getBytes", "(Ljava/lang/String;)[B");
    const auto bytesObject = static_cast<jbyteArray>(app->env->CallObjectMethod(
        nativeLibraryDirObject, getBytesMethod, app->env->NewStringUTF("UTF-8")));
    const size_t length = app->env->GetArrayLength(bytesObject);
    const jbyte* const bytes = app->env->GetByteArrayElements(bytesObject, nullptr);
    const std::string libDir(reinterpret_cast<const char*>(bytes), length);

回答by PYK

String libpath = getApplicationInfo().nativeLibraryDir;

Class used: import android.content.pm.ApplicationInfo;

使用的类:import android.content.pm.ApplicationInfo;

回答by Verdigrass

String libraryPath = context.getFilesDir().getParentFile().getPath() + "/lib";

For better compatibility, use the following function:

为了更好的兼容性,请使用以下函数:

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public static String getLibraryDirectory(Context context) {
    int sdk_level = android.os.Build.VERSION.SDK_INT;

    if (sdk_level >= Build.VERSION_CODES.GINGERBREAD) {
        return context.getApplicationInfo().nativeLibraryDir;
    } 
    else if (sdk_level >= Build.VERSION_CODES.DONUT) {
        return context.getApplicationInfo().dataDir + "/lib";
    }

    return "/data/data/" + context.getPackageName() + "/lib";
}

回答by Ken

Maybe a device support different CPU_ABIs, so it's better to get nativeRootLibraryDir which contain all sub lib directories:

也许一个设备支持不同的 CPU_ABI,所以最好获取包含所有子库目录的 nativeRootLibraryDir:

public static String getNativeLibraryDirectory(Context context) {
    int sdk_level = android.os.Build.VERSION.SDK_INT;

    if (sdk_level >= Build.VERSION_CODES.GINGERBREAD) {
        try {
            String secondary = (String) ApplicationInfo.class.getField("nativeLibraryRootDir").get(context.getApplicationInfo());
            return secondary;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    else if (sdk_level >= Build.VERSION_CODES.DONUT) {
        return context.getApplicationInfo().dataDir + "/lib";
    }

    return "/data/data/" + context.getPackageName() + "/lib";
}