How do I save variable values across Activities in Android Studio - java

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.

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:
The key is a unique identifier used to access the data
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!

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.

Related

How to change the background color of a view from a different activity in android?

I am working on a Quiz app. First when a user opens the app they go to the MainActivity, from there when they press start they go to the Categories Activity , from there after selecting a category they go to the Sets Activity, from there after selecting a set the go to the Questions Activity and finally after completing all the questions they reach the Score Activity. Here in the score activity when the click on Done button they are redirected to the MainActivity. In the Score Activity i want to change the color of the Set that they completed to green instead of the default color. How can i do this? I created a sets item layout xml file and used an adapter to fill the gridview in the Sets Activity with views from the adapter. Currently i am getting a null object reference after clicking the Done button in the ScoreActivity.
Here is the code :
SetsAdapter.java
public class SetsAdapter extends BaseAdapter {
private int numOfSets;
public SetsAdapter(int numOfSets) {
this.numOfSets = numOfSets;
}
#Override
public int getCount() {
return numOfSets;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
View view;
if(convertView == null){
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.set_item_layout, parent, false);
}
else {
view = convertView;
}
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent questionIntent = new Intent(parent.getContext(), QuestionActivity.class);
questionIntent.putExtra("SETNUM", position +1);
parent.getContext().startActivity(questionIntent);
}
});
((TextView) view.findViewById(R.id.setNumber)).setText(String.valueOf(position+1));
return view;
}
}
SetsActivity.java
public class SetsActivity extends AppCompatActivity {
private GridView sets_grid;
private FirebaseFirestore firestore;
public static int categoryID;
private Dialog loadingDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sets);
Toolbar toolbar = (Toolbar)findViewById(R.id.set_toolbar);
setSupportActionBar(toolbar);
String title = getIntent().getStringExtra("CATEGORY");
categoryID = getIntent().getIntExtra("CATEGORY_ID",1);
getSupportActionBar().setTitle(title);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
sets_grid = findViewById(R.id.sets_gridView);
loadingDialog = new Dialog(SetsActivity.this);
loadingDialog.setContentView(R.layout.loading_progressbar);
loadingDialog.setCancelable(false);
loadingDialog.getWindow().setBackgroundDrawableResource(R.drawable.progress_background);
loadingDialog.getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
loadingDialog.show();
firestore = FirebaseFirestore.getInstance();
loadSets();
}
private void loadSets() {
firestore.collection("Quiz").document("CAT" + String.valueOf(categoryID))
.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot doc = task.getResult();
if (doc.exists()) {
long sets = (long) doc.get("SETS");
SetsAdapter adapter = new SetsAdapter(Integer.valueOf((int)sets));
sets_grid.setAdapter(adapter);
} else {
Toast.makeText(SetsActivity.this, "No Sets Exists!", Toast.LENGTH_SHORT).show();
finish();
}
} else {
Toast.makeText(SetsActivity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
loadingDialog.cancel();
}
});
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if(item.getItemId() == android.R.id.home)
finish();
return super.onOptionsItemSelected(item);
}
}
ScoreActivity.java
public class ScoreActivity extends AppCompatActivity {
private TextView score;
private Button done;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_score);
score = findViewById(R.id.score_tv);
done = findViewById(R.id.score_activity_done);
String score_str = getIntent().getStringExtra("SCORE");
final int setNum = getIntent().getIntExtra("SetNum", 1);
score.setText(score_str);
done.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Here is the issue I am facing
View view = findViewById(R.id.setNumber);
view.setBackgroundColor(Color.GREEN);
Intent mainIntent = new Intent(ScoreActivity.this, MainActivity.class);
startActivity(mainIntent);
ScoreActivity.this.finish();
}
});
}
}
As your activity Sequence is MainActivity -> Categories -> Sets -> Scores.
You've two options to change the color with two different life cycle of the change.
To change the color on a temporary basis, this will reset itself after closing the app or resrtating the 'Sets' activity. It can be done in two ways: Using Public Static Variable and using a public function.
To change the color on a permanent basis until the app is uninstalled/reinstalled. You should use SharedPreferences. SharedPreferences acts like a private data stored in device's memory for further use and it stays there unchanged until and unless the app is removed/data is cleared. Although, apps with root permission can access any app's SharedPreferences data and can modify it as well.You can use SharedPreferences as explained here. Or, you can use some library to access it an easy way. The way I use it in all my apps is TinyDB(it's just a java/kotlin file). This works as:
//store the value from ScoreActivity after completion as
TinyDB tinyDB = TinyDB(this);
tinyDB.putBoolean("isSet1Completed",true);
//access the boolean variable in SetsActivity to change the color of any set that
//is completed and if it's true, just change the color.
TinyDB tinyDB = TinyDB(this);
Boolean bool1 = tinyDB.getBoolean("isSet1Completed");
But, it's your choice what way you want to prefer.
Now, this was about the lifecycle of the change you'll do: Temp or Permanent. Now, we'll talk about how you change the color.
Using public static variable in Sets activity. What you can do is you can set the imageView/textview whose background you want to change as public static variable. Remember, this idea is not preferred as it causes memory leak but it's just easy.
Declare it as public static ImageView imageview;(or TextView) intialize it in the
onCreated() as imageView = finViewById(R.id.viewId); in Sets activity. Call
it as new SetsActivity().imageView.setBackgroundColor(yourColor); in ScoreActivity.
Second way is to create a public function in SetsAcitvity, putting the color change code in it, and then calling it from the ScoreActivity. Just declare it as public void changeColor(){ //your work} and call it from ScoreActivity as new SetsActivity().changeCOlor(). You can also pass some arguments to the function like setId.
I've provided you every thing you need. Rest you should figure out yourself to actually learn it and not copy it.
I think simply you add flag in MainActivity.
for example, add flag in MainActivity.
boolean isFromDone = false;
and when done clicked,
done.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Here is the issue I am facing
Intent mainIntent = new Intent(ScoreActivity.this, MainActivity.class);
mainIntent.putExtra("FromDone", true);
startActivity(mainIntent);
ScoreActivity.this.finish();
}
});
and in MainActivity, add this.
#Override
protected void onResume() {
super.onResume();
isFromDone = getIntent().getBooleanExtra("FromDone", false);
if(isFromDone) {
(TextView) view.findViewById(R.id.setNumber)).setBackgroundColor(Color.GREEN);
}
}
Suppose you have a Linear Layout in Activity A and you want to change it's background color from a button click which is present in Activity B.
Step 1 Create a class and declare a static variable.
class Util { private static LinearLayout mylayout ; }
Step 2
In the activity which is holding this layout, initialize it.
Util.mylayout = findviewbyid(R.id.linear);
Step 3Change the background color on button click from Activity B
onClick{
Util.mylayout.setBackgroundColor(Color.RED);
}

Initializing variables in onCreate, but updating them in onResume()

Here is my situation:
I have an OnCreate code like the following:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bunz = Bunz.getInstance(); //getting instance of bunz
bunz.setBunz(50);
bunz.setMoney(0);
bunz.setIncrement(1);
Button upgradeButton = (Button) findViewById(R.id.upgradeButton);
upgradeButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
Intent startIntent = new Intent(getApplicationContext(), UpgradeMenu.class);
startActivity(startIntent);
}
});
moneyCount = (TextView) findViewById(R.id.moneyCount);
bunzCount = (TextView) findViewById(R.id.bunzCount);
ImageButton bun = (ImageButton) findViewById(R.id.bun);
}
Notice how in my OnCreate code, I do 2 things; first, I initialize all the values I need:
bunz.setBunz(50);
bunz.setMoney(0);
bunz.setIncrement(1);
and then I display these values on TextViews and set up some Buttons and intents:
Button upgradeButton = (Button) findViewById(R.id.upgradeButton);
upgradeButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
Intent startIntent = new Intent(getApplicationContext(), UpgradeMenu.class);
startActivity(startIntent);
}
});
moneyCount = (TextView) findViewById(R.id.moneyCount);
bunzCount = (TextView) findViewById(R.id.bunzCount);
ImageButton bun = (ImageButton) findViewById(R.id.bun);
I'm new to Android studio, and here is the problem I'm having. I want to use onResume() to update these values in the TextView (I update them in another activity) every time I go back to this activity. However, if I move all the code in onCreate into onResume, then every time I go back to this activity, the values will be set to 50,0, and 1. I understand I could use a boolean, so that onCreate() triggers the first time the app is launched, but onResume() doesn't trigger, and then onResume() triggers after that, and simply copy and paste the second half of the onCreate code into onResume(), but that seems inefficient, and isn't how Android studio is designed to work. Can I somehow initialize the values in another location?
I have a global Bunz class that looks like the following:
public class Bunz {
private int bunz;
private int money;
private int increment;
//singleton code
private static Bunz instance;
private Bunz(){
}
public static Bunz getInstance(){
if (instance == null){
instance = new Bunz();
}
return instance;
}
public int getBunz() {
return bunz;
}
public void setBunz(int num){
bunz = num;
}
public int getMoney(){
return money;
}
public void setMoney(int num){
money = num;
}
public int getIncrement(){
return increment;
}
public void setIncrement(int num){
increment = num;
}
}
so maybe I could initialize these values here somehow?
Thanks!
here's one thing you could alternatively do:
public static Bunz getInstance(){
if (instance == null){
instance = new Bunz();
instance.setBunz(50);
instance.setMoney(0);
}
return instance;
}
in your instance creation here, try setting the values you want here, instead of in onCreate of the app.
you could just be making the changes in the constructor as well.
While your code uses statics, which I believe is unnecessary. Statics are not your average goto solution, they come with a hefty price of an object not eligible for GC.
You can get the result from the second activity via onActivityResult method.
First, start second activity using startAtivityForResult() //This takes in a request code(Int), it can be whatever you set.
First activity
Intent intent = new Intent(this, SecondActivity.class);
startActivityForResult(intent , 100);
Second Activity
//Do you work in the second activity, generate new data
Intent returnIntent = new Intent();
returnIntent.putExtra("bunz", 100);
returnIntent.putExtra("money", 200);
returnIntent.putExtra("increment", 2);
setResult(Activity.RESULT_OK, returnIntent);
finish();
Capture Second Activity Result
This code is supposed to be written in your first activity.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100) { //Remember the code we set in startActivityForResult? This is where we identify our work
if(resultCode == Activity.RESULT_OK){ //Code to check if data is passed
Int bunz =data.getIntExtra("bunz")
bunz.setBunz(bunz)
.....
}
}
}

How do I store game scores including team names for a basketball score counter app?

I'm trying to store game scores including the team names and date when it was stored from my basketball game counter app when clicking a save button.
Here is the Java code:
package com.example.android.courtcounter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
int scoreTeamA = 0;
int scoreTeamB = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
displayForTeamA(0);
displayForTeamB(0);
setTitle("Basketball Count");
Toast.makeText(getApplicationContext(), "You can change team names and scores manually by clicking on them", Toast.LENGTH_LONG).show();
}
// +3 Points for Team A
public void addThreeForTeamA (View view) {
scoreTeamA = scoreTeamA + 3;
displayForTeamA(scoreTeamA);
}
// +2 Points for Team A
public void addTwoForTeamA (View view) {
scoreTeamA = scoreTeamA + 2;
displayForTeamA(scoreTeamA);
}
// +1 Point for Team A
public void addOneForTeamA (View view) {
scoreTeamA = scoreTeamA +1;
displayForTeamA(scoreTeamA);
}
// Displays the given score for Team A.
public void displayForTeamA(int score) {
TextView scoreView = (TextView) findViewById(R.id.team_a_score);
scoreView.setText(String.valueOf(score));
}
// +3 Points for Team B
public void addThreeForTeamB (View view) {
scoreTeamB = scoreTeamB + 3;
displayForTeamB(scoreTeamB);
}
// +2 Points for Team B
public void addTwoForTeamB (View view) {
scoreTeamB = scoreTeamB + 2;
displayForTeamB(scoreTeamB);
}
// +1 Point for Team B
public void addOneForTeamB (View view) {
scoreTeamB = scoreTeamB +1;
displayForTeamB(scoreTeamB);
}
// Displays the given score for Team B.
public void displayForTeamB(int score) {
TextView scoreView = (TextView) findViewById(R.id.team_b_score);
scoreView.setText(String.valueOf(score));
}
public void resetScore (View view) {
scoreTeamA = 0;
scoreTeamB = 0;
displayForTeamA(scoreTeamA);
displayForTeamB(scoreTeamB);
}
}
I've stored the scores and team names in EditText views and want to save them and load them later. Anyone got an idea what to use for saving and loading a specific game score?
I recognize this code from Udacity's excellent "Intro to Android" course .. You'd have to use sharedPreferences to save the scores. For example:
SharedPreferences sharedPref = getSharedPreferences(
getString(R.string.preference_file_key), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("scoreTeamA", scoreTeamA);
editor.putInt("scoreTeamB", scoreTeamB);
editor.apply();
And then to retrieve the values:
SharedPreferences sharedPref = getSharedPreferences(
getString(R.string.preference_file_key), Context.MODE_PRIVATE);
int scoreTeamA = sharedPref.getInt(scoreTeamA, 0);
int scoreTeamB = sharedPref.getInt(scoreTeamB, 0);
You could use databases but I think it is more than what you need.
You could also use files:
Add these at your manifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Add two functions:
void writeToFile(String string) {
FileOutputStream outputStream = openFileOutput("thiswillbethenameofyourfile", Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
}
String readFromFile() {
String content;
FileInputStream inputStream = openFileInput("thiswillbethenameofyourfile");
byte[] buffer = new byte[1024];
int n;
while ((n = inputStream.read(buffer)) != -1)
{
content.append(new String(buffer, 0, n));
}
return content;
}
Call WriteToFile with a string that contains the score.
Call readFromFile to get that score back.
You can use multiple files to store multiple data right if you should store every thing in one file but this is a good start!
Also as #Andrew Sun mentioned you could use sharedPreferences
https://developer.android.com/training/basics/data-storage/shared-preferences.html
If you want to create a database for all users around the world, you should use SQL and maybe php programming languages. SQL for database editting, php for controlling the database edittings.
But if you just want to store the data just for the device you are using the app on then you can simply create a text file in the android project file. Then you can fill the text file in the way you want using code.

Android Studio 'Run app' dialogue doesn't appear in one project but will in another

I'm toying with Android Studio making a very simple very stupid app to learn about saving key preferences and I ran into a weird obstacle. I'll try to provide as much as I can since it may be hard to reproduce this bug but honestly both apps I'm running are super basic and there no compile errors.
Specs:
No emulator, I'm running a Samsung Galaxy Tablet. Windows 7, Android Studio 1.2, Gradle 2.2.1.
In the question title, I mean that I have a project named Kitty (pretty much hello world and a button). I click Run->'Run app'->(Dialogue box opens)->OK->Within moments the app launches on my tablet.
^^^THIS IS THE BEAUTIFUL SCREEN I WANT TO SEE ON Sharedpreferences, but it's only on kitty.
Now I started another project called SharedPreferences (gist: two checkboxes ask you "do you like chocolate" and "do you like luigi" and you check one none or both and press save. Two textviews underneath will update to say if you like those things and even later if you reopen the app the textviews will remember Chocolate Luigi preferences). It is just a main_activity.
I don't think I changed any settings or project preferences between the two and neither give me an error. MainActivity.java OUTDATED ORIGINAL SEE EDIT:
package gaga.sharedpreferences;
import android.content.SharedPreferences;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
public final class setup extends MainActivity {
public void setup () {
//Nothing to see here!
}
// Define the File of Prefs; created if nonexistent
public static final String PREFS_NAME = "MyPrefsFile";
// Start up
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
// Restore preferences on Startup
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean Chocolate = settings.getBoolean("checkChocolate", false);
boolean Luigi = settings.getBoolean("checkLuigi", false);
// Function set to Whatever
// setSilent(silent);
/* Note:
* CheckedTextView and CheckBox::isChecked()
* CheckBox::setChecked()
* */
CheckBox checkHandleChocolate = (CheckBox) findViewById(R.id.checkChocolate);
CheckBox checkHandleLuigi = (CheckBox) findViewById(R.id.checkLuigi);
// What was the preference? On Start set it to the bool it left off in
checkHandleChocolate.setChecked(Chocolate);
checkHandleLuigi.setChecked(Luigi);
// Change report text on Start
TextView buttonHandleChocolate = (TextView) findViewById(R.id.chocolate);
TextView buttonHandleLuigi = (TextView) findViewById(R.id.luigi);
if(Chocolate)
buttonHandleChocolate.setText("I do prefer Chocolate");
else
buttonHandleChocolate.setText("I do not prefer Chocolate");
if(Luigi)
buttonHandleLuigi.setText("I do prefer Luigi");
else
buttonHandleLuigi.setText("I do not prefer Luigi");
}
public void saveChocolate(Boolean c) {
// All objects from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("Chocolate", c);
// Commit the edits
editor.commit();
}
public void saveLuigi(Boolean l) {
// All objects from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("Chocolate", l);
// Commit the edits
editor.commit();
}
}
#Override
protected void onStop(){
super.onStop();
// Objects are from android.context.Context
//Normally I'd put the edit commits here, but that's not true
}
// Clicks on Done
public void userDone (View view) {
// View is which widget
boolean checked = ((CheckBox) view).isChecked();
// Which checkbox was clicked
switch(view.getId()) {
case R.id.checkChocolate:
setup instance1 = new setup();
instance1.saveChocolate(checked);
// No break; continue along
case R.id.checkLuigi:
setup instance2 = new setup();
instance2.saveLuigi(checked);
break;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Red parts of logcat:
06-02 20:49:57.245 25557-25557/? I/SDP.PUB_CRYPTOD﹕ Starting
06-02 20:49:57.245 25557-25557/? I/SDP.PUB_CRYPTOD﹕ Socket created with fd:-1
06-02 20:49:57.245 25557-25557/? E/SDP.PUB_CRYPTOD﹕ Failed to open the netlink socket with error: Protocol not supported
06-02 20:49:57.245 25557-25557/? E/SDP.PUB_CRYPTOD﹕ Exiting
06-02 20:49:59.995 2866-3012/? V/AlarmManager﹕ waitForAlarm result :8
06-02 20:50:02.280 25633-25633/? I/SDP.PUB_CRYPTOD﹕ Starting
06-02 20:50:02.280 25633-25633/? I/SDP.PUB_CRYPTOD﹕ Socket created with fd:-1
06-02 20:50:02.280 25633-25633/? E/SDP.PUB_CRYPTOD﹕ Failed to open the netlink socket with error: Protocol not supported
06-02 20:50:02.280 25633-25633/? E/SDP.PUB_CRYPTOD﹕ Exiting
Thanks for any help. I haven't seen this issue while prowling the internet so it might be excessively noob.
EDIT: Rewritten with the only onCreate in the larger MainActivity class
package gaga.sharedpreferences;
import android.content.SharedPreferences;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
public final class setup extends MainActivity {
public void setup () {
//Nothing to see here!
}
// Define the File of Prefs; created if nonexistent
public static final String PREFS_NAME = "MyPrefsFile";
// Start up
public void onCreateSubclass() {
// super.onCreate(state);
// Restore preferences on Startup
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean Chocolate = settings.getBoolean("checkChocolate", false);
boolean Luigi = settings.getBoolean("checkLuigi", false);
// Function set to Whatever
// setSilent(silent);
/* Note:
* CheckedTextView and CheckBox::isChecked()
* CheckBox::setChecked()
* */
CheckBox checkHandleChocolate = (CheckBox) findViewById(R.id.checkChocolate);
CheckBox checkHandleLuigi = (CheckBox) findViewById(R.id.checkLuigi);
// What was the preference? On Start set it to the bool it left off in
checkHandleChocolate.setChecked(Chocolate);
checkHandleLuigi.setChecked(Luigi);
// Change report text on Start
TextView buttonHandleChocolate = (TextView) findViewById(R.id.chocolate);
TextView buttonHandleLuigi = (TextView) findViewById(R.id.luigi);
if(Chocolate)
buttonHandleChocolate.setText("I do prefer Chocolate");
else
buttonHandleChocolate.setText("I do not prefer Chocolate");
if(Luigi)
buttonHandleLuigi.setText("I do prefer Luigi");
else
buttonHandleLuigi.setText("I do not prefer Luigi");
}
public void saveChocolate(Boolean c) {
// All objects from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("Chocolate", c);
// Commit the edits
editor.commit();
}
public void saveLuigi(Boolean l) {
// All objects from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("Chocolate", l);
// Commit the edits
editor.commit();
}
}
#Override
protected void onStop(){
super.onStop();
// Objects are from android.context.Context
//Normally I'd put the edit commits here, but that's not true
}
// Clicks on Done
public void userDone (View view) {
// View is which widget
boolean checked = ((CheckBox) view).isChecked();
// Which checkbox was clicked
switch(view.getId()) {
case R.id.checkChocolate:
setup instance1 = new setup();
instance1.saveChocolate(checked);
// No break; continue along
case R.id.checkLuigi:
setup instance2 = new setup();
instance2.saveLuigi(checked);
break;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setup startInstance = new setup();
startInstance.onCreateSubclass();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
In Android Studio you need create a Run Configuration in your project.
Go to this link to left run icon
And click on Edit Configuration, after in the windows configure like this:
And save it, for test click run icon.
It appears that you have two onCreate methods. Try removing the second one and running it again.

Sending Data From One Activity to Another Without Creating a new Intent Android

i have an impending question that is mind buggling me at the moment in regards to android app development.
In my app, which works exactly the way i want it to, except for one part i have problem figuring out is how will i send a piece of data from one activity to another without making a new Intent.
In my Code, the user inputs his Name, Mass, and Height, and when the user clicks on Button calculate, it takes all the values in a new intent to a second activity, there, it calculates the BMI of the user. Now, i want to send this freshly calculated BMI back to the First activity without creating a new intent but i am now sure on how to go about that
Here are the relevant part of my Code
Main Activity.java
package mobileapp.melvin.bmicalculator;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.*;
import android.content.*;
import android.widget.*;
public class MainActivity extends Activity {
public String name,mass,height,bmi;
public EditText nameField, massField, heightField;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bmi = getIntent().getStringExtra("BMI");
//Create "TextFields" By getting ID of Editviews from Main XML
nameField = (EditText) findViewById(R.id.mText_box1);
massField = (EditText) findViewById(R.id.mText_box2);
heightField = (EditText) findViewById(R.id.mText_box3);
//Button To calculate and display BMI as TextViews
Button launchBtn = (Button) findViewById(R.id.mButton_calculate);
launchBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Check is The "Textfields" have values
if(!verifyData()){
return;
}
/*Create a new Intent to Launch another activity
* To display all the Values gotten from
* The TextFields as Normal Text Values
*/
Intent launcher = new Intent(v.getContext(),BMI1.class);
//This intent then passes these values over to the next Intent
launcher.putExtra("Name", name);
launcher.putExtra("Mass", mass);
launcher.putExtra("Height", height);
//We then start this new activity with the new Intent
startActivity(launcher);
}
});
}
and BMI1.java
package mobileapp.melvin.bmicalculator;
import android.app.*;
import android.content.*;
import android.os.*;
import android.view.*;
import android.widget.*;
public class BMI1 extends Activity {
String name,mass,height,bmi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bmi1);
//Get data from the first activity through intent
name = getIntent().getStringExtra("Name");
mass = getIntent().getStringExtra("Mass");
height = getIntent().getStringExtra("Height");
//convert mass and height to double and calculate BMI
double m = Double.parseDouble(mass);
double h = Double.parseDouble(height);
bmi = Double.toString(calculateBMI(m, h));
((TextView) findViewById(R.id.b1_Label2)).setText(name);
((TextView) findViewById(R.id.b1_Label4)).setText(mass);
((TextView) findViewById(R.id.b1_Label6)).setText(height);
((TextView) findViewById(R.id.b1_Label8)).setText(bmi);
Button backBtn = (Button) findViewById(R.id.b1Button_back);
backBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent launcher = getIntent();
launcher.putExtra("BMI", bmi);
finish();
}
});
}
private double calculateBMI(double toMass, double toHeight){
double value;
value = toMass/(toHeight * toHeight);
return value;
}
}
I know there is no value passed because when a user clicks Display in the first Activity, it takes the values to a third Activity where a textView Should display For example "BMI: 20.66" but instead i get "BMI: null", how will i fix this error?
You don't have to always use Intent to send data between activities. You use other android storage options like Sqlite db, SharedPreferences. You can also store data on SDcard. Have a look at Android storage options
here
To solve the above problem properly, android provides startActivityForResult that basically launch an activity for which you would like a result when it finished.
For example, here's how to start an activity that allows the user to pick a contact:
static final int PICK_CONTACT_REQUEST = 1; // The request code
...
private void pickContact() {
Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}
Receive the Result
When the user is done with the subsequent activity and returns, the system calls your activity's onActivityResult() method. This method includes three arguments:
The request code you passed to startActivityForResult().
A result code specified by the second activity. This is either RESULT_OK if the operation was successful or RESULT_CANCELED if the user backed out or the operation failed for some reason.
An Intent that carries the result data.
For example, here's how you can handle the result for the "pick a contact" intent:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == PICK_CONTACT_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which contact was selected.
// Do something with the contact here (bigger example below)
}
}
}
You can see the complete example of startActivityForResult in this article here.
For send data between Activity without using Intent you can use SharedPreferences or SQlite db.
Example for SharedPreferences:
// Create object of SharedPreferences.
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
//now get Editor
SharedPreferences.Editor editor = sharedPref.edit();
//put your value
editor.putString("userName", "stackoverlow");
//commits your edits
editor.commit();
Using putString(),putBoolean(),putInt(),putFloat(),putLong() you can save your desired dtatype.
and to fetch data:
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");

Categories