Алексей
Алексей

Reputation: 13

java.lang.NoSuchFieldError: no "Ljava/lang/String;" field JNI

Good day. Please tell me what I'm doing wrong. Implemented getting keys from android / provider / Settings $ System. Keys like ACCELEROMETER_ROTATION look no problem (those described https://developer.android.com/reference/android/provider/Settings.System) but such as sms_delivered_sound, he refuses to search. Writes an error.

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.woodman.testlibsettingsv2, PID: 31133
    java.lang.NoSuchFieldError: no "Ljava/lang/String;" field "sms_delivered_sound" in class "Landroid/provider/Settings$System;" or its superclasses
        at com.example.woodman.testlibsettingsv2.frmMain.GetSystemKyesString(Native Method)
        at com.example.woodman.testlibsettingsv2.frmMain.onCreate(frmMain.java:32)
        at android.app.Activity.performCreate(Activity.java:7210)
        at android.app.Activity.performCreate(Activity.java:7201)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2926)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6806)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

code

    extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_woodman_testlibsettingsv2_frmMain_GetSystemKyesString(JNIEnv *env,
                                                                       jobject instance,
                                                                       jstring key_Name_) {
    const char *key_Name = env->GetStringUTFChars(key_Name_, 0);

    // TODO
    jclass activityThread = env->FindClass("android/app/ActivityThread");
    jmethodID currentActivityThread = env->GetStaticMethodID(activityThread,
                                                             "currentActivityThread",
                                                             "()Landroid/app/ActivityThread;");
    jobject at = env->CallStaticObjectMethod(activityThread, currentActivityThread);

    jmethodID getApplication = env->GetMethodID(activityThread, "getApplication",
                                                "()Landroid/app/Application;");
    jobject context = env->CallObjectMethod(at, getApplication);


    jclass c_settings_system = env->FindClass("android/provider/Settings$System");
    jclass c_context = env->FindClass("android/content/Context");
    if (c_settings_system == NULL || c_context == NULL) {
        return NULL;
    }
    jmethodID m_get_content_resolver = env->GetMethodID(c_context, "getContentResolver",
                                                        "()Landroid/content/ContentResolver;");
    if (m_get_content_resolver == NULL) {
        return NULL;
    }

    jfieldID f_android_string_key = env->GetStaticFieldID(c_settings_system,
                                                          key_Name,
                                                          "Ljava/lang/String;");

    if (f_android_string_key == NULL) {
        return NULL;
    }
    jstring s_android_string_key = (jstring) env->GetStaticObjectField(c_settings_system,
                                                                       f_android_string_key);


    jobject o_content_resolver;
    o_content_resolver = env->CallObjectMethod(context,
                                               m_get_content_resolver);
    if (o_content_resolver == NULL || s_android_string_key == NULL) {
        return NULL;
    }

    jmethodID m_get_string = env->GetStaticMethodID(c_settings_system, "getString",
                                                    "(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;");

    if (m_get_string == NULL) {
        return NULL;
    }

    jstring string_key = (jstring) env->CallStaticObjectMethod(c_settings_system,
                                                                       m_get_string,
                                                                       o_content_resolver,
                                                                       s_android_string_key);
    return string_key;
}

thank

Upvotes: 0

Views: 1239

Answers (1)

Alex Cohn
Alex Cohn

Reputation: 57203

This value is not part of system settings. Actually, it can be found on miui framework but not in other Android systems.

There is no public API to read this setting, neither in C++ not in Java. But we know that this value is written in system/build.prop file in simple key=value format.

This file is readable for everybody. You don't need JNI to read it, usual C++ or even C file APIs will work perfectly.

A more flexible approach would be to run the settings command from your code.

Upvotes: 1

Related Questions