private void setHighScore(){
SharedPreferences.Editor scoreEdit = gamePrefs.edit();
DateFormat dateForm = new SimpleDateFormat("MM/dd/yy");
String dateOutput = dateForm.format(new Date());
String scores = gamePrefs.getString("highScores", "");
if(scores.length() > 0) {
List<Score> scoreStrings = new ArrayList<Score>();
String[] exScores = scores.split("\\|");
for(String eSc : exScores){
String[] parts = eSc.split(" - ");
scoreStrings.add(new Score(parts[0], Integer.parseInt(parts[1])));
}
Score newScore = new Score(dateOutput, score);
scoreStrings.add(newScore);
Collections.sort(scoreStrings);
StringBuilder scoreBuild = new StringBuilder("");
for (int x = 0; x < scoreStrings.size(); x++){
if(x >= 10) break;
if(x > 0) scoreBuild.append("|");
scoreBuild.append(scoreStrings.get(x).getScoreText());
}
scoreEdit.putString("highScores", scoreBuild.toString());
scoreEdit.commit();
}else{
scoreEdit.putString("highScores", ""+dateOutput+ " - " + score);
scoreEdit.commit();
}
}
public class MyCount extends CountDownTimer{
public MyCount(long millisInFuture,long countDownInterval){
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish() {
final TextView time = (TextView) findViewById(R.id.time);
time.setText("Times Up!");
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
setHighScore();
Intent intent = new Intent(getApplicationContext(), score_screen.class);
startActivity(intent);
finish();
}
#Override
public void onTick(long millisUntilFinished){
final TextView time = (TextView) findViewById(R.id.time);
time.setText("Left: " + millisUntilFinished/1000);
}
}
public class score_screen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_score_screen);
TextView scoreView = (TextView)findViewById(R.id.scoreView);
ImageButton home = (ImageButton)findViewById(R.id.home);
SharedPreferences scorePrefs = getSharedPreferences(Game.GAME_PREFS, 0);
String[] savedScores = scorePrefs.getString("highScores", "").split("\\|");
StringBuilder scoreBuild = new StringBuilder("");
for(String score : savedScores) {
scoreBuild.append(score+"\n");
}
scoreView.setText(scoreBuild.toString());
home.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), ColorMatch.class);
startActivity(intent);
}
});
}
}
I am trying to save a highscore from my gamescreen after my timer is up. I am able to do this just fine and then when I re access my ArrayList for a second time the last score is resaved and I can't figure out why this is happening.
For example,after one game is finished with a score of 3170, it takes me to the high score screen where I see only one instance of the score. Then if I play a new game, or open my Highscores screen from the Main menu, I now see two instances of the same score. (3170) My guess is that it is double committing the score, but I cannot find a second .commit() in my highscore screen.
Actually you may not be saving the high score to preferences twice. I think the problem lies in that you are appending the high score.
Instead of appending the high score, you need to insert the high score into some position in the array. Java arrays are a fixed size though, so you may want to consider using an ArrayList or LinkedList.
In a method I didn't post, (OnDestroy()) I had a second instance of the method setHighScore() to store the score if someone backed out. When I removed this it stopped double writing making me believe that the problem was finish() references onDestroy() to close the activity.
Related
Im new to Android development. I want to take a user input as a double value and then pass it to the next activity, and then sum it with another value, but I am having trouble passing it.
When passing this double array called winning onto activity 2, I recieve an error. The error is: Incompatible types.
Required: java.util.ArrayList Found: double[]
Activity 1
public void btnAdd_OnClick(View v)
{
{
if (txtWinnings.getText().toString().isEmpty()) {
displayToast("Please enter an amount");
}else{
double winning =
Double.parseDouble(txtWinnings.getText().toString());
if(winning > 0) {
winnings.add(winning);
txtWinnings.setText("");
txtWinnings.setHint("You have added " + (winnings.size()) +
" tournament winnings");
} else {
displayToast("You must enter an amount more than 0");
}
}
}
}
public void btnClear_OnClick(View v)
{
if(winnings.size() < 0)
{
displayToast("You have no winnings to clear");
}else {
winnings.clear();
displayToast("Cleared");
}
}
public void btnSummary_OnClick(View v)
{
{
if(winnings.size() > 0)
{
Intent i = new Intent(this, SummaryActivity.class);
i.putExtra("winnings", winnings);
startActivity(i);
}else{
displayToast("You must enter at least one amount of winnings");
}
}
}
public void displayToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
}
Activity 2
public class SummaryActivity extends AppCompatActivity {
ArrayList<Double> winnings = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_summary);
setTitle("Summary");
TextView lblTournaments = (TextView) findViewById(R.id.txtAverage);
TextView lblTotal = (TextView) findViewById(R.id.txtTotal);
TextView lblMax = (TextView) findViewById(R.id.txtMax);
TextView lblMin = (TextView) findViewById(R.id.txtMin);
TextView lblAverage = (TextView) findViewById(R.id.txtAverage);
Intent i = getIntent();
winnings = i.getDoubleArrayExtra("winnings");
}
}
winnings is a ArrayList<Double>. You cannot assign it a double[] as you do at this line :
winnings = i.getDoubleArrayExtra("winnings");
You can convert the double[] to a List<Double> like this :
List<Double> winnings = Arrays.stream(i.getDoubleArrayExtra("winnings"))
.mapToObj(d-> d)
.collect(Collectors.toList());
Using streams for that is a bit overkill but learning streams is worth it.
EDIT :
Stream might not be available (see comments). Without Stream, you can manually empty the winnings collection then iterate on the array to fill it again :
double[] array = i.getDoubleArrayExtra("winnings");
winnings.clear();
for(double winning : array) {
winnings.add(winning);
}
I am developing an android app and want to save a rand2(Double type) value using savedInstanceState so that i can use rand2 value whenever app is reopened but while retrieving rand2 value it always comes NULL, Either the value is not saving or value is not retrieving . Why it is happening and what should i do to save rand2 value so that i can reuse it when the app is reopened?
public class MainActivity extends AppCompatActivity {
double rand2;
private boolean started = false;
private Handler handler = new Handler();
public Runnable runnable = new Runnable() {
#Override
public void run() {
double rand1 = Math.random() * 5;
rand2 = rand2 + rand1 * 0.04;
DecimalFormat df = new DecimalFormat("0.00");
String message1 = "" + df.format(rand1);
DecimalFormat dff = new DecimalFormat("000000.00");
String message2 = "" + dff.format(rand2);
displayRate(message1);
displaySatoshi(message2);
if (started) {
start(started);
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// recovering the instance state
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
if (savedInstanceState != null) {
rand2 = savedInstanceState.getDouble("abc");
} else {
rand2 = 0.00;
}
setContentView(R.layout.activity_main);
// Find the View that shows the numbers category
TextView numbers = (TextView) findViewById(withdraw);
// Set a click listener on that View
numbers.setOnClickListener(new View.OnClickListener() {
// The code in this method will be executed when the numbers View is clicked on.
#Override
public void onClick(View view) {
Intent numbersIntent = new Intent(MainActivity.this, Withdraw.class);
startActivity(numbersIntent);
}
});
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putDouble("abc", rand2);
// call superclass to save any view hierarchy
super.onSaveInstanceState(savedInstanceState);
}
public void Start(View v) {
ToggleButton starStopTogglrButton = (ToggleButton) findViewById(R.id.start_stop);
boolean hasStartStop = starStopTogglrButton.isChecked();
if (hasStartStop) {
start(hasStartStop);
} else {
stop(hasStartStop);
}
}
public void stop(Boolean hasStartStop) {
//Checking start or stop
started = hasStartStop;
handler.removeCallbacks(runnable);
}
public void start(Boolean hasStartStop) {
started = hasStartStop;
handler.postDelayed(runnable, 1000);
}
private void displayRate(String message1) {
TextView orderSummaryTextView = (TextView) findViewById(R.id.rate);
orderSummaryTextView.setText(message1);
}
private void displaySatoshi(String message2) {
TextView orderSummaryView = (TextView) findViewById(R.id.satoshis);
orderSummaryView.setText(message2);
}
}
onSaveInstanceState is called when the app is closed, but onCreate is only called when the app is booted after it's been finished. Remember the acitvity lifecycle:
So since onSaveInstanceState is called at closing and onCreate only is called when the activity is (re)created, it is null because it isn't added at that time.
You're looking for onRestoreInstanceState. Override that method and grab the variable and assign it from there.
Remember that using the savedInstanceState does not save the data if the activity is completely destroyed. For persistent data storage, use sharedprefs, files or SQL
I did a small android application which is about taking time from the user by timePicker and if the chosen time is same as the current one, the application sends you a notification. This is the code that I wrote on android studio :
public Button mb;
public EditText editText;
public Button pb;
int i=0;
public void showMotivation(){
mb = (Button)findViewById(R.id.mb);
editText = (EditText)findViewById(R.id.editText);
mb.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
editText.setText(MotivationWords());
}
}
);
}
public String MotivationWords(){
Random rnd = new Random();
List l = new LinkedList<>();
l.add("The price of excellence is discipline; the cost of mediocrity is disappointment.");
l.add("If we had no winter, the spring would not be so pleasant; if we did not sometimes taste of adversity, prosperity would not be so welcome.");
l.add("If your ship doesn’t come in, swim out to it!");
l.add("Tomorrow will be a better day ..");
l.add("Life’s not about waiting for the storms to pass... it’s about learning to dance in the rain.");
l.add("When you reach the end of your rope, tie a knot in it and hang on.");
l.add("A smooth sea never made a skilled mariner.");
l.add("Great masters merit emulation, not worship.");
l.add("Confidence is contagious. So is the lack of confidence.");
l.add("Optimism may sometimes be delusional, but pessimism is always delusional.");
i=rnd.nextInt()%9;
return l.get(i).toString();
}
public void changing(){
pb = (Button)findViewById(R.id.pb);
pb.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intb = new Intent(MainActivity.this, Main2Activity.class);
startActivity(intb);
}
}
);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
changing();
showMotivation();
}
public Button tb;
public Button bb;
public TimePicker timep;
public int h,m;
public int curh, curm;
public Calendar c;
NotificationCompat.Builder mbuilder = new NotificationCompat.Builder(this);
public int i;
public void change2(){
bb = (Button)findViewById(R.id.bb);
bb.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intbb = new Intent(Main2Activity.this, MainActivity.class);
startActivity(intbb);
}
}
);
}
public String MotivationWords(){
Random rnd = new Random();
List l = new LinkedList<>();
l.add("The price of excellence is discipline; the cost of mediocrity is disappointment.");
l.add("If we had no winter, the spring would not be so pleasant; if we did not sometimes taste of adversity, prosperity would not be so welcome.");
l.add("If your ship doesn’t come in, swim out to it!");
l.add("Tomorrow will be a better day ..");
l.add("Life’s not about waiting for the storms to pass... it’s about learning to dance in the rain.");
l.add("When you reach the end of your rope, tie a knot in it and hang on.");
l.add("A smooth sea never made a skilled mariner.");
l.add("Great masters merit emulation, not worship.");
l.add("Confidence is contagious. So is the lack of confidence.");
l.add("Optimism may sometimes be delusional, but pessimism is always delusional.");
i=rnd.nextInt()%9;
return l.get(i).toString();
}
public void takeTime(){
timep = (TimePicker)findViewById(R.id.timep);
timep.setOnTimeChangedListener(
new TimePicker.OnTimeChangedListener() {
#Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
h = hourOfDay;
m = minute;
curh = c.get(Calendar.HOUR);
curm = c.get(Calendar.MINUTE);
if( (h==curh) && (m == curm) ){
mbuilder.setContentTitle("Your Motivation For now :");
mbuilder.setContentText(MotivationWords());
}
}
}
);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
change2();
tb = (Button)findViewById(R.id.tb);
tb.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
takeTime();
}
}
);
}
here is my code it is working pls tell me what code i should write to every 5th launch the dialog box should show, mean when user launch application 5th time in a day then should show dialog box for rating app,similarly every 5th launch dialog box should be show.
public class MainActivity extends Activity {
String android_id,version,ver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//********************For Rating APP **********************
SharedPreferences sharedPrefs = MainActivity.this.getSharedPreferences("RATER", 0);
SharedPreferences.Editor prefsEditor = sharedPrefs.edit();
long time = sharedPrefs.getLong("displayedTime", 0);
if (time < System.currentTimeMillis() - 259200000) {
displayDialog();
prefsEditor.putLong("displayedTime", System.currentTimeMillis()).commit();
}
}
//dialog box Function for rating app.
private void displayDialog() {
// TODO Auto-generated method stub
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
//Yes button clicked
Intent in = new Intent(android.content.Intent.ACTION_VIEW);
in.setData(Uri.parse(url));
startActivity(in);
break;
case DialogInterface.BUTTON_NEGATIVE:
//No button clicked
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Rate This App");
builder.setMessage("You really seem to like this app, "
+"since you have already used it %totalLaunchCount% times! "
+"It would be great if you took a moment to rate it.")
.setPositiveButton("Rate Now", dialogClickListener)
.setNegativeButton("Latter", dialogClickListener)
.setNeutralButton("No,thanks", dialogClickListener).show();
}
//End dialog box Function for rating app.
}
Here is my code actually i want to implement app rating dialog box in application that should display every 5th time launch in a day
Use below method to check Launch Count.
private void checkLaunchCount()
{
int sessionUniqueId = mSharedPref.getInt("DATE_UNIQUE", 0);
int launchCount = mSharedPref.getInt("LAUNCH_COUNT", 0);
if(sessionUniqueId != 0)
{
int todayUniqueId = getUniqueNumberFromDate();
if(todayUniqueId == sessionUniqueId)
{
if(launchCount >= 5)
{
//Show Dialog
}
else
{
updateLaunchCount(launchCount);
}
}
else
{
updateUniqueDateId();
updateLaunchCount(launchCount);
}
}
else
{
updateUniqueDateId()
updateLaunchCount(launchCount);
}
}
This method used to getUniqueInt for the Date
private int getUniqueNumberFromDate()
{
Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.DAY_OF_YEAR);
}
This method use to save day in SharedPref
private static SharedPreferences mSharedPref;
private void updateUniqueDateId()
{
if(mSharedPref == null)
mSharedPref = getActivity().getSharedPreferences(getActivity().getPackageName(), Activity.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = mSharedPref.edit();
prefsEditor.putInt("DATE_UNIQUE", getUniqueNumberFromDate()).commit();
}
This method use to save count in SharedPref
private void updateLaunchCount(int launchCount)
{
launchCount++;
SharedPreferences.Editor prefsEditor = mSharedPref.edit();
prefsEditor.putInt("LAUNCH_COUNT", launchCount).commit();
}
You can get a Calendar values and one counter, and store its value to the preferences.
Calendar rightNow = Calendar.getInstance();
int year = rightNow.get(rightNow.YEAR);
int dayOfYear = rightNow.get(rightNow.DAY_OF_YEAR);
int count = mPreferences.getInt("launchCount",0);
int storedYear = mPreferences.getInt("storedYear",0);
int storedDayOfYear = mPreferences.getInt("storedDayOfYear",0);
if (storedYear == year && storedDayOfYear == dayOfYear) {
if (count == 5) {
//rate
}
count++;
mPreferences.edit().putInt("launchCount",count).commit();
} else {
mPreferences.edit().putInt("year",count);
mPreferences.edit().putInt("dayOfYear",count);
count = 1;
mPreferences.edit().putInt("launchCount",count);
mPreferences.edit().commit();
}
Something like that, have not tried it, but you can get an idea...
I made an app for my use for calculating a string of values appear in an another activity. My app has 3 editTexts and one button. If we press button calculate with the input in edit text and calculated values will displayed in a second activity. I made it successfully but my problem is if the user is leave any of the boxes empty and press the button, the system will Force Close. To avoid this I made editText in graphical layout pre entered with a hint. But if the user accidentally presses button after editing the editText again system shows a Force Close.
I tried many if else methods but it does not work. Some one show me a correct way to check all editText boxes.
public class Screen1 extends Activity {
public static StringBuilder EXTRA_MESSAGE=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.screen1);
Button bu1= (Button)findViewById(R.id.bu);
bu1.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View message)
{ int f1,f3,f4;
String vis;
EditText t1=(EditText)findViewById(R.id.a);
EditText t3=(EditText)findViewById(R.id.c);
EditText t4=(EditText)findViewById(R.id.d);
String e1=t1.getText().toString();
String e3= t3.getText().toString();
String e4= t4.getText().toString();
f1 =Integer.parseInt(e1);
f4=Integer.parseInt(e4);
f3=Integer.parseInt(e3);
StringBuilder sb = new StringBuilder();
for( float i= (float)0.1;i<=5;i=i+(float) .1)
{
sb.append(String.format("%.1f", i)+" mcg = "+(f1*60*i*f4)/(f3*1000)+"\n");
}
vis=sb.toString();
Intent intent = new Intent(message.getContext(),Screen2.class);
intent.putExtra("EXTRA_MESSAGE",vis);
startActivity(intent);
}
});
}
}
Using [TextUtils][1] check isEmpty() text inside your onClick:
#Override
public void onCreate(Bundle savedInstanceState){
EditText t1=(EditText)findViewById(R.id.a);
EditText t3=(EditText)findViewById(R.id.c);
EditText t4=(EditText)findViewById(R.id.d);
Button bu1 = (Button) findViewById(R.id.bu);
bu1.setOnClickListener(this);
}
#Override
public void onClick(View message){
boolean foundEmpty = false;
if(TextUtils.isEmpty(t1.getText())) {
foundEmpty = true;
t1.setError("Please Enter a value");
}
if(TextUtils.isEmpty(t2.getText()){
foundEmpty = true;
t2.setError("Please Enter a value");
}
if(TextUtils.isEmpty(t3.getText()){
foundEmpty = true;
t3.setError("Please enter a value");
}
if(!foundEmpty){
/* none of your text fields are empty */
int f1, f3, f4;
f1 =Integer.parseInt(e1);
f4=Integer.parseInt(e4);
f3=Integer.parseInt(e3);
final StringBuilder sb = new StringBuilder();
for( float i= (float)0.1;i<=5;i=i+(float) .1) {
sb.append(String.format("%.1f", i)+
" mcg = "+
(f1*60*i*f4)/(f3*1000)+"\n");
}
final String vis = sb.toString();
Intent intent = new Intent(message.getContext(), Screen2.class);
intent.putExtra("EXTRA_MESSAGE", vis);
startActivity(intent);
}
}
From what I gather from your question, you're getting an error when bu1 is clicked, and at least one of the EditTexts is empty. This is because you're calling Integer.parseInt() on an empty String. The following code will check if the boxes are empty, and show a Toast if any are. It will also show a Toast if the user enters anything that's not a valid number:
public class Screen1 extends Activity
{
private static final String EXTRA_MESSAGE = "extra_msg";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.screen1);
final EditText t1 = (EditText)findViewById(R.id.a);
final EditText t3 = (EditText)findViewById(R.id.c);
final EditText t4 = (EditText)findViewById(R.id.d);
Button bu1 = (Button)findViewById(R.id.bu);
bu1.setOnClickListener(new View.OnClickListener()
{
public void onClick(View message)
{
int f1,f3,f4;
String e1 = t1.getText().toString();
String e3 = t3.getText().toString();
String e4 = t4.getText().toString();
if (e1.equals("") || e3.equals("") || e4.equals(""))
{
Toast.makeText(Screen1.this, "Please enter all numbers.", Toast.LENGTH_SHORT).show();
return;
}
try
{
f1 = Integer.parseInt(e1);
f4 = Integer.parseInt(e4);
f3 = Integer.parseInt(e3);
StringBuilder sb = new StringBuilder();
for (float i = 0.1f; i <= 5; i = i + .1f)
{
sb.append(String.format("%.1f", i) + " mcg = " + (f1 * 60 * i * f4) / (f3 * 1000) + "\n");
}
Intent intent = new Intent(Screen1.this, Screen2.class);
intent.putExtra(EXTRA_MESSAGE, sb.toString());
startActivity(intent);
}
catch (NumberFormatException e)
{
Toast.makeText(Screen1.this, "Invalid numbers.", Toast.LENGTH_SHORT).show();
}
}
}
);
}
}