Togglebutton state with shared preferences not changable via asynctask - android

Ok I have a togglebutton in my main activity. I want the state of this button to be saved if I switch to another activity, minimize the app and a service should be able to set the button state to false (not clicked). Everything worked fine, but for some reason when I started Android Studio again it didn´t work anymore?!
MainActivity:
monitor = (ToggleButton)findViewById(R.id.toggleButton);
monitor.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (monitor.isChecked()) {
Intent intent = new Intent(MainActivity.this, NotifiyService.class);
startService(intent);
} else {
Intent intent = new Intent(MainActivity.this, NotifiyService.class);
stopService(intent);
}
}
});
In the onStop Method the following is executed:
if (monitor.isChecked())
{
tbstate = true;
SharedPreferences sharedPreferences1 = getSharedPreferences("tbstate",MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences1.edit();
editor.putBoolean("keyTB",tbstate);
editor.commit();
}
else
{
tbstate = false;
SharedPreferences sharedPreferences1 = getSharedPreferences("tbstate",MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences1.edit();
editor.putBoolean("keyTB",tbstate);
editor.commit();
}
The onStart Method:
//get Togglebutton state
SharedPreferences sharedPreferences6 = getSharedPreferences("tbstate", MODE_PRIVATE);
monitor.setChecked(sharedPreferences6.getBoolean("keyTB",false));
Asynctask (not complete). In the onPostExecute I set the tbstate to false and in onDestroy it is saved in the sharedpreference. Then a message pop ups which "leads" to main2activity of the same app. When I go from main2activity to mainactivity the togglebutton is still activated.
I hope it is clear what I want ;-)
#Override
public void onDestroy() {
//super.onDestroy();
Th1.interrupt();
checkhttp.cancel(false);
SharedPreferences sharedPreferences8 = getSharedPreferences("tbstate",MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences8.edit();
editor.putBoolean("keyTB", tbstate);
Toast.makeText(NotifiyService.this,getResources().getString(R.string.MonStopped), Toast.LENGTH_LONG).show();
stopSelf();
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return null;
}
private static class HttpTaskParams{
boolean value;
String address;
HttpTaskParams(boolean value, String address){
this.value = value;
this.address = address;
}
}
private class HttpTask extends AsyncTask<HttpTaskParams,Void,Boolean>{
#Override
protected Boolean doInBackground(HttpTaskParams... params) {
boolean value = params[0].value;
String address = params[0].address;
try {
URL url = new URL(address);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("HEAD");
httpURLConnection.setConnectTimeout(3000);
httpURLConnection.setReadTimeout(3000);
httpURLConnection.connect();
value = true;
return value;
} catch (MalformedURLException e) {
e.printStackTrace();
value = false;
return value;
} catch (IOException e) {
e.printStackTrace();
value = false;
return value;
}
}
#Override
protected void onPostExecute(Boolean result) {
if(result){
//Notification in Status Bar
NotificationCompat.Builder builder = new NotificationCompat.Builder(NotifiyService.this);
builder.setSmallIcon(R.drawable.dummy);
Intent intent = new Intent(NotifiyService.this, Main2Activity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(NotifiyService.this,0,intent,0);
builder.setContentIntent(pendingIntent);
builder.setLights(Color.YELLOW, 600, 600);
builder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.dummy));
builder.setContentTitle(getResources().getString(R.string.newNotify));
builder.setContentText(getResources().getString(R.string.newNotify2));
builder.setAutoCancel(true);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(1, builder.build());
tbstate=false;
onDestroy();
}
}
}

You need call commit() method of shared preference editor after any change in shared preference..
You haven't called this in ondestroy method

It happens because onPostExecute methods executes after onDestroy of Activity and preferences didn't saved. You need to save preferences in onPostExecute method too

Related

SharedPreferences always shows the same thing

So I'm trying to save a value to sharedpreferences by a click of a button, and then see which value it is in another activity. (to basically set a background for activity2 based on which button they pressed in activity1)
Saving code:
public void onClick(View v) {
SharedPreferences.Editor background = getSharedPreferences("Background", MODE_PRIVATE).edit();
if(btn1 == v)
{
background.remove("selectedBG");
Toast.makeText(this, "btn1", Toast.LENGTH_SHORT).show();
background.putInt("selectedBG", 1);
background.commit();
}
if(btn2 == v)
{
background.remove("selectedBG");
background.putInt("selectedBG", 2);
Toast.makeText(this, "btn2", Toast.LENGTH_SHORT).show();
background.commit();
}
if(btn3 == v)
{
background.remove("selectedBG");
background.putInt("selectedBG", 3);
Toast.makeText(this, "btn3", Toast.LENGTH_SHORT).show();
background.commit();
}
if(btn4 == v)
{
background.remove("selectedBG");
background.putInt("selectedBG", 4);
Toast.makeText(this, "btn4", Toast.LENGTH_SHORT).show();
background.commit();
}
}
And then, the Toast here always shows "chosenbackground:0":
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.play);
LLayout=(LinearLayout)findViewById(R.id.llayout);
SharedPreferences background2 = getSharedPreferences("Background", MODE_PRIVATE);
int chosenBackground = background2.getInt("selectedBg", 0);
Toast.makeText(this,"chosenBackground:" + chosenBackground, Toast.LENGTH_SHORT).show();
if (chosenBackground != 0) {
if(chosenBackground==1)
{
LLayout.setBackgroundColor(Color.WHITE);
}
if(chosenBackground==2)
{
LLayout.setBackgroundColor(Color.rgb(34,34,34));
}
if(chosenBackground==3)
{
LLayout.setBackgroundColor(Color.rgb(51,68,85));
}
if(chosenBackground==4)
{
LLayout.setBackgroundColor(Color.rgb(68,34,17));
}
}
}
Answer for your question is that you have misspelled the key in second activity, in first one you are using "selectedBG" but in the second one "selectedBg". It is not the same, it's case sensitive. Correct in the second one for "selectedBG" and it should work.
Using the SharedPreferences here it's really bad idea, if u only want to pass a background or rather a color if I see it correctly. Just pass it in intent:
Intent intent = new Intent(this, Activity2.class);
intent.putExtra("EXTRA_BACKGROUND_ID", background);
startActivity(intent);
Access that intent on next activity for eg. in onCreate()
String s = getIntent().getStringExtra("EXTRA_SESSION_ID");
#Updated
public class PreferencesUtils {
private SharedPreferences sharedPrefs;
private SharedPreferences.Editor prefsEditor;
public static final String KEY_BACKGROUND = "BACKGROUND";
public PreferencesUtils(Context context) {
this(context, PREFS_DEFAULT);
}
public PreferencesUtils(Context context, String prefs) {
this.sharedPrefs = context.getSharedPreferences(prefs, Activity.MODE_PRIVATE);
this.prefsEditor = sharedPrefs.edit();
}
public int getValue(String key, int defaultValue){
return sharedPrefs.getInt(key, defaultValue);
}
public boolean saveValue(String key, int value){
prefsEditor.putInt(key, value);
return prefsEditor.commit();
}
}
PreferencesUtils preferencesUtils = new PreferencesUtils(this);
preferencesUtils.saveValue(PreferencesUtils.KEY_BACKGROUND, 1); //saveValue
preferencesUtils.getValue(PreferencesUtils.KEY_BACKGROUND, 0); //getValue,
second arg is defult if not found
Use if (!background2.contains("selectedBg"))
to check ,first whether the key exists and if not getInt is not able to create a key and hence always returns default value 0.Also you can use apply() instead of commit to check whether commit has taken place successfully.Debug the code more to see all possibilities
int chosenBackground=0;
if (!background2.contains("selectedBg"))
{
//is called once when after you freshly install the app
background2.putInt("selectedBG", 0);
}
else
chosenBackground = background2.getInt("selectedBg", 0);

how to run a service in background and managed by SharedPreferences Settings

I'm coding an app, where there is a PrefereceActivity which contains a SwitchPreference that start or stop a service when the user switches on or off it, and it saves the status of the switch in to SharedPreference.
Then in the MainActivity I registered A On SharedPreferenceChangeListener, which read the status of the switch, then based on the it start or Stop the service.
// This is the code in MainATY:
preferences= getPreferences(Activity.MODE_PRIVATE);
editor= preferences.edit();
preferences.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
boolean pushNotification= sharedPreferences.getBoolean(MyPreferences.pushNotificationKey,true);
if (pushNotification)
{
if (!NotificationService.isRunning){
Intent i = new Intent(MainActivity.this, NotificationService.class);
bindService(i,MainActivity.this,Context.BIND_AUTO_CREATE);
}
}
else{
if (NotificationService.isRunning){
unbindService(MainActivity.this);
}
}
}
});
and this is PreferenceATY code:
pushNotification.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object o) {
pushNotification= (SwitchPreference) preference;
editor.putBoolean(pushNotificationKey,pushNotification.isChecked());
if (!editor.commit())
{
Toast.makeText(MyPreferences.this, R.string.changes_saved,Toast.LENGTH_SHORT).show();
}
return true;
}
});
But it doesn't work, can you help me?
One last thing, how can I make Notifications with more than one line of the content?
This is my notification function:
String thingsToDo=new String();
while (c.moveToNext())
{
thingsToDo+=String.format("%s: %s: %s "
,c.getString(c.getColumnIndex("subject"))
,c.getString(c.getColumnIndex("typeOfEvent"))
,c.getString(c.getColumnIndex("what"))
);
thingsToDo+="/n";
}
thingsToDo.substring(0,4);
NotificationCompat.Builder mBuilder=new NotificationCompat.Builder(MainActivity.this)
.setSmallIcon(R.drawable.small_icon_diary)
.setContentTitle(getString(R.string.homework_for_tomorrow))
.setContentText(thingsToDo);
mBuilder.setShowWhen(true);
Intent i= new Intent(MainActivity.this,NotificationViewActivity.class);
Bundle b= new Bundle();
b.putString("time",time);
i.putExtra("b",b);
i.putExtra("time",time);
mBuilder.addAction(R.drawable.small_icon_diary,"Open",PendingIntent.getActivity(MainActivity.this,0,i,0));
I have solved the Question about Notification in this way:
NotificationCompat.Builder mBuilder=new NotificationCompat.Builder(MainActivity.this)
.setSmallIcon(R.drawable.small_icon_diary)
.setContentTitle(getString(R.string.homework_for_tomorrow))
.setContentText(thingsToDo)
.setStyle(new NotificationCompat.BigTextStyle().bigText(thingsTodo));

Android- saving data that updates before restarting the application

In the Android application I'm working on, I have one activity where the user inputs data that is saved using SharedPreferences, and is used for certain calculations on the main activity. An issue I'm having is that after saving the data, the changes do not actually take effect until after the application is restarted. Is there a way I can make it so the variables associated with these SharedPreferences are updated before restarting?
Here is where I save the data in a separate activity.
saveBn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
weightString = weightText.getText().toString();
ageString = ageText.getText().toString();
getSharedPreferences("PREFERENCE", MODE_PRIVATE).edit()
.putString("savedWeight", weightString).commit();
getSharedPreferences("PREFERENCE", MODE_PRIVATE).edit()
.putString("savedAge", ageString).commit();
//Intent i = new Intent("com.williammiller.capstonelapv2.MainActivity");
//startActivity(i);
finish();
}
});
And here is where I'm checking in the main activity to see what they are
String age = getSharedPreferences("PREFERENCE", MODE_PRIVATE)
.getString("savedAge", "25");
String weight = getSharedPreferences("PREFERENCE", MODE_PRIVATE)
.getString("savedWeight", "200");
startBn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "weight = " + weightInt + " age = " + ageInt, Toast.LENGTH_LONG).show();
}
});
You can use a BroadcastReceiver to achieve that. Do as following:
Register a BroadcastReceiver in your Main Activity:
public static final String UPDATE_ACTION = "yourpackage.update";
public static final String EXTRA_KEY_AGE = "key_age";
public static final String EXTRA_KEY_WEIGHT = "key_weight";
private BroadcastReceiver mReceiver;
// In the onCreate() method
mReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(UPDATE_ACTION)){
// Here you get the update data from another activity
String age = intent.getStringExtra(EXTRA_KEY_AGE);
String weight = intent.getStringExtra(EXTRA_KEY_WEIGHT);
}
}
};
registerReceiver(receiver, new IntentFilter(UPDATE_ACTION ));
// Add the following code to onDestroy() method
unregisterReceiver(mReceiver);
Send a broadcast in your "separate activity":
public void onClick(View v) {
weightString = weightText.getText().toString();
ageString = ageText.getText().toString();
Intent intent = new Intent(MainActivity.UPDATE_ACTION );
intent.putExtra(MainActivity.EXTRA_KEY_AGE, ageString);
intent.putExtra(MainActivity.EXTRA_KEY_WEIGHT, weightString );
sendBroadcast(intent);
}
Update: Change part of the code to unregister the BroadcastReceiver when activity is destroyed.

onResume called on noHistory activity

I have two activities, LoginActivity and MainActivity.
LoginActiviy is the launcher Activity, its purpose is to check whether the user is signed in or not if he's signed in; go to MainActivity.
Although I set android:noHistory="true" to LoginActivity the activity's onResume(LoginActivity) is called again when user exits(means onPause called) the program and launch it again.
Did I misunderstood what noHistory means ? if so what can I do to make the OS forget about the existence of LoginActivity?
EDIT : I tried to put this on LoginActivity's onResume , but it calls MainActivity's onCreate, which I don't want
if(!firstTime) {
goToMainActivity();
}
LoginActivity :
public class LoginActivity extends Activity {
protected static final String PASSED_TWITTER = "mosaed.thukair.alsafytooth.LoginActivity";
private static final String TAG = "mosaed.thukair.alsafytooth.LoginActivity";
protected static final int RESULT_BROWSER = 0;
private SharedPreferences prefs;
private Twitter twitter;
private RequestToken requestToken;
private AccessToken accessToken;
private String authUrl;
private Button login;
private boolean firstTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.prefs = PreferenceManager.getDefaultSharedPreferences(this);
firstTime = true;
if(isAuthenticated()) {
Log.i(TAG, "splash screen");
setContentView(R.layout.splash_screen);
String token = prefs.getString(Constants.OAUTH_TOKEN, "");
String tokenSecret = prefs.getString(Constants.OAUTH_TOKEN_SECRET, "");
Log.i(TAG, "oauth login");
OAuthLogin(token, tokenSecret);
} else {
setContentView(R.layout.activity_login);
login = (Button) findViewById(R.id.connect_button);
login.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Log.i(TAG, "clicked");
LoginActivity.this.setContentView(R.layout.splash_screen);
OAuthLogin();
}
});
}
}
private boolean isAuthenticated() {
String token = prefs.getString(Constants.OAUTH_TOKEN, "");
if(token.equals(""))
return false;
String secret = prefs.getString(Constants.OAUTH_TOKEN_SECRET, "");
if(secret.equals(""))
return false;
return true;
}
private void OAuthLogin() {
twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
new AsyncTask<Void,Void,Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
requestToken = twitter.getOAuthRequestToken(Constants.CALLBACK_URL);
authUrl = requestToken.getAuthenticationURL();
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl));
myIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP |
Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
Log.i(TAG, "open browser");
LoginActivity.this.startActivity(myIntent);
} catch (TwitterException e) {
e.printStackTrace();
}
return null;
}
}.execute();
}
private void OAuthLogin(final String token, final String tokenSecret) {
twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
new AsyncTask<Void,Void,Void>() {
#Override
protected Void doInBackground(Void... params) {
AccessToken accessToken = new AccessToken(token, tokenSecret);
twitter.setOAuthAccessToken(accessToken);
return null;
}
#Override
protected void onPostExecute(Void param) {
goToMainActivity(twitter);
}
}.execute();
}
#Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume");
if ((this.getIntent() != null) && (this.getIntent().getData() != null)) {
setContentView(R.layout.splash_screen);
new AsyncTask<Void,Void,Void>() {
#Override
protected Void doInBackground(Void... params) {
Uri uri = LoginActivity.this.getIntent().getData();
afterBrowser(uri);
return null;
}
#Override
protected void onPostExecute(Void uri) {
storeAccessToken();
goToMainActivity(twitter);
}
}.execute();
} else if(!firstTime) {
goToMainActivity(twitter);
}
}
private void afterBrowser(Uri uri) {
String verifier = uri.getQueryParameter("oauth_verifier");
String token = uri.getQueryParameter("oauth_token");
try {
twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
requestToken = new RequestToken(token, Constants.CONSUMER_SECRET);
accessToken = twitter.getOAuthAccessToken(requestToken,
verifier);
twitter.setOAuthAccessToken(accessToken);
} catch (TwitterException ex) {
Log.e(TAG, "" + ex.getMessage());
}
}
private void storeAccessToken() {
prefs.edit()
.putString(Constants.OAUTH_TOKEN, accessToken.getToken())
.putString(Constants.OAUTH_TOKEN_SECRET, accessToken.getTokenSecret())
.commit();
}
private void goToMainActivity(Twitter twitter) {
firstTime = false;
Intent myIntent = new Intent(this, MainActivity.class);
MyApplication.getInstance().setTwitter(twitter);
startActivity(myIntent);
}
}
if(!firstTime) {
goToMainActivity();
finish();
}
What no history does is that it doesn't let that certain activity register in the stack of past activities, it doesn't allow it to skip parts of the Activity lifecycle.
If you don't want certain code not to execute then you should do something like:
Login Activity:
if(!firstTime) {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent. putExtra("skip", true);
finish();
}
Main Activity: (inside onCreate)
if(!getIntent().getBundle().getBoolean("skip", false)) {
//You code that you don't want
}
This is the activity lifecycle I hope it's beneficial to you:
android:noHistory Whether or not the activity should be removed from
the activity stack and finished (its finish() method called) when the
user navigates away from it and it's no longer visible on screen —
"true" if it should be finished, and "false" if not. The default value
is "false". A value of "true" means that the activity will not leave a
historical trace. It will not remain in the activity stack for the
task, so the user will not be able to return to it.
This attribute was introduced in API Level 3.
Quoting the documentation, "it's finish() method called", have you tried finishing the activity yourself?
noHistory = true means once the activity is finish() for that user session, the user will never see it again, however, if the activity is just being paused without finishing, then it will be restarted when going back to it. Before you go to the main activity, just finish() it, if thats your desired behavior.

how to kill Activity permanetly After button click Using Shared prefrance

public class MainActivity extends Activity {
Button btn1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent newpage = new Intent(MainActivity.this, PhonrRegistaion.class);
startActivity(newpage);
btn1=(Button)findViewById(R.id.button1);
btn1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent myintent=new Intent(MainActivity.this,nextActvity.class);
startActivities(null);
}
});
}
}
this is my Activity i want moving from one Activity to another Activity i want to kill my Activity permanently using shared prefrances means if open Application then it should launch second Activity . please help i dont know how to kill Activity using shred prefrances
here is the complete solution
//firstly when you register the user set the shared preferences in your register class like this
//declare pref editor
SharedPreferences prefs;
SharedPreferences.Editor prefsEditor;
prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefsEditor = prefs.edit();
//paste below peace of code when the registration will be success
prefsEditor.putString("register", "yes");
prefsEditor.commit();
//now in your first activity you just check the shared pref value to know the user is register or no
SharedPreferences prefs;
String register;
prefs = PreferenceManager.getDefaultSharedPreferences(this);
register=prefs.getString("register", "");
//now check the value of shared pref and apply the condition like this
Intent intent ;
if(register.equalsIgnoreCase("yes"))
{
intent = new Intent(this, NextAct.class);
startActivity(intent);
finish();
}
else
{
intent = new Intent(this, Register.class);
startActivity(intent);
finish();
}
You cannot "kill" an activity but you can finish() it.
In onCreate() create condition:
if (<your condition>) {
startActivity(...);
finish();
}
Either finish the old activity when the new one is started:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences prefs = getSharedPreferences(LOC_PREF_FILE, MODE_PRIVATE);
Boolean startSecond = prefs.getBoolean("StartSecondActivty", false);
if (startSecond) {
Intent newpage = new Intent(this, PhonrRegistaion.class);
startActivity(newpage);
finish();
}
btn1=(Button)findViewById(R.id.button1);
btn1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent myintent=new Intent(this, nextActvity.class);
startActivities(null);
finish();
SharedPreferences prefs = getSharedPreferences(
LOC_PREF_FILE, MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("StartSecondActivty", true);
editor.commit();
editor.apply();
}
});
}
}
This is not permanent as such as it will reside in memory until GC.
If you want to permanently kill you activity (and app) try killing your own process:
// Kill everything you can
public void killMyProcess() {
try {
Process process = Runtime.getRuntime().exec(
"/system/bin/kill -9 -1");
BufferedReader reader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
process.waitFor();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

Categories

Resources