Pass variable value to class (NOT intent) from home activity - java

I need to update a variable (via setter, I think) in a class that is not the intent class of a button. I need to set c to a given value in Creator from the Home activity. The chosen activity will then use Item Creator.
Home Activity:
int c;
public void setC(int c) {
this.c = c;
}
public void one(View view) {
setC(1);
Intent intent = new Intent(this, One.class);
startActivity(intent);
}
public void two(View view) {
setC(2);
Intent intent = new Intent(this, Two.class);
startActivity(intent);
}
public void three(View view) {
setC(3);
Intent intent = new Intent(this, Three.class);
startActivity(intent);
}
public void four(View view) {
setC(4);
Intent intent = new Intent(this, Four.class);
startActivity(intent);
}
public int getC() {
return c;
}
}
Class I am trying to pass c to:
public class Creator{
HomeActivity home = new HomeScreenActivity();
private int c = home.getC();
If I manually change c's value...
int c = 3;
... the class I want to receive it gets it fine. The issue seems to be getting the buttons to setC().
Thank you for any advice!

As far as your original question, I'd suggest using intents:
What's the best way to share data between activities?
cricket_007 is correct: use startActivity(), not "new HomeScreenActivity()":
https://developer.android.com/training/basics/firstapp/starting-activity.html

Related

Getting Intent values from a class and set Intent to another class

Good day everyone, can somebody help me on how will I make this process? I'm just trying to test this on one button. Suppose that:
After click the btnEasy1, it will go to the ButtonFunctions class and set the necessary setting for the GameActivity class.
PS. I am try this for now on one button(btnEasy1) only for now
PPS. The error says that I am trying to invoke virtual method on a null object reference.
ImageButton btnEasy1, btnEasy2, btnEasy3, btnEasy4, btnEasy5, btnEasy6, btnEasy7, btnEasy8, btnEasy9, btnEasy10, btnBack;
int row = 0 , column = 0 , stage = 0;
ButtonFunctions btnFunc;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_level__easy);
this.btnEasy1 = findViewById(R.id.btnEasy1);
this.btnEasy2 = findViewById(R.id.btnEasy2);
this.btnEasy3 = findViewById(R.id.btnEasy3);
this.btnEasy4 = findViewById(R.id.btnEasy4);
this.btnEasy5 = findViewById(R.id.btnEasy5);
this.btnEasy6 = findViewById(R.id.btnEasy6);
this.btnEasy7 = findViewById(R.id.btnEasy7);
this.btnEasy8 = findViewById(R.id.btnEasy8);
this.btnEasy9 = findViewById(R.id.btnEasy9);
this.btnEasy10 = findViewById(R.id.btnEasy10);
this.btnBack = findViewById(R.id.btnBack);
//Easy Level intents
Intent easyLevelIntent = new Intent(getApplicationContext(), GameActivity.class);
btnBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), Level_Selection.class);
startActivity(intent);
finish();
}
});
btnEasy1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
btnFunc =new ButtonFunctions();
btnFunc.functions("easy1");
finish();
}
});
public class ButtonFunctions extends AppCompatActivity {
int row, column, stage;
public void functions(String diffStage){
Intent easyLevelIntent = new Intent(getApplicationContext(), GameActivity.class);
if(diffStage.equals("easy1")){
stage = 1 ;row = 2; column = 2 ;
setRowCol(easyLevelIntent);
startActivity(easyLevelIntent);
}
}
private void setRowCol(Intent easyLevelIntent) {
easyLevelIntent.putExtra("easyStageCount", stage);
easyLevelIntent.putExtra("rowCount", row);
easyLevelIntent.putExtra("colCount", column);
easyLevelIntent.putExtra("difficulty", 1);
}
Process: com.flip, PID: 10543
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:106)
at com.flip.Functions.ButtonFunctions.functions(ButtonFunctions.java:14)
at com.flip.StageSelection.Level_Easy$2.onClick(Level_Easy.java:54)
at android.view.View.performClick(View.java:5680)
at android.view.View$PerformClick.run(View.java:22650)
at android.os.Handler.handleCallback(Handler.java:836)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6364)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1076)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:937)
You have declared ButtonFunctions as extending AppCompatActivity. But this class is not an Activity, it is just a utility class. You are getting this NullPointerException because you have created an Activity using the new keyword. This is not allowed. Only the Android framework can correctly create new instances of Android components (Activity, Service, Provider).
You should remove the extends AppCompatActivity from the ButtonFunctions class declaration and add a Context parameter to any of the methods that need one. For example, this one:
public void functions(Context context, String diffStage){
Intent easyLevelIntent = new Intent(context, GameActivity.class);
if(diffStage.equals("easy1")){
stage = 1 ;row = 2; column = 2 ;
setRowCol(easyLevelIntent);
context.startActivity(easyLevelIntent);
}
}
Another approach would be to move all the methods from ButtonFunctions into your Activity, since they seem to be very dependent on it. But this is an architectural choice that you need to make.

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)
.....
}
}
}

Trouble understanding how intents work

I'm a noobie making a quiz in Android Studio and i'm trying to pass an integer between activities to add to the amount of questions they got correct for the end but in the second activity it isn't changing when I answer the first question correct.
Question1 activity:
public class Question1 extends AppCompatActivity {
public int correctAnswers = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question1);
Intent intent = new Intent(Question1.this, Question2.class);
Intent i = getIntent();
Intent answersCorrect = new Intent(Question1.this, Question2.class);
answersCorrect.putExtra("correctAnswers", correctAnswers);
}
public void submitQuestion1(View view) {
EditText question1TextInput = (EditText) findViewById(R.id.question1TextInput);
if (question1TextInput.getText().toString().length() >= 1) {
startActivity(new Intent(Question1.this, Question2.class));
if (question1TextInput.getText().toString().toUpperCase().contentEquals("FATHER")) {
correctAnswers += 1;
Intent answersCorrect = new Intent(Question1.this, Question2.class);
answersCorrect.putExtra("correctAnswers", correctAnswers);
}
}
}
}
Question2 Activity:
public class Question2 extends AppCompatActivity {
public int correctAnswers;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question2);
Intent intent = getIntent();
int number = intent.getIntExtra("correctAnswers", 0);
TextView myAwesomeTextView = (TextView)findViewById(R.id.text);
myAwesomeTextView.setText(String.valueOf(number));
}
}
you duplicate your intent here:
Intent intent = new Intent(Question1.this, Question2.class);
Intent i = getIntent();
Intent answersCorrect = new Intent(Question1.this, Question2.class);
answersCorrect.putExtra("correctAnswers", correctAnswers);
replace it to:
Intent intent = new Intent(Question1.this, Question2.class);
intent.putExtra("correctAnswers", correctAnswers);
startActivity(intent);
in your second Activity:
int correctAnswers;
correctAnswers = (int) getIntent().getIntExtra("correctAnswers", 0);
So basically, when you have one activity and want to open a second activity, an Intent is the most important thing to have. It's responsible for communcation between your system and your application.
Intent is responsible for starting an activity, starting a service, and delivering a broadcast.
Note that there are two different types of intent: Explicit and Implicit.
Explicit Intent is used in this manner:
You have Activity_1 and you KNOW that you want to start Acticity_2 FROM Activity_1.
Implicit Intent is used when you DON'T know the name of the activity that you want to start.
Now, I know you probably understand what the StartActivity() method DOES, but StartActivity always requires an intent to go into the parenthesis. StartActivity(Activity_2); will not work.
So, when using Explicit Intent:
Intent i = new Intent(Activity_1.this, Activity_2.class);
StartActivity(i);
You start with making a reference - i - and, inside the parameters, the first being the activity from which you are calling the second activity, and the second being the activity which you want to call.
Here's a video on Intents as well: https://youtu.be/FH1Ym1KjJNc
Hope this helped.
Move the intent to a field. You only need it once.
Then, the issue is that you start the other activity too soon, without setting any value. You started the other activity with an empty, new Intent
public class Question1 extends AppCompatActivity {
public int correctAnswers = 0;
final Intent answersIntent = new Intent(Question1.this, Question2.class);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question1);
}
public void submitQuestion1(View view) {
EditText question1TextInput = (EditText) findViewById(R.id.question1TextInput);
String answer = question1TextInput.getText().toString();
// No need to check for length if directly checking another string
if (answer.toUpperCase().contentEquals("FATHER")) {
answersIntent.putExtra("correctAnswers", ++correctAnswers);
startActivity(answersIntent);
}
}
If you plan on sharing that value over many questions, try SharedPreferences.
FWIW, make a generic View for any question that has the question text and possible answer fields. Try not to make one activity per question.

Android - Navigate to previous screen

I have a problem as explained here. I have a Class A, ClassB. Both have Intents to navigate to Class C. Now, I want to know from Which class i have navigated to Class C so that i will navigate to previous screen either A or B. Calling finish() in Class C doesnt help me because i need to update the data in Class A and Class B differently. Can anybody please help me. How to use Intent here? Can i know from which class i have to navigated to Class C?
you should use startActivityForResult and override the onActivityResult callback. This way you can safetly update your data without know from wich activity you came from.
public class A extends Activity {
private final static int REQUEST_CODE= 1000;
public void onCreate(BUndle b) {
...
Intent intent = new Intent(this, C.class);
startActivityForResult(intent, REQUEST_CODE);
}
#override
void onActivityResult(int requestCode, int resultCode, Intent data) {
// here through data you will receive new data
}
}
public class C extends Activity {
public void onCreate(BUndle b) {
// modify same data
Intent intent = new Intent();
// pute data inside intent
setResult(Activity.RESULT_OK, intent);
finish();
}
}
in your intents in class A and B, put a parameter like a boolean "isclassA" and make tests on it to know.
in intent of classe A :
intent.putExtra("isfromclassA",true);
in intent of class B :
intent.putExtra("isfromclassA",false);
therefor in your class C :
boolean isfromclassA = intent.getBoolExtra("isfromclassA");

How to use String array in another activity

I have 2 activities. Each extends Activity. I tried all ways I found here, but none of them was working.
I need to send String array from one to other activity, but stay in first activity.
I try this:
Intent intent = new Intent(ActivityFrom.this, ActivityTo.class);
intent.putExtra("string-array", ARRAY);
ActivityFrom.this.startActivity(intent);
And to recive:
Intent intent = getIntent();
String[] array = intent.getExtras().getStringArray("string-array");
Any idea?
Bundle b=new Bundle();
b.putStringArray("key", strarray);
Intent intent=new Intent(this, nextActivity.class);
intent.putExtras(b);
startActivity(intent);
I would suggest a Singleton class, this will also make your String array available throughout your application, if you so desire to use it later on. Something like this should get you started:
public class StringArrayHolder {
private static StringArrayHolder instance;
private String[] mArray;
public static StringArrayHolder getInstance() {
if (instance == null) {
instance = new StringArrayHolder();
}
return instance;
}
private StringArrayHolder() {
}
public void setStringArray(String[] value) {
mArray = value;
}
public String[] getStringArray() {
return mArray;
}
}
You could also use the putStringArrayListExtra() method.
Hope this helps.
You could use public Intent putExtra (String name, Bundle value) where your Bundle object contains the String[] array using putStringArray(String key, String[] value).
This should do the trick for you
ActivityFrom.java:
...
// Start ActivityTo
Intent intent = new Intent(this, ActivityTo.class);
intent.getExtras().putStringArray("string-array", ARRAY);
startActivity(intent);
...
ActivityTo.java:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] strings = getIntent().getStringArrayExtra("string-array");
...
}

Categories