Android : Need to create Shared Preferences object in c++ NDK and Store some Boolean value

Amjad Khan 07/29/2017. 3 answers, 887 views
java android android c++ android-ndk android-ndk jni

I am new to this don't know how to start this,

I have created a project that is linked to C++ using Android.mk

So when I call a method from java it should do the storing boolean value to my shared preference object.

This is my JNI method

extern "C"
JNIEXPORT void JNICALL
Java_com_example_sample_storeBoolean(JNIEnv *env,jobject instance){
//TODO 
const char *name ="hello";
__android_log_print(ANDROID_LOG_ERROR, "TRACKERS", "***** %s *****", name);
}

normal log I have printed it is working now only just need create sharepreference object and set boolean value

SharedPreferences prefs = context.getSharedPreferences("myprefdata", Context.MODE_PRIVATE);

prefs.edit().putBoolean("settingnootification", true).commit();

Please guide me how to do. Thanks

public abstract SharedPreferences getSharedPreferences(String name, int mode);

Need to use this method in c++

3 Answers


vikas kumar 08/05/2017.

I just called saveBoolean(boolean bool) in MainActivity from JNI and it saved the value. Here is code: MainActivity

public class MainActivity extends AppCompatActivity {

// Used to load the 'native-lib' library on application startup.
static {
    System.loadLibrary("native-lib");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    stringFromJNI(this);
}

/**
 * A native method that is implemented by the 'native-lib' native library,
 * which is packaged with this application.
 */
public native void stringFromJNI(MainActivity mainActivity);

public void saveBoolean(boolean bool){
    SharedPreferences sharedPreferences = this.getSharedPreferences("Test", Context.MODE_PRIVATE);
    sharedPreferences.edit().putBoolean("testBool",bool).commit();
    Log.d("MainActivity","saveBoolean Called "+bool);
}

}

#include <jni.h>
#include <string>

extern "C"
JNIEXPORT void JNICALL
Java_com_android_techgig_sharedpref_MainActivity_stringFromJNI(JNIEnv *env,jobject  obj /* this */) {

    jclass cls = (env)->GetObjectClass(obj); //for getting class
    jmethodID mid = (env)->GetMethodID(cls, "saveBoolean", "(Z)V"); //for getting method signature, Z for boolean
    if (mid == 0)
        return;
    //will return 0 in case of class not found
    (env)->CallVoidMethod(obj, mid, true); //now calling actual method
    printf("native called");
}

Here is method signatures types

Signature   Java Type
Z   boolean
B   byte
C   char
S   short
I   int
J   long
F   float
D   double

Here is link to explore more..

Happy coding!!!


mko 07/31/2017.

I guess you want to call Java class from your code. I suggest to call Java back from your C++ code.

Take a look here:

https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo032

In this sample, what you do is:

  • Java calls C++
  • Based on info passed from Java, C++ attaches to JVM
  • C++ code calls Java code from another class (in your case, it will be SharedPreferences object)

It might be you will need some helper class to make things simpler. E.g. PreferencesStorer - where you will get proper preferences class and pass values you want to store.

Take a look here:

public static int fun() {
  System.out.println("From JVM");
  return 0;
}

This is the method you want to call but you want it to be: store(String value, int mode).

In your code (in Java) you need to create this object and pass it as argument to your C++ code. Inside C++ you want to call method of this object. Inside JVM it will be already there - ready to be called.

If this is not what you are looking for, I think you need to provide some more info to make the whole use-case little bit more clear.

Have fun with JNI


Amjad Khan 09/06/2017.

I need to call a getSharedPreferences() method, So how can I call that and store boolean.

So, I have created two simple methods for storing and retrieving boolean value in NDK C++

MainActivity.java

public class MainActivity extends Activity {
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("Native");
    }
    private Activity activity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        activity=MainActivity.this;
        setStoreBoolValues(activity, true);

        if (getStoreValues(activity))
            Log.e("Store Value", " ** true **");
        else
            Log.e("Store Value", " ** false **");
    }

    public native boolean getStoreValues(Activity activity);
    public native void setStoreBoolValues(Activity activity, boolean flag);
}

Declared Native Method in MainActivity and also called my .so file

NativeClass.Cpp

jobject mainClass;

jstring spname(JNIEnv *env) {
    return env->NewStringUTF("sharedstore");
}

jstring objectname(JNIEnv *env) {
    return env->NewStringUTF("boolvaluestore");
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_ebizzinfotech_amjad_contentresolverproj_MainActivity_getStoreValues(JNIEnv *env,
                                                                             jobject instance,
                                                                             jobject activity) {

    jclass spcls = env->FindClass("android/content/SharedPreferences");
    jclass contextcls = env->FindClass("android/content/Context");
    mainClass = env->NewGlobalRef(activity);
    jmethodID mid = env->GetMethodID(contextcls, "getSharedPreferences",
                                     "(Ljava/lang/String;I)Landroid/content/SharedPreferences;");
    jmethodID midbool = env->GetMethodID(spcls, "getBoolean",
                                         "(Ljava/lang/String;Z)Z");
    jobject jobjectshared = env->CallObjectMethod(mainClass, mid, spname(env), 0);
//    jobject jobjectsharededit  = env->CallObjectMethod(jobjectshared,midedit);
    jboolean jboolean1 = env->CallBooleanMethod(jobjectshared, midbool,objectname(env), JNI_FALSE);

    env->DeleteLocalRef(spcls);
    env->DeleteLocalRef(contextcls);
    return jboolean1;
}


extern "C"
JNIEXPORT void JNICALL
Java_com_ebizzinfotech_amjad_contentresolverproj_MainActivity_setStoreBoolValues(JNIEnv *env,
                                                                                 jobject instance,
                                                                                 jobject activity,
                                                                                 jboolean flag) {
    jclass spcls = env->FindClass("android/content/SharedPreferences");
    jclass speditorcls = env->FindClass("android/content/SharedPreferences$Editor");
    jclass contextcls = env->FindClass("android/content/Context");

    mainClass = env->NewGlobalRef(activity);

    jmethodID mid = env->GetMethodID(contextcls, "getSharedPreferences",
                                     "(Ljava/lang/String;I)Landroid/content/SharedPreferences;");

    jmethodID midedit = env->GetMethodID(spcls, "edit",
                                         "()Landroid/content/SharedPreferences$Editor;");

    jmethodID midputbool = env->GetMethodID(speditorcls, "putBoolean",
                                            "(Ljava/lang/String;Z)Landroid/content/SharedPreferences$Editor;");

    jmethodID midapply = env->GetMethodID(speditorcls, "apply",
                                          "()V");
    jobject jobjectshared = env->CallObjectMethod(mainClass, mid,spname(env), 0);
    jobject jobjectsharededit = env->CallObjectMethod(jobjectshared, midedit);
    env->CallVoidMethod(env->CallObjectMethod(jobjectsharededit, midputbool, objectname(env), flag),
                        midapply);
    env->DeleteLocalRef(spcls);
    env->DeleteLocalRef(contextcls);
    env->DeleteLocalRef(speditorcls);
}

Related questions

Hot questions

Language

Popular Tags