0

I have defined some SharedPreferences in my Main Activity (called ScoreboardActivity). The values are definitely either getting retrieved or the correct default value is working. However, I have now tried to setup a SettingsActivity screen so that the user can change these values and it isn't working correctly. When the new Activity is opening, the values aren't loading into the fields in the XML layout.

(as you will be able to tell, I'm very new to this so please be kind)

Here is my ScoreboardActivity code related to the Shared Preferences (this works):

// get the preferences
        prefs = getPreferences(MODE_PRIVATE);

        // Load the values or defaults from the SharedPreferences
        msMainClockStart = prefs.getLong( "Default_Main_Clock", 480000);    // 8 minute default
        useShotClock = prefs.getBoolean( "Use_ShotClock", false );
        msShotClockStart = prefs.getLong( "Default_Shot_Clock", 24000);     // 24 second default
        tvPeriodPrefix = prefs.getString( "Period_Prefix", getResources().getString(R.string.period) );
        valMaxPeriods = prefs.getInt( "Max_Periods", 4);


Here is my code when the menu button is pressed and Settings is clicked on (I think this is wrong but the settings.xml page does open:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        setContentView(R.layout.settings);

        return super.onOptionsItemSelected(item);
    }

Here is my SettingsActivity:

 package com.example.ultimatescoreclock;

    import android.app.Activity;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.widget.CheckBox;
    import android.widget.EditText;

    public class SettingsActivity extends Activity {

    ScoreboardActivity scoreboard = new ScoreboardActivity();
    SharedPreferences settings = scoreboard.prefs;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        EditText
            strMainMinutes,
            strShotSeconds,
            strPeriodPrefix,
            strMaxPeriods;

        CheckBox
            cbUseShotClock;

        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings);

        // Load the values or defaults from the SharedPreferences
        scoreboard.msMainClockStart = settings.getLong( "Default_Main_Clock", 480000);  // 8 minute default
        scoreboard.useShotClock = settings.getBoolean( "Use_ShotClock", true );
        scoreboard.msShotClockStart = settings.getLong( "Default_Shot_Clock", 24000);       // 24 second default
        scoreboard.tvPeriodPrefix = settings.getString( "Period_Prefix", getResources().getString(R.string.period) );
        scoreboard.valMaxPeriods = settings.getInt( "Max_Periods", 4);

        strMainMinutes = (EditText) findViewById(R.id.numMainMinutes);
        cbUseShotClock = (CheckBox) findViewById(R.id.cbUseShotClock);
        strShotSeconds = (EditText) findViewById(R.id.numShotSeconds);
        strPeriodPrefix = (EditText) findViewById(R.id.periodPrefix);
        strMaxPeriods = (EditText) findViewById(R.id.periodMax);


        strMainMinutes.setText( Long.toString(scoreboard.msMainClockStart / 1000) );
        cbUseShotClock.setChecked( scoreboard.useShotClock );
        strShotSeconds.setText( Long.toString(scoreboard.msShotClockStart / 1000) );
        strPeriodPrefix.setText( scoreboard.tvPeriodPrefix );
        strMaxPeriods.setText( Integer.toString(scoreboard.valMaxPeriods) );
    }


}

Here is my XML Layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
    android:id="@+id/lblMainClock"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Main Clock Default (mins)" />

<EditText
    android:id="@+id/numMainMinutes"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:ems="10"
    android:inputType="number"
    android:minEms="4" />

<CheckBox
    android:id="@+id/cbUseShotClock"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical|start"
    android:text="Use Shot Clock" />

<TextView
    android:id="@+id/lblShotClock"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Shot Clock Default (secs)" />

<EditText
    android:id="@+id/numShotSeconds"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:ems="10"
    android:inputType="number"
    android:minEms="4" >

    <requestFocus />
</EditText>

<TextView
    android:id="@+id/lblPeriodPrefix"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Period Prefix (e.g. Q, Shift, etc)" />

<EditText
    android:id="@+id/periodPrefix"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10" />

<TextView
    android:id="@+id/lblMaxPeriods"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Maximum Number of Periods" />

<EditText
    android:id="@+id/periodMax"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:minEms="4" />

Sahil Mahajan Mj
  • 11,033
  • 8
  • 53
  • 100
Jim Thornton
  • 123
  • 1
  • 9
  • 1
    A (probably) related note: Why are you instantiating an activity using `new ScoreboardActivity()`? – Cat Dec 31 '12 at 05:38
  • SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); // then you use prefs.getBoolean("keystring", true); you should use above lines.. according to string and boolean. – itsrajesh4uguys Dec 31 '12 at 05:49
  • @Eric - Because I am very new and trying to figure this out. I have almost no OOP experience. The variables msMainClockStart, useShotClock (etc) are all defined in the ScoreboardActivity. Without instantiating the ScoreboardActivity Eclipse was not recognizing the variables. What is the better way to do this? – Jim Thornton Dec 31 '12 at 06:40
  • @Eric - Oh, I forgot. In the onCreate() method of my main activity (ScoreboardActivity) I have already retrieved the preferences and assigned them to the variables for the Activity. So I figured it would be better to just access the values from the scoreboard object from within the SettingsActivity. Does that explain my (probably incorrect) thought process? – Jim Thornton Dec 31 '12 at 06:44

2 Answers2

1

You should really learn basics of android first.

The way you are instantiating ScoreboardActivity is not the android's way of instantiation of Activity.

In your code, I didn't find any code related to SAVING DATA to SharedPreferences. the code you put there is only for retrieving data from SharedPreferences in both classes.

and when you change values using UI components, like changing the CheckBox state, changing the text in EditText etc, you need to save them again to SharedPreferences while you are finalizing the value (asking user to save or finishing current Activity).

I would suggest you to read some basics of android-sdk.

  • Here are some example and explanation on saving and retrieving data from SharedPreferences
  • Here is an android tutorial about how to start Activity. (switching between Activities)
Community
  • 1
  • 1
Adil Soomro
  • 37,609
  • 9
  • 103
  • 153
  • Thanks for the tutorials, I will definitely read them. The reason I'm building this app is to "learn the basics of android". I'm on these forums to learn as well. I have read and am learning as I go and coming to the forums when I don't understand something or it doesn't work. I first search for the answers, but they aren't always easy to find if you don't know what to search for. The SharedPreferences was found by searching. Also, I am aware that I don't have any data saving methods yet. But there is no point having a method to save data if I first can't get it to appear on the screen. – Jim Thornton Dec 31 '12 at 13:51
  • @JimThornton: correct, but how could you get data from `SharedPreferences` without prior saving it. this way you would only get null values or fase boolean. – Adil Soomro Dec 31 '12 at 13:56
  • From the defaults that are set in get methods. For example, `getBoolean("Use_Shot_Clock", false);` would default to false (from my understanding. So, my thought was (for new installations) they would start the app and the defaults are set. If they decide to change something (once I add the save method) then the XML preference file would be created and then next time it would retrieve the saved values instead of the defaults. I figured if I just create a save method at the beginning of my code it would overwrite the previous changed values. What is the correct what to do this? (pseudo code) – Jim Thornton Dec 31 '12 at 16:08
  • Thanks for the help to get me in the right direction. I have added an answer with detailed code but if you could tell me one thing I would appreciate it. I think it is very redundant to have the getPreferences in both the main activity and the Settings class especially since you have to type in a default value. So I created constants in the main activity with the default values (i.e. DEFAULT_MAIN_CLOCK_START) but when I go to use them in the settings activity Eclipse doesn't recognize them. Is there a better way to do this or do I just import my main activity? – Jim Thornton Dec 31 '12 at 22:31
  • 1
    Thats great, yeah the default values can be written as `public static final String` variables in some `Utils` class so that you can access them globally like `Utils.DEFAULT_MAIN_CLOCK_START` etc. – Adil Soomro Jan 01 '13 at 06:13
0

@Eric & @Adil Soomro - Thank you for your comments. You have put me on the right track and I have discovered how to accomplish the retrieving of the SharedPreferences in my SettingsActivity.

Here is my altered code for anyone that might be interested in the future...

Main Activity code retrieving the initial values:

    // get the preferences
    prefs = getPreferences(MODE_PRIVATE);

    // Load the values or defaults from the SharedPreferences
    msMainClockStart = prefs.getLong( "Default_Main_Clock", DEFAULT_MAIN_CLOCK_START);
    useShotClock = prefs.getBoolean( "Use_ShotClock", DEFAULT_USE_SHOT_CLOCK );
    msShotClockStart = prefs.getLong( "Default_Shot_Clock", DEFAULT_SHOT_CLOCK_START);
    tvPeriodPrefix = prefs.getString( "Period_Prefix", DEFAULT_PERIOD_PREFIX );
    valMaxPeriods = prefs.getInt( "Max_Periods", DEFAULT_PERIOD_MAX );

The onOptionsItemSelected method:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    Intent intent = new Intent(this, SettingsActivity.class);       
    startActivity(intent);

    return super.onOptionsItemSelected(item);
}

The SettingsActivity class:

package com.example.ultimatescoreclock;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.CheckBox;
import android.widget.EditText;

public class SettingsActivity extends Activity {

EditText
    strMainMinutes,
    strShotSeconds,
    strPeriodPrefix,
    strMaxPeriods;

long
    msMainClockStart,
    msShotClockStart;

int valMaxPeriods;

CheckBox cbUseShotClock;

SharedPreferences prefs;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.settings);

    // get the Shared Preferences
    prefs  = getPreferences(MODE_PRIVATE);

    // assign the views
    strMainMinutes = (EditText) findViewById(R.id.numMainMinutes);
    cbUseShotClock = (CheckBox) findViewById(R.id.cbUseShotClock);
    strShotSeconds = (EditText) findViewById(R.id.numShotSeconds);
    strPeriodPrefix = (EditText) findViewById(R.id.periodPrefix);
    strMaxPeriods = (EditText) findViewById(R.id.periodMax);

    // Load the values or defaults from the SharedPreferences
    msMainClockStart = prefs.getLong( "Default_Main_Clock", DEFAULT_MAIN_CLOCK_START);
    cbUseShotClock.setChecked( prefs.getBoolean( "Use_ShotClock", DEFAULT_USE_SHOT_CLOCK) );
    msShotClockStart = prefs.getLong( "Default_Shot_Clock", DEFAULT_SHOT_CLOCK_START);
    strPeriodPrefix.setText( prefs.getString("Period_Prefix", DEFAULT_PERIOD_PREFIX) );
    valMaxPeriods = prefs.getInt( "Max_Periods", DEFAULT_PERIOD_MAX );

    // convert the values that need converting
    strMainMinutes.setText( Long.toString(msMainClockStart / 60000) );
    strShotSeconds.setText( Long.toString(msShotClockStart / 1000) );
    strMaxPeriods.setText( Integer.toString(valMaxPeriods) );

}

}
Jim Thornton
  • 123
  • 1
  • 9