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

sharedpreferences - android example
shared preference login example in android
how to get data from shared preference in android
android sharedpreferences kotlin
sharedpreferences in android studio stack overflow
android sharedpreferences example androidhive
how to store multiple values in sharedpreferences in android
shared preferences flutter

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++

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!!!

Android Shared preferences for creating one time activity (example , I have three activities A,B and C where A and B are forms and after filling and saving the form data in database(SQLITE). I am using intent from A to B and then B to  One of this way is called Shared Preferences. Shared Preferences allow you to save and retrieve data in the form of key,value pair. In order to use shared preferences, you have to call a method getSharedPreferences() that returns a SharedPreference instance pointing to the file that contains the values of preferences.

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);
}

Shared Preferences in Android with Examples, The first thing we need to do is to create one shared preferences file per app. and atomically commit those changes back to the SharedPreferences object. Shared Preferences in Android with Examples. One of the most Interesting Data Storage option Android provides its users is Shared Preferences. Shared Preferences is the way in which one can store and retrieve small amounts of primitive data as key/value pairs to a file on the device storage such as String, int, float, Boolean that make up your preferences in an XML file inside the app on the device storage.

SharedPreferences, Interface used for modifying values in a SharedPreferences object. Create a new Editor for these preferences, through which you can make Note that you must call Editor#commit to have any changes you perform in the  Creating a shared preferences file. You need only one shared preferences file for your app, and it is customarily named with the package name of your app. This makes its name unique and easily associated with your app. You create the shared preferences file in the onCreate() method of your main activity and store it in a member variable.

I have created two .cpp classes: SharedPreferences for reading and SharedPreferences_Editor for writing They do not need any special java code and you should be able to include them in your project easily by copy-paste.

//
// Created by Constantin on 24.10.2017.
//

#ifndef FPV_VR_HELPER_SHARED_PREFERENCES_HPP
#define FPV_VR_HELPER_SHARED_PREFERENCES_HPP

#include <jni.h>
#include <android/log.h>
#include <string>

///Example reading values
///SharedPreferences sharedPref(env,context,"pref_telemetry");
///T_Protocol=sharedPref.getInt(IDT::T_Protocol);
///Example writing values
///SharedPreferences_Editor editor=sharedPref.edit();
///editor.putString("MY_KEY","HELLO");
///editor.commit();

class SharedPreferences_Editor{
public:
    SharedPreferences_Editor(JNIEnv* env,const jobject joSharedPreferences_Edit):env(env),joSharedPreferences_Edit(joSharedPreferences_Edit){
        //find the methods for putting values into Shared preferences via the editor
        jclass jcSharedPreferences_Editor = env->GetObjectClass(joSharedPreferences_Edit);
        jmPutBoolean=env->GetMethodID(jcSharedPreferences_Editor,"putBoolean","(Ljava/lang/String;Z)Landroid/content/SharedPreferences$Editor;");
        jmPutInt=env->GetMethodID(jcSharedPreferences_Editor,"putInt","(Ljava/lang/String;I)Landroid/content/SharedPreferences$Editor;");
        jmPutString=env->GetMethodID(jcSharedPreferences_Editor,"putString","(Ljava/lang/String;Ljava/lang/String;)Landroid/content/SharedPreferences$Editor;");
        jmCommit=env->GetMethodID(jcSharedPreferences_Editor,"commit","()Z");
    }
    //return itself for method chaining
    const SharedPreferences_Editor& putBoolean(const char* key,const bool value)const{
        env->CallObjectMethod(joSharedPreferences_Edit,jmPutBoolean,env->NewStringUTF(key),(jboolean)value);
        return *this;
    }
    const SharedPreferences_Editor& putInt(const char* key,const int value)const{
        env->CallObjectMethod(joSharedPreferences_Edit,jmPutInt,env->NewStringUTF(key),(jint)value);
        return *this;
    }
    const SharedPreferences_Editor& putString(const char* key,const char* value)const{
        env->CallObjectMethod(joSharedPreferences_Edit,jmPutString,env->NewStringUTF(key),env->NewStringUTF(value));
        return *this;
    }
    bool commit()const{
        return (bool)env->CallBooleanMethod(joSharedPreferences_Edit,jmCommit);
    }
private:
    JNIEnv* env;
    jobject joSharedPreferences_Edit;
    jmethodID jmPutBoolean;
    jmethodID jmPutInt;
    jmethodID jmPutString;
    jmethodID jmCommit;
};


class SharedPreferences {
public:
    SharedPreferences(SharedPreferences const &) = delete;
    void operator=(SharedPreferences const &)= delete;
public:
    //Note: Per default, this doesn't keep the reference to the sharedPreferences java object alive
    //longer than the lifetime of the JNIEnv.
    //With keepReference=true the joSharedPreferences is kept 'alive' and you can still use the class after the original JNIEnv* has become invalid -
    //but make sure to refresh the JNIEnv* object with a new valid reference via replaceJNI()
    SharedPreferences(JNIEnv *env, jobject androidContext,const char* name,const bool keepReference=false){
        this->env=env;
        //Find the 2 java classes we need to make calls with
        jclass jcContext = env->FindClass("android/content/Context");
        jclass jcSharedPreferences = env->FindClass("android/content/SharedPreferences");
        //jclass jcSharedPreferences_Editor=env->FindClass("android/content/SharedPreferences$Editor");
        if(jcContext==nullptr || jcSharedPreferences== nullptr){
            __android_log_print(ANDROID_LOG_DEBUG, "SharedPreferences","Cannot find classes");
        }
        //find the 3 functions we need to get values from an SharedPreferences instance
        jmGetBoolean=env->GetMethodID(jcSharedPreferences,"getBoolean","(Ljava/lang/String;Z)Z");
        jmGetInt=env->GetMethodID(jcSharedPreferences,"getInt","(Ljava/lang/String;I)I");
        jmGetFloat=env->GetMethodID(jcSharedPreferences,"getFloat","(Ljava/lang/String;F)F");
        jmGetString=env->GetMethodID(jcSharedPreferences,"getString","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
        //find the 1 function we need to create the SharedPreferences.Editor object
        jmEdit=env->GetMethodID(jcSharedPreferences,"edit", "()Landroid/content/SharedPreferences$Editor;");
        //create a instance of SharedPreferences and store it in @joSharedPreferences
        jmethodID jmGetSharedPreferences=env->GetMethodID(jcContext,"getSharedPreferences","(Ljava/lang/String;I)Landroid/content/SharedPreferences;");
        joSharedPreferences=env->CallObjectMethod(androidContext,jmGetSharedPreferences,env->NewStringUTF(name),MODE_PRIVATE);
        //jmEdit_commit=env->GetMethodID(jcSharedPreferences_Editor,"putString","(Ljava/lang/String;Ljava/lang/String;)Landroid/content/SharedPreferences$Editor;");
        if(keepReference){
            joSharedPreferences=env->NewWeakGlobalRef(joSharedPreferences);
        }
    }
    void replaceJNI(JNIEnv* newEnv){
        env=newEnv;
    }
private:
    JNIEnv* env;
    jobject joSharedPreferences;
    jmethodID jmGetBoolean;
    jmethodID jmGetInt;
    jmethodID jmGetFloat;
    jmethodID jmGetString;
    jmethodID jmEdit;
public:
    bool getBoolean(const char* id,bool defaultValue=false)const{
        return (bool)(env->CallBooleanMethod(joSharedPreferences,jmGetBoolean,env->NewStringUTF(id),(jboolean)defaultValue));
    }
    int getInt(const char* id,int defaultValue=0)const{
        return (int)(env->CallIntMethod(joSharedPreferences,jmGetInt,env->NewStringUTF(id),(jint)defaultValue));
    }
    float getFloat(const char* id,float defaultValue=0.0f)const{
        return (float)(env->CallFloatMethod(joSharedPreferences,jmGetFloat,env->NewStringUTF(id),(jfloat)defaultValue));
    }
    std::string getString(const char* id,const char* defaultValue="")const{
        auto value=(jstring)(env->CallObjectMethod(joSharedPreferences,jmGetString,env->NewStringUTF(id),env->NewStringUTF(defaultValue)));
        const char* valueP = env->GetStringUTFChars(value, nullptr);
        const std::string ret=std::string(valueP);
        env->ReleaseStringUTFChars(value,valueP);
        //__android_log_print(ANDROID_LOG_DEBUG, "SharedPreferences","%s",ret.c_str());
        return ret;
    }
    SharedPreferences_Editor edit()const{
        //create a instance of SharedPreferences.Editor and store it in @joSharedPreferences_Edit
        jobject joSharedPreferences_Edit=env->CallObjectMethod(joSharedPreferences,jmEdit);
        SharedPreferences_Editor editor(env,joSharedPreferences_Edit);
        return editor;
    }
private:
    static constexpr const int  MODE_PRIVATE = 0; //taken directly from java, assuming this value stays constant in java
};


#endif //FPV_VR_HELPER_SHARED_PREFERENCES_HPP

Save key-value data, If you have a relatively small collection of key-values that you'd like to save, A SharedPreferences object points to a file containing key-value pairs You can create a new shared preference file or access an existing one by  Android Shared Preferences Example. Following is the example of storing and retrieving the primitive data type values from shared preferences file using SharedPreferences. Create a new android application using android studio and give names as SharedPreferencesExample.

SharedPreferences, Retrieve a SharedPreferences object for accessing preferences that are private to this activity. To create a PreferenceScreen, you need a few things: An XML  In this article, I shall tell you about how to save the object of the model class (POJO) in preferences. Many times, we need to save an instance of a class which has only fields like Int , Long , Float , Double , String , Boolean and has further objects of different classes which are again model classes.

9.1: Shared preferences · GitBook, Shared preferences vs. saved instance state; Creating a shared preferences file; Saving The Android framework manages the shared preferences file itself. in an object such as an activity that will exist as long as you need the listener. If there is a need to edit a preferences file without user interaction, it can be done by creating an Editor instance of SharedPreferences like so. SharedPreferences.Editor editor = sharedPreferences.edit(); Then you can begin to add data to the Settings file declared when you instantiated the SharedPreferences like so.

android.content.SharedPreferences.edit java code examples, Best Java code snippets using android.content.SharedPreferences.edit (Showing top 20 results out of 12,870) SharedPreferences s = Create a new Editor for these preferences, through which you can make modifications to the preferences and atomically commit those changes back to the SharedPreferences object. Write to shared preferences. To write to a shared preferences file, create a SharedPreferences.Editor by calling edit() on your SharedPreferences. Note: You can edit shared preferences in a more secure way by calling the edit() method on an EncryptedSharedPreferences object instead of on a SharedPreferences object.

Comments
  • see JNIEnv.call*Method(jobject, jmethodID, ...)
  • Thanks, In your case calling a java function from native rather than I need to call a getSharedPreferences method, So how can I call that and store boolean.
  • app is crashing on System.loadLibrary("Native") java.lang.UnsatisfiedLinkError:
  • Now they have made changes in NDK for supporting different device. which you are running unable to find the .SO file so giving this error.
  • Thanks, But I did not get the solution which I am searching for creating and calling of the abstract method from C++ getSharedPreferences(String name, int mode);
  • abstract method in java doesn't mean it can be called from C++ .... as @mko said you need to create a java class with a method that takes the boolean as argument and stores it in SharedPreferences, You need to instantiate an object of the class and pass it as argument in a JNI call and then you can call the method from the C++ code.