I have an issue, i have to set a whole host of settings prior to running my main app. These are done through an on-boarding process, however this is not being reflected in my main settings once in the main app.
During on-boarding i set:
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
int radioId = checkedId;
radioButton = getActivity().findViewById(radioId);
String str = (String) radioButton.getText();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MyApplication.getAppContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(kDirection, str).apply();
editor.commit();
}
});
My Preference:
<PreferenceCategory app:title="Directions">
<ListPreference
app:key="kDirectionSetting"
app:entryValues="#array/directions"
android:entries="#array/directions"
app:useSimpleSummaryProvider="true"
app:title="Direction Preference"
/>
</PreferenceCategory>
This is reflected in my preferences If i open them in device file explorer before i open the preferences screen. Then when the main menu is opened and the preference screen loaded the String is changed to an unset default value from my array, the same every time.
How do i get the reflected changes to show in my settings first time?
I think that if you have the same key for both your ListPreference and the initial Preference value that you stored, then you will get the ListPreference to edit the initial value. However, do this to set the default value to the ListPreference:
#Override
public void onCreate(Bundle savedInstanceState) {
ListPreference kDirectionPref = (ListPreference) findPreference("kDirectionSetting");
kDirectionPref.setDefaultValue(prefs.getString("kDirection"));
So basically, what I'm saying is that you should ensure that you use the same key to put values for your Preference, i.e. in the first piece of code, kDirection should be changed to "kDirectionSetting".
Related
Im making wallpaper app which it has a setting button for users which could adjust how many circle can be drawn on the wallpaper. Here i set 5 as default value in the preferences.xml . When i install the app,the wallpaper constructor get the number of circles in preference.xml which just 0 and i have to manually press setting button and set the number. So I want the keep the number is 5 ( default) when installing the app.
Some class that use for the App:
preferences.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference android:key="numofparticles" android:title="Number of particles" android:summary="Chose a initial particle's number" android:defaultValue="5">
</EditTextPreference>
</PreferenceScreen>
Prefernces.java
public class Preferences extends PreferenceActivity {
public static String numofparticles="numofparticles";
public static String image="getimage";
private static final int Pic_image=1;
private SharedPreferences.OnSharedPreferenceChangeListener PreferenceChangeListener;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
PreferenceChangeListener=new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
if (s.equals(numofparticles) && s.getClass().getSimpleName()=="Interger")
{
Preference numofP=findPreference(s);
numofP.setSummary(sharedPreferences.getString(s,"")+ " Particles");
Toast.makeText(getApplicationContext(),"success",Toast.LENGTH_SHORT);
}
}
};
Snippet from another class which i get this preference data.
public wallpaperengine()
{
display.getRealSize(size);
wallpaper_height=size.y;
wallpaper_width=size.x;
background=BitmapFactory.decodeResource(getResources(),R.drawable.particlebackground);
background=Bitmap.createScaledBitmap(background,wallpaper_width,wallpaper_height,true);
sharedPreferences= PreferenceManager.getDefaultSharedPreferences(particlewallpaper.this);
sharedPreferences.registerOnSharedPreferenceChangeListener(listener);
num_particle=Integer.valueOf(sharedPreferences.getString(Preferences.numofparticles,"5"));
handler.post(drawFrames);
}
The default 5 is in the layout file (which resides in xml folder of AS) for your preferences activity.
Not in the real preferences data file which resides in /data/data/package/shared_prefs/package_preferences.xml.
The wallpaper code reads from the real data file.
Not from the layout file.
And you know that that activity and layout file are not needed 'to work with shared preferences'.
Summary of problem: When I force close the app by opening task window and swiping it closed my if/else statement is not working properly. I have the Name Selection Activity as the Default Launcher Activity. The name selection Activity should only pop up if there are no Shared Prefs, meaning the user has not selected a name yet from the spinner. But even after the user has selected a name and it is stored in Share Prefs, when I force close the app I still get returned to the name selection activity
What I have tried I have tried if (stringNamePackage.equals("")) and if (stringNamePackage == "") and if (NAME.equals("")) and if (NAME == "") At first I thought it was because maybe my Shared Prefs was not saving the name correctly but it is not that, the name still appears correctly when I force close it. But when I try to add the if/else statment it always just sends me back to the name selection activity regardless if I have a name saved in Shared Prefs or not. I have spent 4 hours trying to get this to work and I am at my wits end. I also spent hours looking at different stack articles of how to save and retrieve Shared Pref data. I even tried how to check the SharedPreferences string is empty or null *android and it is still not working.
NameSelectionActivity
public class NameSelection extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
Spinner nameSpinner;
String stringNamePackage;
Button bSaveSelection;
Context context;
public ArrayAdapter<CharSequence> adapter;
public static String SHARED_PREFS = "sharedPrefs";
public static String NAME = "name";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_name_selection);
context = this;
nameSpinner = findViewById(R.id.horizonNameSpinner);
stringNamePackage = "";
//Create the list to populate the spinner
List<String> nameList = new ArrayList<>();
nameList.add("01");
nameList.add("02");
nameList.add("03");
//Array Adapter for creating list
//adapter = ArrayAdapter.createFromResource(this, R.array., android.R.layout.simple_spinner_item);
adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, nameList);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
nameSpinner.setAdapter(adapter);
nameSpinner.setOnItemSelectedListener(this);
//If User has not selected name, start this activity to allow user to pick Name, else, send user to Main Activity
//else start MainActivity
if (stringNamePackage .equals("")) {
Toast.makeText(this, "Welcome, please select Name", Toast.LENGTH_LONG).show();
} else {
Intent sendToMainActIntent = new Intent(this, MainActivity.class);
startActivity(sendToMainActIntent);
}
//Save Selection Button Code
bSaveSelection = findViewById(R.id.bSaveSelection);
bSaveSelection.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent myIntent = new Intent(view.getContext(), MainActivity.class);
//Saves name to SharedPrefs
saveName();
//Sends user to MainActivity
startActivity(myIntent);
finish();
}
});
}
//Stores name selected in SharedPreferences
public void saveName() {
SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = app_preferences.edit();
editor.clear();
//Stores selection in stringNamePackage
editor.putString(NAME, stringNamePackage );
editor.commit();
}
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
//Put user selection into String text
String text = adapterView.getItemAtPosition(i).toString();
stringNamePackage = text;
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
Main Activity
The purpose of this activity case is to send the user back to the name Selection screen when they hit the "Test" button which will erase the shared prefs and hence, trigger the if/else statement and making the user pick a name. This is how I get and set the Name in Main Activity:
in onCreate
Getting name
SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(context);
nameSharedPref = app_preferences.getString(NAME, "");
name.setText(nameSharedPref);
Clearing Name
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = mPrefs.edit();
editor.clear();
editor.commit();
finish();
What I expect: I expect the user to have to pick a name the first time they boot up the app. Then, every time they open the app an if/else statement will check if the user has a name or not in Shared Prefs. If they have a name they will go directly to the Main Activity. If they don't then they will go back to the Name Selection Activity.
To get data and store data to your SharedPreferences you use this:
SharedPreferences sharedPreferences = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
PreferenceManager.getDefaultSharedPreferences(context) is used to build "Settings" screens or similar, the first one you use it to store/retrieve arbitrary data not necessarily binded to UI.
Even more if you want to organize your SharedPreferences you could append to getPackageName() different keys like:
getSharedPreferences(getPackageName() + ".booleans", Context.MODE_PRIVATE);
getSharedPreferences(getPackageName() + ".flags", Context.MODE_PRIVATE);
getSharedPreferences(getPackageName() + ".keys", Context.MODE_PRIVATE);
each one of them is different file that stores shared preferences, you can ommit the prepending dot ., but for naming consistency it'll be better to keep it, there is no really need for the extra keys, but if you have some sort of OCD, that might be "relaxing" ;-).
Then you can use your Android Studio's Device Explorer to browse the shared preferences, they are located under "data/data/your.package.name/shared_prefs"
I've created a question and answer game with different levels, each level consisting a question. I didn't create it with a database. I just used string. When the user answers a question in level one he is taken to level two but when the user returns back to level one, he has to type the answer again even though he's solved it before. Is there anyway in JAVA to keep the answer in the type panel (if the user's solved it) without having to create a database?? Also, while typing in the type panel, the user has to delete the "Type here..." and then answer. Is there anyway that when user taps to type the "Type here..." is automatically erased?
Here's my level one activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
android:weightSum="1"
android:textAlignment="center"
android:id="#+id/level1">
<TextView
android:layout_width="300dp"
android:layout_height="200dp"
android:text="What has 88 keys but cannot open a single door?"
android:id="#+id/que1"
android:width="255dp"
android:textSize="30dp"
android:layout_margin="50dp"
android:textStyle="italic"
android:gravity="center" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/type1"
android:layout_gravity="center_horizontal"
android:text="Type here..." />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Check answer..."
android:id="#+id/check1"
android:layout_gravity="center_horizontal" />
</LinearLayout>
and here's my Oneactivity.java
package com.golo.user.gaunkhanekatha;
import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.os.Handler;
public class OneActivity extends Activity {
public SharedPreferences preferences; //ADDED THIS LINE
public Button check;
public EditText typeh;
private Toast toast;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);
toast = Toast.makeText(OneActivity.this, "", Toast.LENGTH_SHORT);
check = (Button)findViewById(R.id.check1); //R.id.button is the id on your xml
typeh = (EditText)findViewById(R.id.type1); //this is the EditText id
check.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
//Here you must get the text on your EditText
String Answer = (String) typeh.getText().toString(); //here you have the text typed by the user
//You can make an if statement to check if it's correct or not
if(Answer.equals("Piano") || (Answer.equals("Keyboard")))
{
preferences = PreferenceManager.getDefaultSharedPreferences(v.getContext());
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("Level 1 question 1 ", 1); //Depends of the level he have passed.
editor.apply();
///Correct Toast
toast.setText("Correct");
toast.setGravity(Gravity.TOP | Gravity.LEFT, 500, 300);
toast.show();
Intent i = new Intent(OneActivity.this, TwoActivity.class);
startActivity(i);
finish();
}
else{
//It's not the correct answer
toast.setText("Wrong! Try again...");
toast.show();
}
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
if(toast!= null) {
toast.cancel();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_aboutus, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Also, the toast is displayed where there's keyboard. Is there anyway to move the toast screen to somewhere on the screen where it is clearly visible?
I'll give to you two methods to do it :
Create a LevelEarned class as follows :
public class LevelEarned {
public static int level = 0;
}
Everytime you get an Intent (because user has answered the question correctly) just type :
LevelEarned.level = 1; // 1 depends with the level you have answered correctly
And the best method that it's that I'd use to this it's called SharedPreferences
You can use SharedPreferences to save any primitive data: booleans, floats, ints, longs, and strings. This data will persist across user sessions (even if your application is killed).
The first thing you have to do is store this data on SharedPreferences and you do it with an Editor as follows :
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(v.getContext());
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("player_level",1); //Depends of the level he have passed.
editor.apply();
NOTE
I guess you will do it immediately when the user accepts the question so, you'll do it on a Button click so you'll have to pass as a context v.getContext() if you are not on a ButtonClick and you are on your onCreate() just call this to refer your context.
To get the stored data (level) you'll need to do this :
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
int level = preferences.getInt("player_level", 0);
Let's explain to you a little bit.
The first parameter it's the key to find the SharedPreference so it won't change and the second one is a default value that it's used in case it doesn't find any "player_level" SharedPreferences.
Hope it helps to you to keep going in your code :)
EDIT2
Create SharedPreferences preferences as a global variable as follows :
public SharedPreferences preferences;
Then inside of your onClick() method add those lanes :
check.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
//Here you must get the text on your EditText
String Answer = (String) typeh.getText().toString(); //here you have the text typed by the user
//You can make an if statement to check if it's correct or not
if(Answer.equals("4") || (Answer.equals("four")))
{
preferences = PreferenceManager.getDefaultSharedPreferences(v.getContext());
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("player_level",1); //Depends of the level he have passed.
editor.apply();
//Create a Toast because it's correct
Toast.makeText(OneActivity.this, "Correct!",
Toast.LENGTH_LONG).show();
}
else{
//It's not the correct answer
Toast.makeText(OneActivity.this, "Wrong! Try Again",
Toast.LENGTH_LONG).show();
}
}
});
And where you want to know the level you only will have to do :
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
int level = preferences.getInt("player_level", 0); //level is the current level of the player.
EDIT 3
Create a class as follows :
public static class LevelPlayer(){
public int static getLevelPlayer(){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
int level = preferences.getInt("player_level", 0); //level is the current level of the playe
return level;
}
}
And every time you want to ask the level of the player you do :
int Level = LevelPlayer.getLevelPlayer(); //that's the level
So after every question you can ask the level and put the next question.
EDIT4
I've made some changes, delete your lvl class and put this code :
public class lvl{
public Context mcontext;
public lvl(Context context){
this.mcontext = context;
}
public int getLevelPlayer(){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mcontext);
int level = preferences.getInt("player_level", 0); //level is the current level of the playe
return level;
}
Then on your MainActivity(or wherever you have to know what's the level of the player) you have to put this :
public levelplayer mlevelplayer;
Then inside on your onCreate() add this :
mlevelplayer = new levelplayer(this);
int level = mlevelplayer.getLevelPlayer();
You can use SharedPreferences
To Write to shared preference
SharedPreferences sharedPref = context.getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.saved_high_score), newHighScore);
editor.commit();
to read
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);
it is simple. Just create a file to store information. You can do it in two ways.
one is to save a simple xml or json, the second one is to create a model of your answer and serialize a collection of them and save them in file.
Remember that you should do it in some kind of structure way: json, xml, serialized class. it is much simpler to work in future with that
You have a few options that you could try.
One option is as #Stultuske stated, you could try an XML or a TXT file stored on the users device. This (as well as a database) would persist between application sessions.
The other option that you have is you could create a singleton class.
For example, a class called Globals (as below) :
public class Globals {
private static Globals instance;
private String questionOneAnswer;
private Globals(){}
public String getQuestionOne()
{
return this.questionOneAnswer;
}
public void setQuestionOne(String questionOne)
{
this.questionOneAnswer = questionOne;
}
public static synchronized Globals getInstance()
{
if(instance==null)
{
instance=new Globals();
}
return instance;
}
}
This can then be called with Globals g = Globals.getInstance(); . This will only persist through your application instance; however, so if you are wanting to store it throughout app launches you can try the XML/TXT or SharedPreferences as stated by #shaikhmanzoor .
Also it is customary to define variable names with camelCase - ie answers rather than Answers, or typeH rather than typeh. Have a look here for the guidelines for Google Java coding.
For your first question just use SharedPreferences to save and fetch the data like this
SharedPreferences sharedPref = context.getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("level_no_answer", answer_given_by_user);
editor.commit();
and for your second question, you are using android:text="Type here..." in EditText. just replace that line by android:hint="Type here..."
I'm trying to achieve a goal which is adding some kind of wizard like this:
App launches for the first time > User follows wizard > Final wizard step saves some data into the SharedPreferences and continues to the activity that the user choosed > App Quits > App Relaunches > App shows activity that the user choose via the wizard data in SharedPreferences.
I know I can save data into the SharedPreferences space but how should I achieve this.
The user gets to see a view via an Android:OnClick action.
My App only has 1 main java class with different view actions like this:
public void myapp_confirmsetup(View view) {
setContentView(R.layout.activity_my_app_confirmsetup);
PreferenceManager.getDefaultSharedPreferences(this).edit().putString("MyApp", "app_off").commit();
}
I think that from now on I only have to load the string with the OnCreate method but I'm unsure how I can do that.
Can someone push me into the right direction?
use this to store the string...
final SharedPreferences pref1 = getSharedPreferences("myapp", MODE_PRIVATE);
SharedPreferences.Editor editor = pref1.edit();
editor.putString("Stringval", "xxxxxxx");
editor.commit();
to get the value from SharedPreference use below code:-
final SharedPreferences pref1 = getSharedPreferences("myapp", MODE_PRIVATE);
String str1= pref2.getString("Stringval", null);
final SharedPreferences pref1 = getSharedPreferences("myapp", MODE_PRIVATE);
String str1= pref1.getString("Stringval", null);
if(str1.equals("app_off")){
//do something
}else(str1.equals("app_on")){
//do something else
}
It's quite simple, all I need to do is save a high score (an integer) for the game. I'm assuming the easiest way to do this would be to store it in a text file but I really have no idea how to go about doing this.
If all you need is to store an integer then SharedPreferences would be best for you to use:
//setting preferences
SharedPreferences prefs = this.getSharedPreferences("myPrefsKey", Context.MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putInt("key", score);
editor.commit();
To get a preference:
//getting preferences
SharedPreferences prefs = this.getSharedPreferences("myPrefsKey", Context.MODE_PRIVATE);
int score = prefs.getInt("key", 0); //0 is the default value
Of course replace "key" with the key for your high score value and "myPrefsKey" with the key for your preferences (These can be whatever. It's just good to set them to something recognizable and unique).
I think this link will help you in it:
The SharedPreferences class provides a general framework that allows you to save and
retrieve persistent key-value pairs of primitive data types. You can use
SharedPreferences to save any primitive data: booleans, floats, ints, longs, and strings.
This data will persist across user sessions (even if your application is killed).
User Preferences
Shared preferences are not strictly for saving "user preferences," such as what ringtone
a user has chosen. If you're interested in creating user preferences for your
application, see PreferenceActivity, which provides an Activity framework for you to
create user preferences, which will be automatically persisted (using shared preferences).
To get a SharedPreferences object for your application, use one of two methods:
getSharedPreferences() - Use this if you need multiple preferences files identified
by name, which you specify with the first parameter.
getPreferences() - Use this if you need only one preferences file for your Activity.
Because this will be the only preferences file for your Activity, you don't supply a name.
To write values:
Call edit() to get a SharedPreferences.Editor.
Add values with methods such as putBoolean() and putString().
Commit the new values with commit()
To read values, use SharedPreferences methods such as getBoolean() and getString().
As I see, the best way for you to save high score is SharedPreferences.
Use shared preferences:
public class Calc extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
#Override
protected void onCreate(Bundle state){
super.onCreate(state);
. . .
// Restore preferences
SharedPreferences settings = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);
}
#Override
protected void onStop(){
super.onStop();
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);
// Commit the edits!
editor.commit();
}
}
It's easiest way to store such a things.
public class HighScores extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_high);
//get text view
TextView scoreView = (TextView)findViewById(R.id.high_scores_list);
//get shared prefs
SharedPreferences scorePrefs = getSharedPreferences(PlayGame.GAME_PREFS, 0);
//get scores
String[] savedScores = scorePrefs.getString("highScores", "").split("\\|");
//build string
StringBuilder scoreBuild = new StringBuilder("");
for(String score : savedScores){
scoreBuild.append(score+"\n");
}
//display scores
scoreView.setText(scoreBuild.toString());
}
}