Jenny Kim
Jenny Kim

Reputation: 1565

Android SharedPreferences not saving

I'm accessing SharedPreferences inside my AppWidgetProvider subclass as follow:

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
        Log.d( TAG, "WidgetProvider.onReceive " + intent.getAction() );
        Toast.makeText( context, "WidgetProvider.onReceive " + intent.getAction(), Toast.LENGTH_LONG ); // TOAST NOT WORKING

        Bundle pExtra = intent.getExtras();
        if ( pExtra != null ) {
            SharedPreferences pref = context.getApplicationContext().getSharedPreferences("widget_pref", Context.MODE_PRIVATE );
            int iWidgetId = intent.getExtras().getInt("widgetId");
            int iCount = pref.getInt("widgetCount", 0);
                    // HERE IS THE PROBLEM, iCount will always start from 0!
            for ( int i = 0; i < 10; i++ ) {
                iCount = pref.getInt("widgetCount", 0);
                iCount++;
                pref.edit().putInt("widgetCount", iCount);
                boolean bSaved = pref.edit().commit(); // return TRUE
                bSaved = pref.contains("widgetCount"); // return FALSE
                Log.w(TAG, "WidgetProvider.onReceive: " + iWidgetId + " > " + iCount + " result: " + bSaved);
            }

                    // non-relevant code
            RemoteViews remoteViews = new RemoteViews( context.getPackageName(), R.layout.widget_layout );
            remoteViews.setTextViewText( R.id.hellotextview, "ID: " + iWidgetId + " > " + iCount );
            Intent clickIntent = new Intent( context, WidgetProvider.class );
            clickIntent.setAction("WIDGET_PROVIDER_CLICKED");
            clickIntent.putExtra("widgetId", iWidgetId);
            PendingIntent clickPendingIntent = PendingIntent.getBroadcast( context, 0, clickIntent, 0 );
            remoteViews.setOnClickPendingIntent( R.id.hellolayout, clickPendingIntent );
//          AppWidgetManager.getInstance(context).updateAppWidget( iWidgetId, remoteViews );
//          ComponentName name = new ComponentName(context, WidgetProvider.class);
            ComponentName name = new ComponentName(context.getApplicationContext(), WidgetProvider.class);
            AppWidgetManager.getInstance(context).updateAppWidget(name, remoteViews);
        }
    }

However, as you can see from the comment, even though I am looping and saving the iCount will always start from default value again. The contains() even return false even though I just commit. I've tried different way of getting the SharedPreferences (using the context directly, or context.getApplicationContext() as well as different Context.MODE_XXX)

Thanks in advance!

Upvotes: 2

Views: 6192

Answers (5)

Elvedin Hamzagic
Elvedin Hamzagic

Reputation: 855

This question has already correct answers, i.e. the same Editor which is used to put data in, should then be used to commit data. I just want to point out that it can be written in single line:

pref.edit().putInt("widgetCount", iCount).commit();

It's nice and elegant and that's the way it's meant to be done. You can expand it numerous times:

pref.edit().putInt("data1", data1).putInt("data2", data2).putBoolean("data3", data3).commit();

But if you write data in loop, then you should first create Editor, then reuse it in the loop. Because the Editor is a local cache, it saves activity from accessing persistent storage too often.

Upvotes: 1

Pradeep Kumar
Pradeep Kumar

Reputation: 877

Replace:

        SharedPreferences pref = context.getApplicationContext().getSharedPreferences("widget_pref", Context.MODE_PRIVATE );
        int iWidgetId = intent.getExtras().getInt("widgetId");
        int iCount = pref.getInt("widgetCount", 0);

        // HERE IS THE PROBLEM, iCount will always start from 0!
        for ( int i = 0; i < 10; i++ ) {
            iCount = pref.getInt("widgetCount", 0);
            iCount++;
            pref.edit().putInt("widgetCount", iCount);
            boolean bSaved = pref.edit().commit(); // return TRUE
            bSaved = pref.contains("widgetCount"); // return FALSE
            Log.w(TAG, "WidgetProvider.onReceive: " + iWidgetId + " > " + iCount + " result: " + bSaved);
        }

by

        SharedPreferences pref = context.getApplicationContext().getSharedPreferences("widget_pref", Context.MODE_PRIVATE );

        int iWidgetId = intent.getExtras().getInt("widgetId");
        int iCount = pref.getInt("widgetCount", 0);
                // HERE IS THE PROBLEM, iCount will always start from 0!
        for ( int i = 0; i < 10; i++ ) {
           pref = context.getApplicationContext().getSharedPreferences("widget_pref", Context.MODE_PRIVATE );
            iCount = pref.getInt("widgetCount", 0);
            iCount++;
            pref.edit().putInt("widgetCount", iCount);
            boolean bSaved = pref.edit().commit(); // return TRUE
            bSaved = pref.contains("widgetCount"); // return FALSE
            Log.w(TAG, "WidgetProvider.onReceive: " + iWidgetId + " > " + iCount + " result: " + bSaved);
        }

Because you have to take updated preference each time when you want to fetch or read it..

Upvotes: 1

Na Felix Wimpy Wijaya
Na Felix Wimpy Wijaya

Reputation: 332

change these 2 code

pref.edit().putInt("widgetCount", iCount);
boolean bSaved = pref.edit().commit();

with

SharedPreferences.Editor ed = pref.edit();
ed.putInt("widgetCount", iCount);
ed.commit();

because everytime you call pref.edit() it will create a new object, and you do 'commit' a new object instead of the one you already called putInt method.

Upvotes: 2

Pratik Butani
Pratik Butani

Reputation: 62411

Edit your Code Like:

I have declared SharedPreferences.Editor object before for loop and then reuse in loop:

Try it:

SharedPreferences pref = context.getApplicationContext().getSharedPreferences("widget_pref", Context.MODE_PRIVATE );
int iWidgetId = intent.getExtras().getInt("widgetId");
int iCount = pref.getInt("widgetCount", 0);

/**** ADD THIS LINE ****/
SharedPreferences.Editor prefEditor = pref.edit();


// HERE IS THE PROBLEM, iCount will always start from 0!
for ( int i = 0; i < 10; i++ ) {
    iCount = pref.getInt("widgetCount", 0);
    iCount++;

    /** Edit Here Like **/
    prefEditor.putInt("widgetCount", iCount);
    prefEditor.commit();

    //boolean bSaved = prefEditor.commit(); // return TRUE
    bSaved = pref.contains("widgetCount"); // return FALSE

    Log.w(TAG, "WidgetProvider.onReceive: " + bSaved);
}

Comment if you any prob.

Upvotes: 2

Zennichimaro
Zennichimaro

Reputation: 5306

You are creating a new SharedPreferences.Editor object every time by calling pref.edit(). Cache the SharedPreferences.Editor object before entering the for loop and re-use that instance.

Upvotes: 7

Related Questions