Frage

Shared Libraries .so-Dateien in lib / armeabi in einer apk-Datei abgelegt werden.

Ich habe nach der Installation lesen Sie die Libs zu / Daten extrahiert wird / data / application_package / lib

Wie kann ich den genauen Pfad zu diesem Verzeichnis in meiner Anwendung zur Laufzeit? Ist das Verzeichnis lesbar durch die Anwendung? Oder ist nur executeable Zugriff erlaubt? Wenn es lesbar ist? - Ist das wahr noch für kopiergeschützte Anwendungen

War es hilfreich?

Lösung

Sie können den genauen Pfad erhalten mit:

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

Das Verzeichnis und seine Dateien sind lesbar durch die Anwendung.

Die Unix-Berechtigungen werden auf rwxr-x--x gesetzt. So Anwendungen mit die gleiche Gruppe, die Dateien lesen kann.

Andere Tipps

Hinzugefügt in API-Ebene 9

getContext().getApplicationInfo().nativeLibraryDir;

String libpath = getApplicationInfo().nativeLibraryDir;

Klasse verwendet: Import android.content.pm.ApplicationInfo;

Und wenn Sie mit einer nativen Aktivität und 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";

Für eine bessere Kompatibilität, verwenden Sie die folgende Funktion:

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

Vielleicht ein Gerät unterstützt unterschiedliche CPU_ABIs, so ist es besser nativeRootLibraryDir zu erhalten, die alle Unter lib Verzeichnisse enthalten:

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";
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top