Save variable to use over classes - java

I want to pass strings to all pages in my android app. When the user logs in I save userName and others to strings. I want to send the strings over multiple pages. How can I do that?
I have tried to send it through Intent
Intent myIntent = new Intent(view.getContext(), Help.class);
myIntent.putExtra("userName", userNameString);
startActivityForResult(myIntent, 0);
But when I go to another page I dont want to keep sending the data through Intent every time.
I have tried to get it from the class where I parse and put them in strings
HomeScreen home = new HomeScreen();
String userName= home.userNameString;
But since i am creating a new instance of the HomeScreen then userNameString is null
Any help will be greatly appreciated

Beware of using a static or instance variable to hold this state as the memory state of an Android application can be in flux. Data only stored in memory can be destroyed without your knowledge if your application process is killed while in the background.
The simplest mechanism would be to persist your data into SharedPreferences that you can access from any place in the application. So, first you save the string that you get from login (this is called inside an Activity, FYI):
//Write the username string to preferences
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.edit().putString("userName", userNameString).commit();
Then elsewhere in your application (i.e. other Activity instances) can read that string:
//Read the username string
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String userName = prefs.getString("userName", "");
With SharedPreferences, your values are actually persisted, meaning they will live forever on disk and won't go away just because your application's memory is reset (this is usually an advantage, especially for login information). Because of this, you will also need to remove the string when your user "logs out" like so:
//Remove the username string from preferences
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.edit().remove("userName").commit();
There are also methods like contains() to allow you to check if the value is currently saved (is the user logged in?), etc.

The calling Activity is not guaranteed to remain in memory... the Android system may destroy it at any time.
If the child Activity depends on the user name, then the correct means of passing the information is with an Intent.

Declare a static variable and use it from everywhere:
public class SomeClass
{
public static String userNameString;
}
Use it like:
Strign s = SomeClass.userNameString;
Change its value as:
SomeClass.userNameString = "new string";

Related

How is a session ID authenticated in SharedPreferences?

I am learning more about SharedPreferences and would like to understand how exactly everything is working. I have watched a decent amount of videos but I still have some questions.
Upon a user logging in, I generate a random session ID using UUID. I then assign the user their session ID and save a session by passing the UserModel into a SessionManagement instance that handles SharedPreferences.
userModel.setSessionId(UUID.randomUUID().toString());
SessionManagement sessionManagement = new SessionManagement(LoginActivity.this);
sessionManagement.saveSession(userModel);
When the user closes/opens the app, onStart() is called. It creates another instance of SessionManagement and checks if the session is null using getSession() to determine whether they're logged in or not.
SessionManagement sessionManagement = new SessionManagement(LoginActivity.this);
if (sessionManagement.getSession() != null) {
// go to some activity
}
And here is what SessionManagement constructor looks like:
private SharedPreferences sharedPreferences;
private final SharedPreferences.Editor editor;
private MasterKey masterKey;
//private String SHARED_PREF_NAME = "session";
private final String SESSION_KEY = "session_user";
private final String SESSION_USERNAME = "session_username";
public SessionManagement(Context context) {
try {
masterKey = new MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build();
} catch (GeneralSecurityException | IOException e) {
e.printStackTrace();
}
try {
sharedPreferences = EncryptedSharedPreferences.create(
context,
"secret_shared_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
} catch (GeneralSecurityException | IOException e) {
e.printStackTrace();
}
//sharedPreferences = context.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
}
My question now is, if I am just checking whether the session is null or not, how does SharedPreferences know that the sessionID corresponds to the user that initialized it in step 1?
What are the ways that people work around weak/exposed session ID's that a SharedPreferences implementation can protect against?
Is my implementation/flow correct?
Is it safe to save the sessionID to a user model?
I appreciate any help I can get with this topic!
I use SharedPreferences a lot but did not yet use EncryptedSharedPreferences. I think this is only necessary, if you have data that deserves protection in a very strict way (like passwords or similar). But then you might probably want to use Google Identity or similar.
If you use private SharedPreferences, by calling context.getSharedPreferences(.., Context.MODE_PRIVATE) the OS already makes sure your data is only accessable from your app. Unless there is a bug in the system or the device is hacked, no other party has access to your data.
Now to answer your question, what do you use the session ID for?
For me it looks like you try to implement a web application inside an Android app. If this is the case because you are used to build web apps and have no more specific reason, then just forget about session handling and implement the app assuming there is only one user.
If you want it because you are communicating with a web service or similar, then let that service do the session handling, if possible.
If you really need that session, then the answer to your question is:
With your example the system doesn't know the SharedPrefrences you are calling is valid for the current session. The values are always the same, independent on who is currently logged in.
What you can do, is to choose a name for your SharedPreferences that corresponds with your logged in user (e.g. the hash of the username/mail address or similar).
So you always load the SharedPreferences based on some user identification, just like that:
context.getSharedPreferences(username.hashCode(), Context.MODE_PRIVATE)
There are two points to consider, if you do so:
You might generate junk data, if a user logs in once, therefore generates a SharedPreferences file, and never logs in again. So it might be appropriate to save the users last activity and clean up from time to time.
If you have lot's of users logging in, you might want to consider a database or some other storage type, like json files or whatever, as it's much easier to handle and clean them up.
sharedPrefences is like a repo. So write our data with string types. You can select your data is private or public. And remove your data when your deleted app.
Maybe your help this link:
https://www.geeksforgeeks.org/shared-preferences-in-android-with-examples/

SharedPreferences does not pass get the saved value

I am working on android project built partially in kotlin and partially in java. I am trying to pass information from a kotlin fragment class to a java class. I have come to see that there is a problem with the passing of information as I do not receive the needed value. After some debugging I have seen that the information is successfully stored, however when the information from shared preferences is accessed, only the default value is returned.
This is the code in the kotlin class. When a button is clicked it changes the value of a boolean variable to the opposite one, sets the text of a button to true/false and saves the value of the variable in shared preferences.
btnStyle.setOnClickListener() {
styleHasChanged = !styleHasChanged;
if(styleHasChanged == true){
btnStyle.setText("true")
}else{
btnStyle.setText("false")
}
val sharedPref : SharedPreferences?= activity?.getPreferences(MODE_PRIVATE);
sharedPref?.edit()?.putBoolean("bla", styleHasChanged)?.apply()
}
This is the java class. Shared preferences is called inside a function which chooses a filepath based on the received value.
public static String getHtmlContent(Context context, String htmlContent, Config config) {
SharedPreferences sharedPreferences = context.getSharedPreferences("bla",MODE_PRIVATE);
boolean hasStyleChanged = sharedPreferences.getBoolean("bla", false);
//moj
String cssPath;
if (!hasStyleChanged) {
cssPath = String.format(context.getString(R.string.css_tag), "file:///android_asset/css/Style.css");
} else {
cssPath = String.format(context.getString(R.string.css_tag), "file:///android_asset/css/Style2.css");
}
This is where the problem arises. Shared preferences in the java class always fetches the default value, no matter if the button is clicked or not.
The getPreferences method implicitly uses the class name of the Activity as the preference file name. By passing "bla" as the file name to getSharedPreferences you're trying to fetch the saved value from a different file.
If you would like to access the same preferences accross your application, then either use getSharedPreferences (for both writing and reading the preference) with the same file name, or use the getDefaultSharedPreferences static method of PreferenceManager to obtain the default SharedPreferences instance.
You should change your code to something like this:
val sharedPref : SharedPreferences? = activity?
.getSharedPreferences("someFileName", MODE_PRIVATE)
sharedPref?.edit()?.putBoolean("bla", styleHasChanged)?.apply()
And the Java part:
SharedPreferences sharedPreferences = context
.getSharedPreferences("someFileName", MODE_PRIVATE);
boolean hasStyleChanged = sharedPreferences.getBoolean("bla", false);
Your context.getSharedPreferences("PreferencesFileName",MODE_PRIVATE) should be the same even when using the activity?.getPreferences("PreferencesFileName",MODE_PRIVATE). In you code it's not like that.
Plus a simple suggestion, because I'm not sure if you're clear on that. The bla is the key for your boolean value not your Preferences file name. I mean it could be, but it's better to separate.

Entering app exactly as it was left

I know there must be douzens of answers to this question out there, but either i cant't find them or I don't understand them.
The Question:
How do I get my app to exactly start as it was left?
F.e. dynamicly added checkBoxes shouldn't dissapear!
There is no "out of the box" way of doing it. You could save the current state of your Activity in some way (More on persistence)
Then you need to be able to rebuild the desired state of the persisted state in your Activity lifecycle
You could save and load with the shared preferences for example:
public void saveState(YourState state) {
SharedPreferences sharedPreferences = app.getSharedPreferences(R.string.preference_file_key, Context.MODE_PRIVATE)
sharedPreferences.edit()
.putString("CustomAtt", state.getCustomAtt())
}
public YourState loadState() {
SharedPreferences sharedPreferences = app.getSharedPreferences(R.string.preference_file_key, Context.MODE_PRIVATE)
String customAtt = sharedPreferences.getString("CustomAtt", "DefaultValue")
return new YoutState(customAtt)
}
And use it like this
#Override
protected void onCreate(Bundle savedInstanceState) {
YourState state = loadState();
// Rebuild your activity based on state
someView.setText(state.getCustomAtt())
}
You can store such values in SharedPreferences.
https://developer.android.com/training/basics/data-storage/shared-preferences.html
It is using key-value approach for saving. So you can save some values and read it from SharedPreferences whenever you want to.
This is the best approach for small data, that can be used on the app launch. So you can quit your app and the data is still present - so can be read on the next app launch.
Or save the condition of your program to a text file, so that the program can "translate" it back into conditions before it stops, or what I do not recommend, it saves every object created with ObjectOutputStream.

Minimize application android

I wrote an application with login/logout logic.
After login(set user and pass as vars) the user can minimize the application.
Minimize code:
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
When user clicks on the app icon in first activity I check is have set user and pass as vars, if they are app go to activity 2(next activity).
if they are not set go to login interface.
Everything is working fine but sometimes the app forgets the user and pass after minimizing and I go to the login interface....
Is like clearing cache I don't know... help
In Android, you cannot assume that your application will be kept in memory when it goes to the background, and you cannot assume it stays on the foreground (people may press the Home key or popups may come up). You should implement the onPause and onResume events and store the details of the logged in user there. These methods are guaranteed to be called by Android whenever your application goes into the background and is re-activated, respectively. You can use the SavedBundle object that you get in these methods to store your data. Also read about the app lifecycle here: http://developer.android.com/reference/android/app/Activity.html
you should use sharedPreferance to store login user and password.
below is code
private void storeUserPreferences(String key, String value) {
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(this);
Editor editor = sharedPreferences.edit();
editor.putString("username", "xyz");
editor.putString("pass", "123");
editor.commit();
}
private void loadUserPreferences() {
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(this);
String pass =sharedPreferences.getString("pass","");
String username=sharedPreferences.getString("username","");
if(!TextUtils.isEmpty(pass)&&!TextUtils.isEmpty(username))
{
login.....success
}
else
{
redirect to login screen
}
}
this is ref doc http://developer.android.com/reference/android/content/SharedPreferences.html

Android save details screen

I am working on a small project that requires a details screen where the user inputs his details and they are permanently stored. The user must have the option to change the details as well if he needs to do so. I looked into the saved preferences library however it does not seem to offer such functionality.
To give a visual idea of what is required, something like this screen should be fine:
http://www.google.com.mt/imgres?start=97&num=10&hl=en&tbo=d&biw=1366&bih=643&tbm=isch&tbnid=aQSZz782gIfOeM:&imgrefurl=http://andrejusb.blogspot.com/2011/10/iphone-web-application-development-with.html&docid=YpPF3-T8zLGOAM&imgurl=http://2.bp.blogspot.com/-YRISJXXajD0/Tq2KTpcqWiI/AAAAAAAAFiE/-aJen8IuVRM/s1600/7.png&w=365&h=712&ei=rbX6ULTDCOfV4gTroIDoCg&zoom=1&iact=hc&vpx=834&vpy=218&dur=2075&hovh=314&hovw=161&tx=80&ty=216&sig=108811856681773622351&page=4&tbnh=155&tbnw=79&ndsp=35&ved=1t:429,r:4,s:100,i:16
Any help is much appreciated. Thanks in advance
You could easily use Shared Preferences to store user's details. Everytime the Preference screen is opened the stored data can then be extracted from the Shared Preferences and presented to the user for edit. ONce the edit is done the new data can be updated back in the the Shared Preferences.
Also look at this thread to see how this can be done.
Using SharedPreferences would be perfect for this kind of small amount of data which you want to store persistently.
// 'this' is simply your Application Context, so you can access this nearly anywhere
SharedPreferences prefs = this.getSharedPreferences(
"com.example.app", Context.MODE_PRIVATE);
To obtain from the preferences:
// You can equally use KEY_LAST_NAME to get the last name, etc. They are just key/value pairs
// Note that the 2nd arg is simply the default value if there is no key/value mapping
String firstName = prefs.getString(KEY_FIRST_NAME_CONSTANT, "");
Or to save:
Editor editor = prefs.edit();
// firstName being the text they entered in the EditText
editor.putString(KEY_FIRST_NAME_CONSTANT, firstName);
editor.commit();
You can achieve such functionality using SharedPreferences Class in android.
public void onCreate(Bundle object){
super.onCreate(object);
// Initialize UI and link xml data to java view objects
......
SharedPreferences myPref = getPreferences(MODE_PRIVATE);
nameView.setText(myPref.getString("USER_NAME", null));
passView.setText(myPref.getString("PASSWORD", null));
}
public void onStop(){
super.onStop();
if (isFinishing()) {
getPreferences(MODE_PRIVATE).edit()
.putString("USER_NAME", nameView.getText().toString())
.putString("PASSWORD", passView.getText().toString())
.commit()
}
}

Categories