Android : SharedPreferences not updated - android

My 2 android applications communicate throught a AIDL file :
Application A <== AIDL ==> Application B (service)
Application A calls methods of Application B (service) that returns some JSON information. However, If user is not logged in application B, null is returned.
(service in application B)
//first : get info
SharedPreferences mPrefs = getSharedPreferences(Consts.SP_NAME, MODE_PRIVATE);
String userId = mPrefs.getString(Consts.PREFS_USER_ID, "");
String userPass = mPrefs.getString(Consts.PREFS_USER_PASS, "");
//then check is valid (remote server)
if (dao.exist (userId, userPass)){
return "MY_JSON_INFO" ;
}else{
return false;
}
If null is returned, "login" activity in Application B is launched from Application A.
(Aplication A)
if(json == null){
Intent intent = new Intent("jp.app.LOGIN_ACTIVITY");
startActivity(intent);
}
User log in (Application B), data are saved in SharedPreferences (Application B) and activity is closed (back to Application A).
SharedPreferences mPrefs = a.getSharedPreferences(Consts.SP_NAME, MODE_PRIVATE);
Editor prefsEditor = mPrefs.edit();
prefsEditor.putString(Consts.PREFS_USER_ID, id);
prefsEditor.putString(Consts.PREFS_USER_PASS, pass);
prefsEditor.commit();
When re-trying to call methods of the Application B, login information saved few seconds ago are not available and null is returned.
I have tried without success with prefsEditor.apply() .
If I restart application B, login data will be loaded....
Please let me know if further information are needed.
Thank you

After a long struggle, I have at last managed to get my updated preferences.
When calling getSharedPreferences, I use Context.MODE_MULTI_PROCESS flag.
MODE_MULTI_PROCESS
Thank you.

Since you need to access the shared preference of other application.
You should try :: Android: Retrieving shared preferences of other application

By reading your comment i can give you a quick solution:
The easier way is to simply terminate your activity (A) before calling the login activity inside your service.
if(json == null){
Intent intent = new Intent("jp.app.LOGIN_ACTIVITY");
startActivity(intent);
this.finish();
}
So that, when you fill in the login form and call back the activity A it will read the new shared preferences!

Related

Shared Preference data not cleared when activity is closed

in my application, I used place picker.and data that place picker gave is sent to 3 different activities using shared preference.and show this data in TextView.problem is when I closed activity and again open that activity my data still visible in TextView.even when I cleared it in onDestroy().
here is my code for send data from place picker:
SharedPreferences settings = getSharedPreferences("city_address", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString("city_address", (String) cityAddress);
editor.putString("city_name", (String) city);
editor.commit();
Intent intent = new Intent(this, CleanlinessActivity.class);
startActivity(intent);
set data using this code in onCreate() of CleanlinessActivity
SharedPreferences settings = getSharedPreferences("city_address", Context.MODE_PRIVATE);
String n = settings.getString("city_name", "Enter Location");
String a = settings.getString("city_address", "");
cityname.setText(n);
cetlocation.setText(a);
and i cleared data using this code in CleanlinessActivity
#Override
protected void onDestroy() {
super.onDestroy();
SharedPreferences settings = getSharedPreferences("city_address", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.remove("city_address");
editor.clear().commit();
}
By closing the app you mean just clicking the home button then onDestroy() is never called, you can get a refresher of the android life cycles here
If what you are doing is simply clicking the home button then consider moving your code to the onStop() otherwise you need to commit() following the remove(...) The android documentation states "Mark in the editor that a preference value should be removed, which will be done in the actual preferences once commit() is called."
You have an instance of SharedPreferences called city_address which is having two fields or (Columns if we call it),but inside onDestroy()you are trying to to clear only one field of it called city_address,and the other field city_name field is left unchanged,if you want to completely remove the content of the city_address SharedPreferences use editor.clear().commit();
or``editor.clear().apply();`

Passing data via intent in android

I have 5 activities, say activity A,B,C,D and E.
Each activity has two buttons yes & no,buttons have the data which I want to pass to activity E only.
I need to do following things:
--> When user press yes/no button of A_activity, the user move to B_activity but data passed to activity E via intent.
Similarly at activity B user press yes/no button, user will move to activity C but data passed to activity E and so on.
I have done lot of search but couldn't find solution is there any way to do this.
Use SharedPreferences class to pass the data:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("key", "Value");
editor.commit();
Then in the Activity E:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
String value = sharedPref.getString("key", defaultValue);
Hope this helps.
You can indeed pass data back through an intent to an Activity's onActivityResult()
Activity E starting Activity A
final int RESULT_FOR_CLASS_DATA = 12; // pick a number to use
String returnedData;
Intent intent = new Intent(this, ActivityA.class);
startActivityForResult(intent, RESULT_FOR_CLASS_DATA);
Example in A (started from E)
Intent data = new Intent();
data.putExtra("ReturnData", dataToReturn);
setResult(RESULT_OK, data);
finish(); // returning to Activity E
Example in onActivityResult() of E
if (requestCode == RESULT_FOR_CLASS_DATA) {
returnedData = data.getStringExtra("ReturnData"));
}
There's a wide variety of ways to accomplish moving data around though so this is just one example.
To recommend an alternative, use Handler instead of this. Supposed that since the return Activity is paused, handler might require setting data in a separate class or global static variables, etc. and retrieved on Activity restart or something. So its possible to do with little to no code duplication in any class. Just retrieve and use. Whereas Intent requires code duplication in every class. It would also easily allow going from any Activity to any Activity like A->B->E->C instead of requiring E->A->E->B. Just something to think about.

How to manage Splash, Login and Main activity on android?

I'm new on android, I have 3 activities :
SplashActivity
LoginActivity
MainActivity
I need to navigate user to LoginActivity for first time then does the authenticate and go to MainActivity but For next time which has been authenticated already, I need to navigate the user to SplashActivity and then MainActivity.
Is it good practice if I remove the splash activity and set Login activity as luncher but hide all controls to display it as Splash Activity and show controls to display it as Login Activity?
thanks
You need to save user actions locally and manage your app behavior based on previous actions of your user. For saving data locally on user device, you can use either SharedPreferences or Database based on your needs. For using these I would suggest you read some tutorials on web.
Base on your needs I suggest you to use SharedPreferences.
You can use SharedPreferences for this purpose. During login keep the user name in SharedPreferences and check the status of SharedPreferences on next login onwards.
http://www.androidhive.info/2012/08/android-session-management-using-shared-preferences/
In your SplashScreen check if user is already authenticated using a flag in SharedPreferences
Use a worker thread to ensure some delay at splash-screen
in onCreate() of SplashScreen
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView("<Layout id>");
Thread navThread = new Thread() {
#Override
public void run() {
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
navigateToHomeScreen();
}
};
navThread.start();
}
void navigateToHomeScreen(){
SharedPreferences preferences=c.getSharedPreferences("<Your pref name>", Context.MODE_PRIVATE);
if(preferences.contains("isAuthenticated")){
// Navigate to Main Activity
}else{
// Navigate to login Activity
}
finish();
}
In your login Activity once User is authenticated
SharedPreferences preferences=c.getSharedPreferences("<Your pref name>", Context.MODE_PRIVATE);
preferences.edit().putBoolean("isAuthenticated", true).apply();
// Navigate to Main Activity
Hints: Declare PrefName in some Constant file and access same wherever you want to access SharedPreferences.
my pscudo code:--- Once you do first time login please same userID and password
and next time you have to check it wheather all user id and password exit or not . In this way you can resolve it.
Save:--
SharedPreferences.Editor sqliteEditor= getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
sqliteEditor.putString("userID", "chay7an");
sqliteEditor.putInt("Password", sadasdas);
sqliteEditor.commit();
Retrive :--
SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
String restoredText = prefs.getString("text", null);
if (restoredText != null) {
String name = prefs.getString("userID", "");
int idName = prefs.getInt("Password", 0);
}

Hide Intent if Default Data Inserted

I have an intent that appear only if certain data have not been inserted yet. It's like a custom form to insert some data. If the data have been inserted, in the future the apps opened, the intent will not appear anymore. It will open another intent, the default one. (Usually this might occur when the apps opened for the first time)
How do I manage the intent since the default intent could only be one?
For example: If the apps opened for the first time it will startIntent Form
next time the apps opened (assumed the data already inserted) it will startIntent MainActivity
i use sharedpreferences to insert data only once , simply use it this way, in the below code
the intent will be started only once the application is first installed, after that it will start the main activity intent.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (isFirstTime()) {
// startIntent Form
}
}
private boolean isFirstTime()
{
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
boolean ranBefore = preferences.getBoolean("RanBefore", false);
if (!ranBefore) {
// first time
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("RanBefore", true);
editor.commit();
}
return !ranBefore;
}
I assume you are doing something like registration thing, and want to show this form once. you have many options here.
1) As Ahmad(in the comments) says use SharedPreferences, and add some flag into it, which can tell you if the data is available or not. add a check in the very beginning of the activity/onCreate and open respective inten/activity depends on check.
2) you can use Database as well to see this value.
I would suggest you to use SPLASH screen, check this value/registration data into it. And if available start Activity A, else start Registration/default one.

How to implement a registration activity in android that works only for once?

I'm designing an application that has an activity for registration process, this activity launches on default. I want this activity to be disabled forever once the registration process has been completed successfully and then it should be replaced by a different activity as the default activity for the rest of the lifetime of the application.I've tried to search my way through this problem but I've hardly found anything.Any help will be much appreciated.
Thanks in advance.
Once registration is complete, commit some value to the SharedPreferences, then in your splash screen or some other opening Activity, check the preferences. If the value indicates that the registration is complete, start a different Activity instead of the Registration one...
Example:
public class SplashScreen extends Activity {
public void onCreate(Bundle state) {
super.onCreate(state);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean regComplete = prefs.getBoolean("registration", false);
if(regComplete) {
startActivity(new Intent(this, SomeActivity.class));
} else {
startActivity(new Intent(this, Registration.class));
}
}
Better still:
Always launch the registration, but in onCreate(), simply launch a different Activity immediately and finish() the registration Activity if the prefs indicate that registration is complete.
Edit
SharedPreferences explained:
SharedPreferences lets you persist primitive values in your app. You grab the SharedPreferences by doing:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
then you write to SharedPreferences by getting the Editor. To do this, you call
SharedPreferences.Editor editor = prefs.Edit();
then you can commit values to the editor by using key/values:
editor.putBoolean("some string as a key here", true/false);
Then to actually save that, you call editor.commit();
Then you grab values back from SharedPreferences by simply calling
prefs.getBoolean("some previously chosen string as a key here", true/false);
where true/false is the default value that will be returned if no such key exists...
This is convenient and lets you do simple things like:
editor.putInt("some important number", 55);
editor.commit();
......later
int i = prefs.getInt("some important number", -1);
if(i != -1) {
//do stuff
} else {
//do other stuff
}
Also, please see: http://developer.android.com/guide/topics/data/data-storage.html#pref
Don't have the registration Activity be the default. Instead have another Activity as the default, and then at runtime it can check to see which Activity it should send the user to. If they haven't registered then startIntent( RegistrationActivity.class ).

Categories

Resources