كيفية الحصول على المسار إلى مجلد LIB لحزمة مثبتة

StackOverflow https://stackoverflow.com/questions/2603648

  •  25-09-2019
  •  | 
  •  

سؤال

يتم وضع المكتبات المشتركة. لذا يتم وضع الملفات في Lib/Armeabi في ملف APK.

لقد قرأت بعد التثبيت يتم استخراج libs إلى/البيانات/البيانات/application_package/lib

كيف يمكنني الحصول على المسار الدقيق لهذا الدليل في طلبي في وقت التشغيل؟ هل هذا الدليل قابل للقراءة حسب التطبيق؟ أم أنه لا يُسمح بالوصول القابل للتنفيذ إلا؟ إذا كان قابلاً للقراءة - هل لا يزال هذا صحيحًا للتطبيقات المحمية للنسخ؟

هل كانت مفيدة؟

المحلول

يمكنك الحصول على المسار الدقيق مع:

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

الدليل وملفاته قابلة للقراءة بواسطة التطبيق.

تم ضبط أذونات UNIX على rwxr-x--x. لذلك يمكن للتطبيقات مع نفس المجموعة قراءة الملفات.

نصائح أخرى

تمت إضافة في مستوى API 9

getContext().getApplicationInfo().nativeLibraryDir;

String libpath = getApplicationInfo().nativeLibraryDir;

فئة المستخدمة: استيراد 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";
}

ربما يدعم الجهاز وحدة المعالجة المركزية المختلفة ، لذلك من الأفضل الحصول على nativerootlibrarydir التي تحتوي على جميع أدلة lib الفرعية:

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 مع الإسناد
لا تنتمي إلى StackOverflow
scroll top