Android SharedPreferences force closes app - java

This is my first post on here so go easy on me lol! Ok so I'm new to this and I've been working on this code for days and I can't seem to get this concept of Preferences. I've searched everywhere on this site and I believe this code should work fine by all of the information I've looked at on this site and others. I've looked at countless examples and still don't understand what I'm doing wrong.
This is a snippet of my main activity that's first initiated when the user launches the app. I have another activity on an options menu that calculates the difference between the current date and the user's selected date and I would like the resulting integer to be passed onto the main activity and show a Toast of it's value.
public class SmokeStopperActivity extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
public static final String PREFERENCE_FILENAME = "DaysPassed";
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SharedPreferences preference = getSharedPreferences("DaysPassed", MODE_PRIVATE);
int diffDays = preference.getInt("daysPassed", 0);
Toast.makeText(SmokeStopperActivity.this, ("Days" + diffDays),
Toast.LENGTH_LONG).show();;
This is a snippet of my second activity that calculates the value of the integer diffDays.
long diff = milis2 - milis1;
int diffDays = (int) (diff / (24 * 60 * 60 * 1000) + 30);
Toast.makeText(SetDate.this, (diffDays),
Toast.LENGTH_LONG).show();;
SharedPreferences preference = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor prefEditor1 = preference.edit();
prefEditor1.putInt("daysPassed", diffDays);
prefEditor1.commit();
I have my second activity send a Toast of the diffDays integer when the user presses a button in a earlier section of the second activity and the calculations work fine. The Toast in the second activity displays the integer that I want. The problem is that when I use this code
SharedPreferences preference = getSharedPreferences("DaysPassed", MODE_PRIVATE);
int diffDays = preference.getInt("daysPassed", 0);
Toast.makeText(SmokeStopperActivity.this, ("Days" + diffDays),
Toast.LENGTH_LONG).show();;
in my first activity it force closes on open. If i delete this code from the first activity the app opens which doesn't make any sense to me. All of the other codes I have checked on here seem to use this snippet exactly as I do with no problems so I do not understand what I'm doing wrong. Any help would be GREATLY appreciated. I have a feeling it's something stupid that I keep overlooking. Probably due from looking at code for hours upon hours lol!

try this:
SharedPreferences preference = SmokeStopperActivity.this.getSharedPreferences("DaysPassed", MODE_PRIVATE);
int diffDays = preference.getInt("daysPassed", 0);
Toast.makeText(SmokeStopperActivity.this, ("Days" + String.valueOf(diffDays)),
Toast.LENGTH_LONG).show();

I think..You should get shared preferences on context of your activity...
try like this..
SharedPreferences prefs = this.getSharedPreferences( "DaysPassed", MODE_PRIVATE);

Use this
Context context = getApplicationContext();
Toast.makeText(context, ("Days" + diffDays),
Toast.LENGTH_LONG).show();

The problem is that when I use this code
SharedPreferences preference = getSharedPreferences("DaysPassed", MODE_PRIVATE);
int diffDays = preference.getInt("daysPassed", 0);
Toast.makeText(SmokeStopperActivity.this, ("Days" + diffDays),
Toast.LENGTH_LONG).show();;
in my first activity it force closes on open. If i delete this code from the first activity the app opens which doesn't make any sense to me.
Correct. It makes no sense at all. There is nothing wrong with that code...well, actually there is. I'd write it as...
Toast.makeText(this, "Days" + diffDays, Toast.LENGTH_LONG).show();
...but either way, it works - my version and yours. There is something else wrong with your code and it isn't to do with those three lines.
Forget your second Activity and just post the whole of your first Activity and also the logcat output indicating which line is throwing an unhandled exception and causing the force close.

Related

Using SharedPrefernces to sum Integers from a RecyclerView

I'm trying to create an App that sums time.
My situation:
I have a RecyclerView with a lot of elements, and each of those has a different time attribute.
Now, when an element is clicked, then another and another I want all those attributes to be summed and the final result to be displayed in another activity.
So what I'm trying to do is to achieve this using SharedPrefernces like this:
private void getTime(int time) {
SharedPreferences sharedPreferences = mContext.getSharedPreferences("sharedPrefs", MODE_PRIVATE);
int time0 = sharedPreferences.getInt("TimeRetrieve", 0);
int sum = time0 + time;
SharedPreferences sharedPreferences2 = mContext.getSharedPreferences("sharedPrefs", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences2.edit();
editor.putInt("Time", sum);
editor.apply();
TimeRetrieve gets the total time that is displayed ion the TextView, so if it's the first time it's defaulted to 0, of course.
After that it's supposed to sum that retrieved int with the int of the Item that has just been clicked and then saved in another SharedPref: Time.
Time gets sent to the TextView, where it gets retrieved by TimeRetrieve
But his doesn't work..
First, you are using 2 different keys : TimeRetrieve and Time. So, you can't make the sum.
Second, why are you using 2 SharedPreferences object ? Only one is needed.
Third, you don't need to use SharedPreferences here. You just have to sum what you want in a variable and then, pass it to the other Activity with extra bundle.
Is there a reason you're using two different SharedPreferences to get and put data? Consider using something like this:
private void GetTime(int time) {
SharedPreferences sharedPreferences = mContext.getDefaultSharedPreferences("sharedPrefs", MODE_PRIVATE);
int time0 = sharedPreferences.getInt("TimeRetrieve", 0);
int sum = time0 + time;
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("TimeRetrieve", sum);
editor.apply();
Notice the call to getDefaultSharedPreferences. This will get the default com.companyname.package.yourapplication SharedPreferences file, and you should be using only that file if you want to set and retrieve data from it. There are other reasons you would create multiple SharedPreferences files, but I don't think that's what you're trying to do. You're also using two different keys, which is definitely a part of the problem as well. I changed them in the code above so that they match and you're referencing the same key both times.

Making a button toggle once a day

I'm trying to implement something in my Android application along these lines:
On any certain day if a user opens the app then they click a button, which will increment a number +1. Then can also click that button again which will put the number back to what it was so the number -1.
They can only do this once a day, so at most the number will be +1 from what it was before. But the user can click it and unlick it as many times as they want, it will only still be adding max +1 to the number.
I currently have something implemented: In my database I have a object for updatedTime. I then use a function to check if its on the same day:
private boolean isSameDay(int position){
Date currentDate = new Date();
Date updatedDate = mDataSource.get(position).getUpdated();
// Strip out the time part of each date.
int MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
long julianDayNumber1 = currentDate.getTime() / MILLIS_PER_DAY;
long julianDayNumber2 = updatedDate.getTime() / MILLIS_PER_DAY;
// If they now are equal then it is the same day.
return julianDayNumber1 == julianDayNumber2;
}
Which checks if it's the same day so user can't click on it again. Now I am stumped on figuring out how to make it toggleable so the user can click it again but it will just decrement it, and then user can click it again and it will increment it and so on, until the next day.
This is my OnClickListener for the button, not sure how to implement the toggle function.
habitChecked.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.i("In on Click:", ""+position+"");
updateHabit(position);
}
});
And this is my updateHabit method:
private void updateHabit(int position){
Realm.init(mContext);
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
if(!isSameDay(position)){ //If the habit hasn't already been updated today
mDataSource.get(position).setTracker(mDataSource.get(position).getTracker()+1);
mDataSource.get(position).setUpdated(new Date()); //update updated date
}
realm.commitTransaction();
}
To summarize: The current functionality is that the user can only click the button once a day which adds the +1, but can't "unclick" it to undo the click and increment, and then reclick it if they want to.
Any help would be appreciated and I can supply any other code that might be relevant.

I am creating an android app and I want multiple people to have access to the same number and be able to change that number with two buttons

I am creating an app where people report whether or not they have the flu that week. I already have the code that allows me to be able to add to the number of people who do have the flu and the number of people who don't have the flu by pressing buttons. It then creates a percentage of people who have the flu based on that data. But whenever I close out of the app, all of the data goes away. The same data also won't be able to be accessed by the other people with the app.
Here is the code for the app.
public void fluButton()
{
Button hasFluButton = (Button)findViewById(R.id.fluButton);
hasFluButton.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
TextView t1 = (TextView)findViewById(R.id.influenzaPercent);
NumberFormat defaultFormat = NumberFormat.getPercentInstance();
defaultFormat.setMinimumFractionDigits(2);
numPeopleWFlu += 1;
percentFlu = ((double)numPeopleWFlu) / (numPeopleWOFlu + numPeopleWFlu);
String percent = defaultFormat.format(percentFlu);
t1.setText(percent + " of people have had the flu this week.");
}
}
);
}
public void noFluButton()
{
Button hasNoFluButton = (Button)findViewById(R.id.noFluButton);
hasNoFluButton.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
TextView t1 = (TextView)findViewById(R.id.influenzaPercent);
NumberFormat defaultFormat = NumberFormat.getPercentInstance();
defaultFormat.setMinimumFractionDigits(2);
numPeopleWOFlu += 1;
percentFlu = ((double)numPeopleWFlu) / (numPeopleWOFlu + numPeopleWFlu);
String percent = defaultFormat.format(percentFlu);
t1.setText(percent + " of people have had the flu in missouri this year.");
}
}
);
}`.
This answer will only provide you with a very vague solution as your question is broad.
Here's what you need to do, you need to rent a server and put all the data to that server.
Why do you need a server? Because you want lots of people to access the data as the same time. If you save the data to your app's SharedPreferences or something local, other people won't be able to get it.
So now you have a server, in your app, you retrieve the data from the server at the start of your app. There are lots of external libraries out there that can help you fetch something from the internet.
After you retrieved the data, you display it in some views and BOOM! You did the first part. The second part is to save the data to the server. When the user taps on a button or something, you save the data.
Sounds easy, huh?

Android - How to save highscore of double value?

I have a double value which is in the range of 0-1. The new highscore value should be the lesser value of the two. Basically for example: if user A had a previous highscore of 0.6, and he just scored 0.4, the new highscore should be 0.4. Please be descriptive as I'm a beginner, thank you.
EDIT: Sorry I didn't make it descriptive enough, but I want the highscore to be saved and be able to be accessed again. So, if the user exits the app and revisits, it still shows the highscore.
It sounds like you'll want to use Shared Preferences to store the value for later: http://developer.android.com/training/basics/data-storage/shared-preferences.html, and then check this when you go to save it.
Here is sample code so you can call writeHighScore(score), and it will save it if it is lower than the previously saved high score:
void writeHighScore(float score)
{
if (score < getOldHighScore())
{
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putFloat("highscore", score);
editor.commit();
}
}
float getOldHighScore()
{
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
return sharedPref.getFloat("highscore", 1);
}
I used a float here instead of a double. If you want to store a double with shared preferences, you'll need to convert it to and from a Long, like here: Can't put double SharedPreferences

Android SharedPreferences auto incrementing technique

I wanted some feedback on this approach. My apologies if this is confusing or nonsensical. (thats probably why I'm asking because im unsure.)
My app auto assigns clientID's to a textview at first launch - is auto set to 100. To do this from that point forward I store an int value to sharedpreferences. At Oncreate I run a check against this specific ID in the sharedpreferences and later it either increments or assigns back to 100. The challenge was that sharedpreferences (that I know of) can only take a string value i.e. (editor.putString("CLIENTID", ID);) or editor.putInt("ID", c);
I wanted to avoid using a database for this portion to minimize overhead (could be wrong) There are validations in place that prevent this from being incremented unless certain conditions are met.
c is my persisted counter used in the shared preferences.
Here's what I did at oncreate:
public String ID; //global
int checkCount = prefs.getInt("ID", c); //get the current ID value currently set or last set.
if( checkCount > 100)
{
c = checkCount; //whatever the value of c is from its latest increment the counter c set to this
}
else if (checkCount <= 100)
{
c = 100; //base value of clientIDs //assign base value for starting clientIDs
}
ID = "" + c + ""; //sets value of the counter to a string
//Parsing integer was not passing correctly.
clientID.setText(ID);
In the onclick:
//Once all the conditions are met pass the clientID for this instance.
SharedPreferences.Editor editor = prefs.edit(); //USING EDITOR TO ADD TO THE PREFERENCES
editor.putInt("ID", c);
....// then other stuff.
Any thoughts? My apologies if this is a noob question. I just want to be sure about this approach if this app goes all the way.
Thanks

Categories