簡體   English   中英

如何獲取已安裝包的lib文件夾的路徑

[英]How to get the path to the lib folder for an installed package

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

我在安裝后讀取了libs被解壓縮到/ data / data / application_package / lib

如何在運行時獲取應用程序中此目錄的確切路徑? 該目錄是否可由應用程序讀取? 或者只允許執行訪問? 如果它是可讀的 - 對於受復制保護的應用程序是否仍然如此?

在API級別9中添加

getContext().getApplicationInfo().nativeLibraryDir;

您可以通過以下方式獲得確切路徑:

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

應用程序可以讀取目錄及其文件。

unix權限設置為rwxr-x--x 因此,具有相同組的應用程序可以讀取文件。

String libpath = getApplicationInfo().nativeLibraryDir;

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

如果您正在使用本機活動和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);
String libraryPath = context.getFilesDir().getParentFile().getPath() + "/lib";

為了更好的兼容性,請使用以下功能:

@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";
}

也許一個設備支持不同的CPU_ABI,所以最好得到包含所有子lib目錄的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";
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM