1

I'm new here and also new to programming. I'm currently working on a project and I've been stuck for bout a week now.The only thing I want to do is save two variables so that it still can be seen after the app is closed and reopened. Also for some reason when I open the Settings Activity my variables values are set back to zero.

I'm aware that others have posted similar questions like this but I just can't adapt it to my work. I don't understand a lot of things I read like SharedPreferences, onPause(), and GAME_STATE_KEY. Could anyone please explain how to do such a thing without linking the Android Documentation articles? I don't even understand what the documentation says and copy/pasting code there doesn't seem to work.

This is my MainActivity

package com.example.courtcounter;

import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity<format> extends AppCompatActivity {


    TextView textView;

     int scoreTeamA = 0;
     int scoreTeamB = 0;


    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy\n hh:mm aa");
    String format = simpleDateFormat.format(new Date());


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.team_a_score);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view) {
                String shareMessage = createMessage(format, scoreTeamA, scoreTeamB);

                Intent intent = new Intent(Intent.ACTION_SEND);
                intent.putExtra(Intent.EXTRA_SUBJECT, "Match Score");
                intent.setType("text/*");
                intent.putExtra(Intent.EXTRA_TEXT, shareMessage);
                if (intent.resolveActivity(getPackageManager()) != null) {
                    startActivity(intent);
                }
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main, menu);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        if (id == R.id.action_settings){

            Intent intent = new Intent(this, SettingsActivity.class);
            startActivity(intent);

            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private String createMessage(String date, int TeamA, int TeamB){

        EditText editTeamA = findViewById(R.id.team_a_name);
        String teamAName =editTeamA.getText().toString();

        EditText editTeamB = findViewById(R.id.team_b_name);
        String teamBName = editTeamB.getText().toString();


        String shareMessage =format +"\n"+ teamAName+ " : "+ TeamA + "\n" + teamBName + " : "+ TeamB;
        return shareMessage;
    }


    /** Resets score of boths teams to 0
     */
    public void resetScore(View v){
        scoreTeamA = 0;
        scoreTeamB = 0;
        displayForTeamA(scoreTeamA);
        displayForTeamB(scoreTeamB);
    }

    /**
     * Displays the given score for Team A.
     */
    public void displayForTeamA(int scoreTeamA){
        TextView scoreViewA = (TextView)findViewById(R.id.team_a_score);
        String teamA = scoreViewA.getText().toString();
        scoreViewA.setText(String.valueOf(scoreTeamA));

    }

    /**
     * Displays the given score for Team B.
     */
    public void displayForTeamB(int score) {
        TextView scoreViewB = (TextView) findViewById(R.id.team_b_score);
        String teamB = scoreViewB.getText().toString();
        scoreViewB.setText(String.valueOf(score));
    }

    /**
     * This method is called when the +3 points button is clicked.
     */
    public void ThreeA(View view){
        scoreTeamA = scoreTeamA +3;
        displayForTeamA(scoreTeamA);
    }

    /**
     * This method is called when the +2 points button is clicked.
     */
    public void TwoA(View view){
        scoreTeamA = scoreTeamA +2;
        displayForTeamA(scoreTeamA);
    }

    /**
     * This method is called when the FREE THROW button is clicked.
     */
    public void OneA(View view){
        scoreTeamA = scoreTeamA + 1;
        displayForTeamA(scoreTeamA);
    }

    /**
     * This method is called when the +3 points button is clicked.
     */
    public void ThreeB(View view){
        scoreTeamB = scoreTeamB +3;
        displayForTeamB(scoreTeamB);
    }

    /**
     * This method is called when the +2 points button is clicked.
     */
    public void TwoB(View view){
        scoreTeamB = scoreTeamB +2;
        displayForTeamB(scoreTeamB);
    }

    /**
     * This method is called when the FREE THROW button is clicked.
     */
    public void OneB(View view){
        scoreTeamB = scoreTeamB + 1;
        displayForTeamB(scoreTeamB);
    }


}

Do I have to change My SettingActivity and SettingsFragment to help solve this or is it not needed?

Thanks.

Nana Kwame
  • 942
  • 1
  • 6
  • 21

2 Answers2

2

If you want them to persist when the app is completely closed, SharedPreferences is the one you're looking for. This is a key/value store that allows you to store data that persists even after the activity is destroyed. Basically, they have two parts:

  1. The key is a unique identifier used to access the data
  2. The value is the actual data that you're trying to save

So first you get a reference to your shared preferences using

SharedPreferences.Editor editor = getSharedPreferences(
  MY_PREFS_NAME, MODE_PRIVATE).edit();

This MY_PREFS_NAME can be any string you like. It allows you access your "slice" of the shared preferences. Once you get this reference, now you can begin reading and writing to them.

To write:

editor.putInt("scoreViewA", 5);
editor.putInt("scoreViewB", 12);
editor.apply();

And later to read:

SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
int scoreViewA = prefs.getInt("scoreViewA", 0);
int scoreViewB = prefs.getInt("scoreViewB", 0);

This second parameter in getInt is a default that will be used if the given key is not found. Note that once again you must use the same MY_PREFS_NAME when retrieving a reference to the shared preferences.

Finally, note that when writing to shared preferences, we call edit() before writing any changes, and we call apply() afterwards.

You'll want to put your code to write to shared preferences in your onPause method. This fires whenever the activity is no longer in the foreground. Then do your reading in the onResume method. This method fires when the app regains focus in the foreground.

@Override
public void onPause() {
  super.onPause();
  // write to shared preferences
}

@Override
public void onResume() {
  super.onResume();
  // read from shared preferences
}

And if you're just trying to share a variable from one activity to a new one, you can use a bundle. Check out this answer for a good example.

Hope that helps, welcome to Stackoverflow!

Danny Buonocore
  • 3,731
  • 3
  • 24
  • 46
  • thanks, although I'm still having issues. The app keep crashing now and in logcat I see " Caused by: java.lang.NullPointerException:Attempt to invoke virtual method 'android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String, int)' on a null object reference" on the line `SharedPreferences.Editor editor = getSharedPreferences("MY_PREFS_NAME", MODE_PRIVATE).edit();`how do I resolve it, I tried declaring SharedPreferences.Editor in the onCreate class but it doesn't work. onPause() and onResume()is in MainActivity and I'm still trying but idk – Nana Kwame Jul 14 '20 at 21:05
1

I finally figured it out, it was very Cathartic. My main issue was figuring out where to put the methods and it looks like I didn't need the onPause() and onResume() methods.

First in the AndroidManifest.xml file I added android:launchMode="singleTop" but it the end it wasn't needed since I managed to save the preferences.

In my display methods I added SharedPreferences myScoreB = getSharedPreferences("teamBScore", Context.MODE_PRIVATE); SharedPreferences.Editor editor = myScoreB.edit();editor.putInt("scoreB", scoreTeamB);editor.commit();

The reading data part was confusing but in the end I managed to do it in the oncreate method SharedPreferences myScoreB = this.getSharedPreferences("teamBScore", Context.MODE_PRIVATE);scoreTeamB = myScoreB.getInt("scoreB", 0);scoreViewB.setText(String.valueOf(scoreTeamB));

It now handle screen rotations without recreating the entire layout as well as restarts.

Nana Kwame
  • 942
  • 1
  • 6
  • 21