Use of Shared Preferences and Intent - Setup and Settings application - android

I am currently developing an application that on the first time the application opens, shows the setup interface and the succeeding times the application is opened, it shows the settings interface. The way I achieved this is that once my application opens, it checks if the shared preferences is null. If the shared preferences is null, it means it was the first time that the application is opened and it will set a value in the shared preferences. Then the next time that the application is opened, when the shared preferences is checked, it isn't null anymore and will go to the settings interface. The problem is, When I run it the first time, it only shows a white screen with no status bar or anything. Below are code snippets of my application
private void saveSharedPref()
{
SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES_FILE, 0);
SharedPreferences.Editor editor = preferences.edit();
//Save values from Edit Text Controls
editor.putString("firstTime", "1234");
editor.commit();
}
private void loadSharedPreferences()
{
SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES_FILE, 0);
//Null check in case file does not exist
if(preferences != null) {
String checkFirst = preferences.getString("firstTime", "");
if (!checkFirst.equalsIgnoreCase("1234"))
{
Intent sendToSetup = new Intent (this, Setup.class);
startActivity(sendToSetup);
}
else
{
saveSharedPref();
}
}
}
I call loadSharedPreferences() in my onCreateMethod
public class Setup extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setup_pg1);
}
This is where the app gets redirected when the user open it for the first time.
Any help would be greatly appreciated. Thanks in advance!
P.S. sorry if my english isnt good
EDIT:
here's the androidmanifest
<?xml version="1.0" encoding="utf-8"?>
<application
android:allowBackup="true"
android:icon="#drawable/icon1"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".SafeSwipe"
android:label="SafeSwipe-UI v.2"
android:theme="#style/AppTheme.NoActionBar">
</activity>
<activity
android:name=".MainActivity"
android:label=""
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Setup" />
</application>
setup_pg1
<TextView
android:text="Setup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="102dp"
android:id="#+id/textView" />
<Button
android:text="Continue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView"
android:layout_alignRight="#+id/textView"
android:layout_alignEnd="#+id/textView"
android:layout_marginTop="71dp"
android:id="#+id/button7" />
setup file
public class Setup extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setup_pg1);
}
}

First, if(preferences != null) will never be true because you'll always get a non-null value from getSharedPreferences()
I call loadSharedPreferences() in my onCreate Method
No you don't... here's your code
public class Setup extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setup_pg1);
}
}
Try again. But use a boolean value rather than some random string.
public class MainActivity extends AppCompatActivity {
public static final String PREFS_NAME = "MyPrefsFile";
public static final String KEY_FIRST_TIME = "firstTime";
#Override
protected void onCreate(Bundle b){
super.onCreate(b);
setContentView(R.layout.activity_main);
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
boolean firstTime = prefs.getBoolean(KEY_FIRST_TIME, false);
if (!firstTime) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(KEY_FIRST_TIME, true);
editor.commit();
} else {
Intent sendToSetup = new Intent (this, Setup.class);
startActivity(sendToSetup);
finish();
}
}
}

Try this:
Instead of checking preferences != null try this..
if (preferences.getString("firstTime","").equals("1234"))
{
Intent sendToSetup = new Intent (this, Setup.class);
startActivity(sendToSetup);
}
else
saveSharedPref();

Your if(preferences != null)is not working here, cause preferences is not null. It's just an empty preference. You can try out the below code:
private void loadSharedPreferences()
{
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String checkFirst = preferences.getString("firstTime", "");
if(!checkFirst.equals("")) {
Intent sendToSetup = new Intent (this, Setup.class);
startActivity(sendToSetup);
}
else
{
saveSharedPref();
}
}
saveSharedPref() method:
private void saveSharedPref()
{
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
//Save values from Edit Text Controls
preferences.edit().putString("firstTime", "1234").apply();
}
Call loadSharedPreferences() in onCreate() of Setup Activity:
Hope this helps.

I don't see any crucial problem in this code. But I have some assumption that you have already called the saveSharedPref() method while testing your program and value of firstTime is already exist. Because SharedPreferences are not deleted after recompiling the program this statement:
if (!checkFirst.equalsIgnoreCase("1234"))
gives false.
The best way to check this is to set a breakpoint in loadSharedPreferences() method and verify it.
If it is so try to remove sharedPreferences (see the answer https://stackoverflow.com/a/3687333/7677939 )
or simply give another file name in SHARED_PREFERENCES_FILE variable.
Also it can be a problem in place where you call loadSharedPreferences(), but I cannot see it in your source.
Update:
Notice, that you should not call loadSharedPreferences() in Setup activity, you should call it in your Main activity!

Related

Confused on Reading SharedPreferences Without a PreferenceActivity

Because I want an AppCompat Action Bar on all of my settings submenus, I had to implement a workaround and my Settings Activity extends AppCompatActivity, not PreferenceActivity. I'm using a PreferenceFragment in the activity to handle the preferences, and each PreferenceScreen has its own xml file, which the PreferenceFragment switches out for each submenu in the settings. All of this was necessary to get the Action Bar to stay put through all of my submenus.
I'm trying to read a string value from the shared preferences file from within my MainActivity, and I've tried three different methods for getting that information, none of which have worked:
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String btSelectPref = sharedPref.getString(getString(R.string.bt_select_key), "");
,
SharedPreferences sharedPref = getSharedPreferences(name, MODE_PRIVATE);
String btSelectPref = sharedPref.getString(getString(R.string.bt_select_key), "");
and
SharedPreferences sharedPref = getPreferences(MODE_PRIVATE);
String btSelectPref = sharedPref.getString(getString(R.string.bt_select_key), "");
Here is the relevant section of my preferences.xml:
<PreferenceCategory
android:title="Bluetooth"
android:key="pref_bt">
<Preference
android:title="Select Bluetooth Device"
android:key="#string/bt_select_key"
android:defaultValue="0">
</Preference>
</PreferenceCategory>
This should fill the btSelectPref string with a "0", but it's always empty when I test it. I have included PreferenceManager.setDefaultValues(this, R.xml.preferences, false); in onCreate in my MainActivity, so the default values should be set.
I'm not sure which of these methods I should be using since I have multiple resource files for my settings, but none of them seem to be working for me. In the case of getSharedPreferences(name, MODE_PRIVATE), I have no idea what the name parameter should be referencing, since I've never named my shared preferences file.
EDIT: It turns out my issue was not related to getting values from the shared preferences file. I just had the wrong xml tag on the preference I was trying to check the value of. I changed it from a generic <Preference> tag to a <ListPreference> and my code started working with PreferenceManager.getDefaultSharedPreferences().
What you want to do and what you are doing differs. If you just want to put default shared preference for a key then consider this example. If your whole activity has just one shared pref file then you need not specify any name. It will automatically get it.
public MainActivity extends AppCompatActivity {
SharedPreferences mPrefs;
int test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_counter);
mPrefs = this.getPreferences(Context.MODE_PRIVATE);
test = mPrefs.getInt("pref_bt_select", 0);}
}
For the above example you can define the key and default value in your strings.xml and then you can refer to it while looking for the prefs you want.
Hey I have used AppCompat for my preference screen too.I did this because I wanted to use Vintage Chroma and this was the only way. But I am able to use PreferenceManager.getDefaultSharedPreference() without any errors.
Also if you want to use default shared preferences in the Fragment you can use :
SharedPreferences preferences = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);
Here is my full code :
public class PreferencesActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager()
.beginTransaction()
.replace(android.R.id.content, new PreferencesScreen())
.commit();
ActionBar toolbar = getSupportActionBar();
if (toolbar != null) {
toolbar.setDisplayHomeAsUpEnabled(true);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
public static class PreferencesScreen extends PreferenceFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings_xml);
}
}
}
Here is my code snippet for MAinActivity
Just the initial part where I set the default text theme.
`public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
AutoCompleteTextView mytextview;
public static String[] list;
ArrayList<String> recent = new ArrayList<String>();
public int recent_index = 0;
Menu mMenu;
#Override
protected void onCreate(Bundle savedInstanceState) {
/*Setting default theme.*/
SharedPreferences Sp= PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
int firstRun=Sp.getInt("firstRun",0);
if(firstRun==0)
{
SharedPreferences.Editor editor=Sp.edit();
editor.putInt("paragraphFontColor", Color.parseColor("#ffffff"));
editor.putInt("headingFontColor",Color.parseColor("#DE5246"));
editor.putInt("subheadingFontColor",Color.parseColor("#597d5e"));
editor.putInt("hyperlinksFontColor",Color.parseColor("#A5D8F5"));
editor.putInt("bodyColor",Color.parseColor("#2b2b2b"));
editor.putString("paragraphFont","PrintClearly.otf");
editor.putString("headingFont","PrintBold.otf");
editor.putString("subheadingFont","PrintBold.otf");
editor.putString("hyperlinkFont","PrintBold.otf");
editor.putString("paragraphFontStyle","normal");
editor.putString("headingFontStyle","normal");
editor.putString("subheadingFontStyle","normal");
editor.putString("hyperlinkFontStyle","normal");
editor.putString("actionBarColor","#597d5e");
editor.putString("paragraphFontSize","20px");
editor.putString("headingFontSize","30px");
editor.putString("subheadingFontSize","20px");
editor.putString("hyperlinkFontSize","20px");
editor.putString("firstRun",0);
editor.commit();
}
`

How to assign initial value to a String in Android

i don´t know where i have to setup the initial value of this variable:
mySharedPreferences.putStringValue("hello", "400");
And it don´t be reset if it is changed every time i open the app.
Thank you!!
The best way to do that is to "set" the default value on get method instead of set it on the first start of your app.
mySharedPreferences.getString("hello", "400");
On this way android checks if there was an value set. If not, it will fallback to the default "400".
Take a look at the documentation:
https://developer.android.com/reference/android/content/SharedPreferences.html#getString(java.lang.String, java.lang.String)
And in application tag
<application
android:name=".YourApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme">
In Application's onCreate Method. It is best place. It will be executed when your app is created.
public class YourApplication extends Application {
public static Boolean sAppOpened = false;
#Override
public void onCreate() {
super.onCreate();
//Write your code here
sAppOpened = true;
....
}
...
}
Declare your SHARED PREFERENCE file name class-wide like this -
public static final String SHARED_PREFERENCES = "SHARED_PREF";
You can use this in your OnCreate method.
SharedPreferences sharedpreferences = getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE);
Editor editor = sharedpreferences.edit();
editor.putString("key", "value");
editor.commit();

SharedPreferencesBackupHelper auto restore doesn't work

I'm trying to use SharedPreferencesBackupHelper to save my SharedPreferences value to cloud.
AndroidManifest.xml
<application
android:allowBackup="true"
android:backupAgent=".DataBackupAgent"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<meta-data android:name="com.google.android.backup.api_key" android:value="AEdPqrEAAAAIXMH86OqosQlXYuS0QbfyOaZT8fUadY1QUDzo2w" />
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
DataBackupAgent.java:
public class DataBackupAgent extends BackupAgentHelper {
public static final String PREFS = "data_prefs";
public static final String PREFS_BACKUP_KEY = "myprefs";
#Override
public void onCreate() {
SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, PREFS);
addHelper(PREFS_BACKUP_KEY, helper);
}
}
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
backupManager = new BackupManager(this);
prefs = getSharedPreferences(DataBackupAgent.PREFS, Context.MODE_PRIVATE);
edit = prefs.edit();
text = (EditText)findViewById(R.id.editText);
String value = prefs.getString(DataBackupAgent.PREFS_BACKUP_KEY,"");
text.setText(value);
Button btnBackup = (Button)findViewById(R.id.button);
btnBackup.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
edit.putString(DataBackupAgent.PREFS_BACKUP_KEY,text.getText().toString());
edit.commit();
backupManager.dataChanged();
}
});
}
My steps:
Write something at the EditText, click Backup button
Close app and open again. The saved value will be shown in EditText
Uninstall the app and reinstall again. The saved value is not shown in EditText at all.
Edit at 27/02/2015:
I added the following code to restore manually:
backupManager.requestRestore(new RestoreObserver() {
#Override
public void restoreFinished(int error) {
super.restoreFinished(error);
String value = prefs.getString(DataBackupAgent.PREFS_BACKUP_KEY,"");
text.setText(value);
}
#Override
public void restoreStarting(int numPackages) {
super.restoreStarting(numPackages);
}
#Override
public void onUpdate(int nowBeingRestored, String currentPackage) {
super.onUpdate(nowBeingRestored, currentPackage);
}
});
Unfortunately no callback functions are called.
This means back or auto restore doesn't work at all. Any idea? Thanks
My steps:
1. Write something at the EditText, click Backup button
2. Close app and open again. The saved value will be shown in EditText
3. Uninstall the app and reinstall again. The saved value is not shown in EditText at all.
To test your implementation there are others steps related to the use of bmgras we can see here.
Nevertheless I implemented this feature some days ago and following the steps in the documentation using a real device - Samsung SII - the automatic restore doesn't happen BUT using the emulator all was fine.
Logcat will show you all the operation output details.
IMO, the Android Data Backup feature is not reliable today. We can see some discussion about the implementation problems here and here.
Hope it helps!

Android where to declare SharedPreferences

Im trying to use edittexts on my second activity to change strings on my first/main activity. So to do that, one must use SharedPreferences.
At the top of my second activity, I had declared them and an editor. It causes a nullpointexception error and crashes the code. I'm not sure where to initalize this as I want the sharedPreferences to be looked at in the main/first activity.
SharedPreferences settings = getSharedPreferences("prefs", 0);
SharedPreferences.Editor editor = settings.edit();
Also, is this proper code to put in the sharedprefs dictionary?
if(!introstring.isEmpty()) //if the fields are NOT empty, they should get saved.
{
editor.putString("intro", introstring);
}
At the top of my second activity
You mean as fields - yes this will cause a NPE for reasons explained in Why getApplicationContext() in constructor of Activity throws null pointer exception?
So as suggested in the comments you need to
class YourSecondActivity extends Activity {
SharedPreferences sp;
Editor e;
protected void onCreate() {
sp = PreferenceManager.getDefaultSharedPreferences(this); // forget about
// named preferences - get the default ones and finish with it
e = sp.edit();
}
meth() {
//...
if(!introstring.isEmpty()) { // save the fields if NOT empty
e.putString("intro", introstring);
e.commit(); // you forgot to commit
}
}
}
My way of handling SharedPrefrences is to create a class that will extend Application class and put SharedPrefrences there so that will be accessible everywhere in the app.
class MyApp extends Application{
SharedPreferences sharedPreferences;
public void onCreate() {
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
}
public static getSharedPrefrences(){
return sharedPrefrences;
}
}
you have to put declare the name tag of the application in the activity tag
<application
android:allowBackup="true"
android:name=".fundamentals.UploadApp"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
....
....
</application>
Then, you can access it from any Activity that you want.
class SomeActivity extends Activity{
onCreate(){
SharedPrefences prefs = MyApp.getSharedPrefrences();
}
}
also, you need to commit the change after you have put something in the SharedPrefrences
if(!introstring.isEmpty()) //if the fields are NOT empty, they should get saved.
{
editor.putString("intro", introstring).commit();
}

Shared preferences only saved first time

The program creates preferences the first time but after that it never changes them. I would appreciate assistance in understanding why.
This is the PreferencesScreen where the xml is called.
public class PreferencesScreen extends PreferenceFragment{
private final String TAG = "PreferencesScreen";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "OnCreate");
addPreferencesFromResource(R.xml.prefs);
}
In the preferences I have a ListPreference and a Preference which calls an activity to store emails.
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="Information Collected">
<ListPreference
android:key="loggins"
android:title="Logs Stored"
android:summary="Choose the top kind of logs do you want to store."
android:dialogTitle="Choose Logs"
android:entries="#array/logs"
android:entryValues="#array/logsValues"/>
</PreferenceCategory>
<PreferenceCategory android:title="Email Configurations">
<Preference
android:key="pushing"
android:title="The Email Activity"
android:summary="Just push">
<intent android:action = "ADDING_EMAIL"/>
</Preference>
</PreferenceCategory>
</PreferenceScreen>
Everything until here. The problems are in the activity called...
public class AddingEmail extends ListActivity implements OnClickListener{
private Set<String> emails;
private EditText emailAdd;
SharedPreferences.Editor editor;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.addingemail);
Button add = (Button) findViewById(R.id.add);
emailAdd = (EditText) findViewById(R.id.email);
prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
editor = prefs.edit();
prefList = toArrayList(prefs.getStringSet("emailWrongs", null));
add.setOnClickListener(this);
}
public void onClick(View v) {
Set<String> list = prefs.getStringSet("emailWrongs", null);
String newEmail = emailAdd.getText().toString();
if (list==null){ //first time the preferences are called.
emails = new TreeSet<String>();
editor.putStringSet("emailWrongs", emails);
editor.apply();
}
if (newEmail != ""){
emails=prefs.getStringSet("emailWrongs", null);
emails.add(newEmail);
editor.putStringSet("emailWrongs", emails);
editor.apply();
}
}
}
The point is that it always stores the first time well but if I when I add another email the preferences doesnt't change. They looks like they change because if I printed them they show all the emails I add but the preference file doesn't change (Checking it in the File Explorer). And if i reboot or close and open again, the preferences are only with the first email I add.
The thing is if i back to and change the preference of the ListPreference, then it stores all the changes even the emails I added.
Hope I was clear, it has a lot of code because i wanted to be very explicit.
Thank you for the help.
After more than a week looking for the mistake I found it.
I think this can be helpful for a lot of people who had the same trouble.
The problem was that when I call the preferences to get the String Set, it only reference the list and not make a copy of it. So I have to create a new list and add all the elements stored before and also add the new element and then with the editor change the preferences with the new list.
The code is like this:
Set<String> list = prefs.getStringSet("emailWrongs", null);
Set<String> newList = new TreeSet<String>();
String newEmail = emailAdd.getText().toString();
if (newEmail != ""){
if (list != null){
for(String each: list){
newList.add(each);
}
}
newList.add(newEmail);
editor.putStringSet("emailWrongs", newList);
editor.apply();
}
For storing a Stringset, a better way to do this is to first remove the last SharedPreferences value, then save the new one with the same key. Like this:
defaultSharedPreferences.edit().remove("keysValue").commit();
defaultSharedPreferences.edit().putStringSet("keysValue",likesset).commit();

Categories

Resources