Android - Passing more variebles via intent makes app crash - java

So, here is the code from the main activity(the main screen,) if you click on play a random activity( a quiz question) will show up. The problem is that, i am trying to pass an integer, default score to question #1, where the score will be 5(it's the default).
if the user clicks on the wrong button, it will navigate the user to Question #2, and for Question #2, the score will be minus2, less than 2.
int defaultScore = 51;
// start Play Intent
public void onPlay(View view){
Random r = new Random();
int XML_random = r.nextInt(5)+1; // 5 different Quiz XML files
Intent startQuiz = new Intent();
switch(XML_random){
case 1:
startQuiz.setClass(view.getContext(), Quiz_1.class);
break;
case 2:
startQuiz.setClass(view.getContext(), Quiz_2.class);
break;
case 3:
startQuiz.setClass(view.getContext(), Quiz_3.class);
break;
case 4:
startQuiz.setClass(view.getContext(), Quiz_4.class);
break;
case 5:
startQuiz.setClass(view.getContext(), Quiz_5.class);
break;
} // end of the Random switch
startQuiz.putExtra("passScore", defaultScore);
startActivity(startQuiz);
}
So, next if a random activity is chosen, then it's score will be 5, because for the first question, I want the users to start with 5 as a start. So, here is an activty(Question #1) and if the user clicks on the wrong button then Question #2 will show up. And for this activity, the score will be minus 2. Because the user chose the wrong answer.
Question 1 - user clicks on the wrong button:
public class Quiz_1 extends Activity {
TextView textviewScore;
int current_score = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.quiz_1);
textviewScore = (TextView) findViewById(R.id.q_result); // declaring the TextView
Bundle extras = getIntent().getExtras();
if (extras != null)
{
current_score = extras.getInt("passScore");
}
textviewScore.setText(String.valueOf(current_score));
} // end of onCreate
public void on_quiz_1_wrong(View view){ // button clicked the wrong answer
current_score = current_score - 2;
Intent quiz1 = new Intent(this, Quiz_2.class);
startActivity(quiz1);
quiz1.putExtra("passNewScore", current_score);
}
And here is Question #2, and for this activity i want the score to be minus 2.
public class Quiz_2 extends Activity {
TextView textviewScore;
int current_score = 0;
int getScore=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.quiz_2);
textviewScore = (TextView) findViewById(R.id.q_result); // declaring the TextView
Bundle extras = getIntent().getExtras();
if (extras != null)
{
current_score = extras.getInt("passScore");
getScore = extras.getInt("passNewScore");
}
current_score = current_score - getScore;
textviewScore.setText(String.valueOf(current_score));
} // end of onCreate

you must first put extra to your intent then start it.
quiz1.putExtra("passNewScore", current_score);
startActivity(quiz1);

You are not passing the value for key "passScore" in quiz1 and calling quiz2, so how can you expect to retrieve the value on "passScore" in quiz2 ?
Pass the value for key "passScore" in quiz1.java in this method on_quiz_1_wrong(View view)

Related

how to check if the random number exists in array

I'm trying to check my random number exists in my array; this is my array
int [] img = {R.drawable.im1,R.drawable.im2}
My function to update data and show it random
private void updateQuestion() {
int ranom_number = random.nextInt(img.length);
image.setImageResource(img[ranom_number]);
ton= MediaPlayer.create(BallActivity.this,Questions.audinb[ranom_number]);
ton.start();
}
this is my class. In my view I have a button I want when the random number is displaying if the user clicks right the other buttons disappear. If he clicks next then all buttons should be displayed. If the last number of array is displaying the activity finish
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn1:
if (ranom_number == img.length) {
bravo = MediaPlayer.create(getApplicationContext(), R.raw.bravo);
bravo.start();
bt2.setVisibility(v.GONE);
}else{
bt1.setVisibility(v.VISIBLE);
bt2.setVisibility(v.VISIBLE);
}
break;
case R.id.btn2:
if(ranom_number <= img.length-1){
}
break;
case R.id.suiv:
if(ranom_number <= imgnb.length-1) {
updateQuestion();
}else{
Intent i = new Intent(BallActivity.this, NewActivity.class);
BallActivity.this.finish();
startActivity(i);
}
}
But doesn't work thank you for helping

Opening another activity based on number of filled editTexts

The app has a MainActivity with 6 editText fields, and a button. There are 5 more activities, named Activity2, Activity3, etc. Now, When a user enters names in editText fields, and press a button, the app should find out how many editText fields are filled, and open the activity with a corresponding number in it's name.
Example:
If only one field is filled, a toast should appear, saying More players.
If two fields are filled, app opens Activity2.
If three fields are filled, app opens Activity3, etc.
Now, to the problem. I am missing something out, and can't find out what. Here is MainActivity.java
public class MainActivity extends AppCompatActivity {
private EditText editText1,editText2,editText3,editText4,editText5,editText6;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.btn);
editText1 = findViewById(R.id.editText1);
editText2 = findViewById(R.id.editText2);
editText3 = findViewById(R.id.editText3);
editText4 = findViewById(R.id.editText4);
editText5 = findViewById(R.id.editText5);
editText6 = findViewById(R.id.editText6);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int filledFileds = countFilledFields();
Log.d("filled", String.valueOf(filledFileds));
Class newClass = MainActivity.class;
switch (filledFileds){
case 1:
Context context = getApplicationContext();
CharSequence text = "You need more players!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
break;
case 2:
newClass = Activity2.class;
System.out.println("Activity2");
break;
case 3:
newClass = Activity3.class;
System.out.println("Activity3");
break;
case 4:
newClass = Activity4.class;
System.out.println("Activity4");
break;
case 5:
newClass = Activity5.class;
System.out.println("Activity5");
break;
case 6:
newClass = Activity6.class;
System.out.println("Activity6");
break;
default:
}
Intent intent = new Intent(MainActivity.this, newClass);
}
});
}
private int countFilledFields() {
ArrayList<EditText> editTexts = new ArrayList<>();
editTexts.add(editText1);
editTexts.add(editText2);
editTexts.add(editText3);
editTexts.add(editText4);
editTexts.add(editText5);
editTexts.add(editText6);
int filledNumber = 0;
for(int i = 0;i < editTexts.size() ;i++){
if(editTexts.get(i).getText()!=null && !editTexts.get(i).getText().toString().matches("")){
filledNumber += 1;
}
}
return filledNumber;
}
}
The log shows the exact number, something is not working...
Here is your click listener, with the switch omitted for brevity:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int filledFileds = countFilledFields();
Log.d("filled", String.valueOf(filledFileds));
Class newClass = MainActivity.class;
switch (filledFileds){
...
}
Intent intent = new Intent(MainActivity.this, newClass);
}
The problem is at the very end: you've created an Intent object ... but you're not doing anything with it. Probably you have just forgotten a startActivity() call:
Intent intent = new Intent(MainActivity.this, newClass);
startActivity(intent);
Also, looking this over, you have a problem with the case where the user only enters one EditText. As written, you'll still try to start a new activity (you'll just start a new copy of the same MainActivity, which is probably a bad idea). A better idea would be to only start the new activity if the user fills out enough EditTexts:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int filledFileds = countFilledFields();
Log.d("filled", String.valueOf(filledFileds));
Class newClass = null;
switch (filledFileds){
...
}
if (newClass != null) {
Intent intent = new Intent(MainActivity.this, newClass);
startActivity(intent);
}
}
You're missing one thing:
startActivity(intent);

How can I store ArrayList<Class> in SharedPreferences to store game progress?

I'm new to android development and I am creating an android application that works like "4 Pics 1 Word" for my project. I'm having difficulties in storing ArrayList in SharedPreferences or in the internal storage of the android phone. The reason why is because I am randomizing the next activity using random generator and ArrayList. Any suggestions or ideas that my help my case? Thank you in advance! I've been stuck here for hours now.
This is my MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
Button btnStart;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnStart = (Button) findViewById(R.id.btnStart);
btnStart.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// We are creating a list, which will store the activities that haven't been opened yet
ArrayList<Class> activityList = new ArrayList<>();
activityList.add(first.class);
activityList.add(second.class);
activityList.add(third.class);
activityList.add(fourth.class);
activityList.add(fifth.class);
Random generator = new Random();
int number = generator.nextInt(5) + 1;
Class activity = null;
// Here, we are checking to see what the output of the random was
switch(number) {
case 1:
activity = first.class;
// We are adding the number of the activity to the list
activityList.remove(first.class);
break;
case 2:
activity = second.class;
activityList.remove(second.class);
break;
case 3:
activity = third.class;
activityList.remove(third.class);
break;
case 4:
activity = fourth.class;
activityList.remove(fourth.class);
break;
default:
activity = fifth.class;
activityList.remove(fifth.class);
break;
}
// We use intents to start activities
Intent intent = new Intent(getBaseContext(), activity);
// `intent.putExtra(...)` is used to pass on extra information to the next activity
intent.putExtra("ACTIVITY_LIST", activityList);
startActivity(intent);
}
}
And here's my first activity:
public class first extends AppCompatActivity implements View.OnClickListener{
EditText etAnswer;
Button btnGo;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
etAnswer = (EditText) findViewById(R.id.etAnswer);
btnGo = (Button) findViewById(R.id.btnGo);
btnGo.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnGo:
String answer = etAnswer.getText().toString();
if(answer.equals("Jose Rizal") || answer.equals("jose rizal") || answer.equals("Rizal") || answer.equals("rizal") ){
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
dlgAlert.setMessage("The famous Rizal monument in Luneta was not the work of a Filipino but a Swiss sculptor named Richard Kissling?" +
"Source: http://www.joserizal.ph/ta01.html");
dlgAlert.setTitle("Did you know that ...");
dlgAlert.setPositiveButton("Next",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
ArrayList<Class> activityList = new ArrayList<>();
Bundle extras = getIntent().getExtras();
activityList = (ArrayList<Class>) extras.get("ACTIVITY_LIST");
if(activityList.size() == 0) {
Context context = getApplicationContext();
CharSequence last = "Congratulations! You just finished the game! Please wait for the next update!";
int durationFinal = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, last, durationFinal);
toast.show();
} else {
// Now, the random number is generated between 1 and however many
// activities we have remaining
Random generator = new Random();
int number = generator.nextInt(activityList.size()) + 1;
Class activity = null;
// Here, we are checking to see what the output of the random was
switch(number) {
case 1:
// We will open the first remaining activity of the list
activity = activityList.get(0);
// We will now remove that activity from the list
activityList.remove(0);
break;
case 2:
// We will open the second remaining activity of the list
activity = activityList.get(1);
activityList.remove(1);
break;
case 3:
// We will open the third remaining activity of the list
activity = activityList.get(2);
activityList.remove(2);
break;
case 4:
// We will open the fourth remaining activity of the list
activity = activityList.get(3);
activityList.remove(3);
break;
default:
// We will open the fifth remaining activity of the list
activity = activityList.get(4);
activityList.remove(4);
break;
}
// Note: in the above, we might not have 3 remaining activities, for example,
// but it doesn't matter because that case wouldn't be called anyway,
// as we have already decided that the number would be between 1 and the number of
// activities left.
// Starting the activity, and passing on the remaining number of activities
// to the next one that is opened
Intent intent = new Intent(getBaseContext(), activity);
intent.putExtra("ACTIVITY_LIST", activityList);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
});
dlgAlert.setCancelable(true);
dlgAlert.create().show();
}else{
Context context = getApplicationContext();
CharSequence text = "Wrong! Try Again.";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
break;
}
}
}
Okay, this is a horrible hack and I don't endorse it in any way, but since you are so close to finishing your app, I propose a workaround:
Instead of storing an ArrayList<Class> in your SharedPreferences (which is impossible), store a HashSet<String> containing the fully qualified names of your classes via putStringSet().
In order to get the String representations of the fully qualified names of your classes you need to call getName(), e.g. first.class.getName().
Then, you can get your Set<String> from SharedPreferences using getStringSet() and create a Class instance for each String in that set via Class.forName().

android java calling button from XML without getting NULL

I'm looking to call a few buttons but seem to be getting a NULL when trying to findbyviewid. When I activate this activity, it crashes.
//CREATE INSTANCE OF GLOBAL - QUESTIONS/ANSWERS
Global global = Global.getInstance();
//CURRENT QUESTION
static int QQ = 0;
//CORRECT ANSWER COUNT
static int correctAnswers = 0;
//CREATE VARIABLE FOR TEXTVIEW/QUESTION
TextView textQuestion = (TextView) findViewById(R.id.textQuestion);
//CREATE VARIABLES FOR BUTTONS/ANSWERS
Button buttonOne = (Button) findViewById(R.id.answerOne);
Button buttonTwo = (Button) findViewById(R.id.answerTwo);
Button buttonThree = (Button) findViewById(R.id.answerThree);
Button buttonFour = (Button) findViewById(R.id.answerFour);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_practice_questions);
setButtons();
buttonOne.setOnClickListener(this);
buttonTwo.setOnClickListener(this);
buttonThree.setOnClickListener(this);
buttonFour.setOnClickListener(this);
}
public void setButtons()
{
//SET QUESTION STRING TO TEXTVIEW
textQuestion.setText(global.getQ(QQ));
//SET ANSWER STRINGS TO BUTTONS' TEXT
buttonOne.setText(global.getA(QQ, 0));
buttonTwo.setText(global.getA(QQ, 1));
buttonThree.setText(global.getA(QQ, 2));
buttonFour.setText(global.getA(QQ, 3));
}
#Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.answerOne:
checkAnswer(0, buttonOne);
break;
case R.id.answerTwo:
checkAnswer(1, buttonTwo);
break;
case R.id.answerThree:
checkAnswer(2, buttonThree);
break;
case R.id.answerFour:
checkAnswer(3, buttonFour);
break;
default:
break;
}
}
public void checkAnswer(int a, Button b){
//IF AN INCORRECT ANSWER WAS CHOSEN, MAKE THE BACKGROUND RED
if(!global.getS(QQ, a))
{
b.setBackgroundColor(Color.RED);
}
else
{
//INCREMENT THE CORRECT ANSWER COUNTER
correctAnswers++;
}
//SET BACKGROUND OF CORRECT BUTTON TO GREEN
if(global.getS(QQ, 0))
{
buttonOne.setBackgroundColor(Color.GREEN);
}
else if(global.getS(QQ, 1))
{
buttonTwo.setBackgroundColor(Color.GREEN);
}
else if(global.getS(QQ, 2))
{
buttonThree.setBackgroundColor(Color.GREEN);
}
else if(global.getS(QQ, 3))
{
buttonFour.setBackgroundColor(Color.GREEN);
}
else
{
//IF NO ANSWER IS CORRECT, SET ALL TO BLUE
buttonOne.setBackgroundColor(Color.BLUE);
buttonTwo.setBackgroundColor(Color.BLUE);
buttonThree.setBackgroundColor(Color.BLUE);
buttonFour.setBackgroundColor(Color.BLUE);
}
//MOVE TO NEXT QUESTION
}
I have 4 buttons in the XML file and want to be able to set the text to them, as well as run a listener for the set of buttons (answers to a question). When one of the buttons is clicked, it should determine if it's the correct answer by pulling the status (true/false) and highlighting it red if it's incorrect. It then highlights the correct answer green.
At least, some of this is in theory and I'm trying to test it out, but I can't start the activity without crashing.
I'm not 100% sure but I think you can't do the findViewById at the instance constructions. You need to those inside onCreate() (after you called setContentView)
Just how i said in comment, you should initialize it in OnCreate method, cause you set view layout for activity here. And before you do it, all findViewById returns null.
So, here your code:
Button buttonOne;
Button buttonTwo;
Button buttonThree;
Button buttonFour;
TextView textQuestion;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_practice_questions);
buttonOne = (Button) findViewById(R.id.answerOne);
buttonTwo = (Button) findViewById(R.id.answerTwo);
buttonThree = (Button) findViewById(R.id.answerThree);
buttonFour = (Button) findViewById(R.id.answerFour);
textQuestion = (TextView) findViewById(R.id.textQuestion);
[...]
}

Android Intent makes my app crash, why?

so I tried out my app without passing the score variable, and it worked. But If I try to use it, it won't work at all.
main class:
int start = 10;
// start Play Intent
public void onPlay(View view){
Intent playIntent = new Intent(this, Quiz_1.class);
playIntent.putExtra("Score", start);
startActivity(playIntent);
}
and the Quiz_1 class:
public class Quiz_1 extends Activity {
int printScore;
TextView printPoints;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.quiz_1);
printPoints = (TextView) findViewById(R.id.q_result);
}
Intent intent = getIntent();
int score = intent.getIntExtra("Score", 0);
String printFin = String.valueOf(score);
public void q_result(View view){
printPoints.setText(printFin);
}
I am sure, I did something wrong when I tried to pass the start value to my other activity. There I wanted to change a textView's text to the previous int start value = 10;
So,
First activity:
int t start = 10;
Second. activity:
int score = start;
printScore(it's a TextView) setText = score
If you want to pass a value to another intent, you can look into the code below.
You can put key value pairs like in intents and you can retrieve these values in the activity you are calling. You can look into :-
Intent returnIntent = new Intent(getApplicationContext, SecondActivity.class);
returnIntent.putExtra("name","abc");
startActivity(returnIntent,11);
And in you other activity result method, you can do
Bundle extras = getIntent().getExtras();
if (extras != null) {
String name = bundle.getString("name");
// and get whatever data you are adding
}
You can look into this.
All Java code must be in a method. Here, the last three lines are not in any method and are therefore not executed.
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.quiz_1);
printPoints = (TextView) findViewById(R.id.q_result);
} <----- move this closing brace
Intent intent = getIntent();
int score = intent.getIntExtra("Score", 0);
String printFin = String.valueOf(score);
} <----- to here
You need to have these inside a method like onCreate
Intent intent = getIntent();
int score = intent.getIntExtra("Score", 0);
String printFin = String.valueOf(score);
However the crash may still happen so better post the stack trace
Edit:
String printFin; //declare as class member
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.quiz_1);
printPoints = (TextView) findViewById(R.id.q_result);
Intent intent = getIntent();
int score = intent.getIntExtra("Score", 0);
printFin = String.valueOf(score);
}
change all your code to
public class Quiz_1 extends Activity {
int printScore;
TextView printPoints;
int score = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.quiz_1);
Bundle extras = getIntent().getExtras();
if (extras != null)
{
score = extras.getInt("Score");
}
printPoints = (TextView) findViewById(R.id.q_result);
printPoints.setText(String.valueOf(score));
}
I have gone through this link - http://pastebin.com/BGAkdeCv
I may have found an error
Case 1 : - You are passing the defaultScore value in passScore key and retrieving it in Quiz1.Java
MainActivity.Java ->
startQuiz.putExtra("passScore", defaultScore);
Quiz_1.Java ->
current_score = extras.getInt("passScore");
Case 2 : - You are passing current_score in passNewScore and retrieving it in Quiz2.Java
Quiz_1.Java ->
quiz1.putExtra("passNewScore", current_score);
Quiz2.Java
current_score = extras.getInt("passScore");
getScore = extras.getInt("passNewScore");
Now, the error here is :-
in quiz2.java where you are extracting passScore in current_score because this key value was put in your main_activity, not your quiz1.java from where you are calling quiz2.java.,.
so to retrieve this value in quiz2.java, you have to pass it again in quiz1.java from where you are calling quiz2 intent
To correct it modify your quiz1.java :-
public void on_quiz_1_wrong(View view){ // button clicked the wrong answer
current_score = current_score - 2;
Intent quiz1 = new Intent(this, Quiz_2.class);
startActivity(quiz1);
quiz1.putExtra("passNewScore", current_score);
quiz1.putExtra("passScore", whatever value you want to pass here);
}

Categories

Resources