Starting multiple activities and getting result before starting the next one - android

I am making a quiz app, my MainActivity(main menu) launches QuestionActivity using startActivityForResult, in QuestionActivity (Question text and answer buttons). After the user has answered the question, I want to send a boolean back a to MainActivity to update the score which then can be pushed into the next intent, in the Question Activity, I display the score in the Actionbar.
The problem is when I answer one question, setResult and Finish Runs but onActivityResult does not, after I answer all questions then OnActivityResult runs 10 times.
How can I get onActivityResult to run after I answer each question, not at the end?
Do I need to use intent flags?
Extra Info
In MainActivity, when the user starts the quiz:
//Called when user clicks quiz
//Creates the list of questions and then asks them.
public void makeQuiz(View view) {
//Pick the questions for the quiz
question[] quiz = new question[10]; //A quiz with 10 questions
for (int i = 0; i < quiz.length; i++) {
quiz[i] = myDBHelper.pickQuestion();
askQuestion(view, quiz[i],i,qscore);
Log.d("Asked question", Integer.toString(i));
}
}
Ask Question is used to start the QuestionActivity:
//Creates a question and then passes it though to the question view.
public boolean askQuestion(View view, question q, int questionNum, int qscore){
question q1 = q;
Log.d("Correct Ans",q.CorrectAns);
Intent question = new Intent(this, QuestionActivity.class);
Bundle extras = new Bundle();
extras.putString("QUESTION", q.QuestionText);
extras.putString("MODULE", q.Module);
extras.putString("CORRECT_ANS",q.CorrectAns);
extras.putString("ANS1", q.WAns[0]);
extras.putString("ANS2", q.WAns[1]);
extras.putString("ANS3", q.WAns[2]);
extras.putInt("qscore",qscore);
question.putExtras(extras); //Passing the question to the QuestionActivity
startActivityForResult(question,1);
return true;
}
In QuestionActivity, When the user answers the question correctly:
//Pass back that we got the correct answer
resultIntent = new Intent();
resultIntent.putExtra("ANSWER",true);
setResult(1, resultIntent);
Log.d("True", "Set result has been called");
finish();
Back in MainActivity:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode,resultCode,data);
//Check which event we are responding to
Log.d("onActivityResult", "called"); //This never runs
if(resultCode == 1){
//Do something with the intent
//if q is correct, update the score in shared prefrences,
Boolean result = data.getBooleanExtra("ANSWER",false);
Log.d("ANSWER IS ", Boolean.toString(result));
qscore += result ? 1:0; //This updated score is then pushed into the next intent so it can be displayed in the next question activity.
}
}

Alright so this is your problem you start the activity for result with:
startActivityForResult(question,questionNum);
so questionNum is your requestCode
but when you finish the QuestionActivity you finish it like this:
setResult(Activity.RESULT_OK, resultIntent);
so here your request code is the value of Activity.RESULT_OK
you need them to be equal.
Edit:
for your request in the comment look at this:
private static final int REQUEST_CODE = 123131;
private Stack<Intent> intentStack = new Stack<>();
//Called when user clicks quiz
//Creates the list of questions and then asks them.
public void makeQuiz(View view) {
//Pick the questions for the quiz
question[] quiz = new question[10]; //A quiz with 10 questions
for (int i = 0; i < quiz.length; i++) {
quiz[i] = myDBHelper.pickQuestion();
askQuestion(view, quiz[i], i, qscore);
Log.d("Asked question", Integer.toString(i));
}
startActivityForResult(intentStack.pop(), REQUEST_CODE);
}
//Creates a question and then passes it though to the question view.
public boolean askQuestion(View view, question q, int questionNum, int qscore) {
question q1 = q;
Log.d("Correct Ans", q.CorrectAns);
Intent question = new Intent(this, QuestionActivity.class);
Bundle extras = new Bundle();
extras.putString("QUESTION", q.QuestionText);
extras.putString("MODULE", q.Module);
extras.putString("CORRECT_ANS", q.CorrectAns);
extras.putString("ANS1", q.WAns[0]);
extras.putString("ANS2", q.WAns[1]);
extras.putString("ANS3", q.WAns[2]);
extras.putInt("qscore", qscore);
question.putExtras(extras); //Passing the question to the QuestionActivity
intentStack.push(question);
return true;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//Check which event we are responding to
if (resultCode == RESULT_OK) {
//Do something with the intent
//if q is correct, update the score in shared prefrences,
Boolean result = data.getBooleanExtra("ANSWER", false);
Log.d("ANSWER IS ", Boolean.toString(result));
qscore += result ? 1 : 0;
if(!intentStack.isEmpty()){
startActivityForResult(intentStack.pop(), REQUEST_CODE);
}
}
}

Related

Finish Activity not close in Android (Xamarin)

I have Two Activity one is InventoryActivity and Second is StoneDetailActivity. In my InventoryActivity have RecycleView In RecycleView Button Click I start the StoneDetailActivity using StartActivityForResult below code.
Intent stonedetailIntent = new Intent(context, typeof(StoneDetailActivity));
stonedetailIntent.PutExtra("SearchitemObject", stoneJson);
stonedetailIntent.PutExtra("position", position);
context.StartActivityForResult(stonedetailIntent, 1000);
context.OverridePendingTransition(Resource.Animation.Slide_in_right, Resource.Animation.Fade_back);
In StoneDetailActivity Button click I use this code to Finish the current Activity and go to OnBackPressed().
public override void OnBackPressed()
{
Intent intent = new Intent();
intent.PutExtra("BoolCheck", postflag);
intent.PutExtra("Position", position);
SetResult(Result.Ok, intent);
Finish();
}
and In InventoryActivity I have set this code.
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Ok)
{
bool checkflag = data.GetBooleanExtra("BoolCheck", false);
int position = data.GetIntExtra("Position", -1);
if (checkflag && position > -1)
{
searchItems.RemoveAt(position);
inventAdapter.NotifyDataSetChanged();
txt_totalStone.Text = searchItems.Count.ToString();
txt_totalCarat.Text = searchItems.Sum(c => c.Weight.Value).ToString();
txt_totalAmount.Text = searchItems.Sum(c => c.Rate.Value).ToString();
mainActivityBool = true;
badgeCounttextView.Text = BizApplication.BADGE_COUNT.ToString();
}
}
}
Button Click code :
add_to_cart_button.Click += async (sender, e) =>
{
ProgressDialog pdialog = new ProgressDialog(this);
pdialog.SetMessage("Please Wait...");
pdialog.Show();
cartItem = new CartItem();
cartItem.StoneId = searchItem.PacketId;
cartItem.UserId = BizApplication.getCredential().Id;
cartItem.Amount = searchItem.Rate.Value;
cartItem.Discount = searchItem.Discount;
postflag = await InventoryService.AddToCart(cartItem);
if (postflag)
{
OnBackPressed();
BizApplication.BADGE_COUNT += 1;
}
pdialog.Dismiss();
};
this code work fine for first Time. But Again if I do the same process, the StoneDetailActivity set open eventhough if I click finish.
UpDate :
When I full debug my code and i found that when I click on Second time OnBackPressed(). and Finish it my debug again start the OnCreate activity that's why it happening. But I am not starting Again then Why is Happening.
What happen I don't understand. Any Help be Appreciated.
As per this Post the Problem was that inside ListView or RecycleView if we are perform some task like OnclickListener then we have check is OnclickListener like below way other it will fire multiple event.
if (!button.HasOnClickListeners)
{
button.Click += this.clickHandler;
}
Then the code is working fine.
For more detail visit this :
https://forums.xamarin.com/discussion/9244/single-click-on-button-invoking-multiple-clicks
try by adding flag Intent
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP);

Correctly load data in listview from startactivityforresult

GOAL
What I am trying to do:
Click on my search button and my database is queried with the results passed in. If nothing is found, we are taken to an activity which says so, but if results are found they are loaded into a list.
What I have done
When I click on the search button I call startActivityForResult then this intent calls an activity (whose layout consist of a list_view). The search button also pass along my parameters and query my database.
if there are no results then an activity saying "No Records" is displayed"
and if there are records the else condition is true and the records are loaded in the list
PROBLEM
The problem I am experiencing is, when the list is loaded, if I want to go back to my search form, I must press the back button a total of three times. I am not entirely sure but I believe this strange behavior is stemming from me not returning a result to the started activity when the else clause is invoked.
I have placed what I think is the important part of my code below, would appreciate any assistance
Main Activity
private void startStudentQuery() {
Intent intent = new Intent(getBaseContext(), retrieveStudentData.class);
intent.putExtra("firstname", firstname);
intent.putExtra("lastname", lastname);
//startActivity(intent);
startActivityForResult(intent, 2);// Activity is started with requestCode 2
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2) {
Intent X = new Intent();
X.setClass(getBaseContext(),NotFound.class);
startActivity(X);
}
}
retrieveStudent Activity
//this activity is a listview
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_student)
}
//Left out some code, just showing the main parts
public class StudentAsynTask extends AsyncTask<String, Void, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
try {
//return result to show Activity if no records are found
if (jsonArray.length() == 0) {
Intent intent=new Intent();
setResult(2,intent);
finish();
} else {//Show list if records are found
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jRealObject = jsonArray.getJSONObject(i);
Student student = new Student ();
student.setFirstname(jRealObject.getString("f_name"));
student.setLastname(jRealObject.getString("l_name"));
student.setImage(jRealObject.getString("image"));
studentList.add(student);
}
}
In startStudentQuery, you should call startActivityForResult only, but now you have called retrieveStudentData twice.

Error: Activity result fragment index out of range: 0x2fffe

When im trying to delete a show with an AsyncTask. I want to call finish() after the AsyncTask has been completed and return an Intent with the result.
from the activity:
new DeleteShowTask().execute();
Intent intent = new Intent(SeasonActivity.this, FragmentShows.class); // I'm not sure if this works
intent.putExtra("tvdbid", tvdbId);
setResult(DELETECODE, intent);
finish();
then in the fragment i have this:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("RESULTCODE", resultCode + "");
Log.d("REQUEST CODE", requestCode +"");
if (resultCode == SeasonActivity.DELETECODE)
{
if (requestCode == SeasonActivity.SHOW)
{
String tvdbid = data.getStringExtra("tvdbid");
for (int i = 0; i < adapter.getCount(); i++) {
SickbeardSerie serie = adapter.getItem(i);
if (serie.getTvdbId().equals(tvdbid))
{
adapter.remove(serie);
adapter.notifyDataSetChanged();
}
}
}
}
}
But it seems like it doenst run through this onAcitivityResult().
I have logged the onActivityResult() as you see but i dont get any logs.
Only thing i get is: 10-19 16:21:44.631: W/FragmentActivity(27672): Activity result fragment index out of range: 0x2fffe
I fixed it for now by using a work around.
I now reload my AsyncTask in the onResume() instead of just removing an item from the arraylist and calling adapter.notifyDataSetChanged(). But its not the best solution.
if you using a Fragment in a another Fragment. You should be call
getParentFragment().startActivityForResult(i, SELECT_PICTURE);

Android: Unable to restart an ListActivity

First post, so please go easy.
I have an app with a handful of tabs, the first is opened on running the app.
One of the tabs is 'My Account' (a ListActivity) showing account options. I switch to this and if the user is not logged in, it, in turn, runs a UserLogon activity using the following:
Intent logonActivity = new Intent(getBaseContext(), UserLogon.class);
startActivityForResult(logonActivity, 0);
To catch the result, I use the following code:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 0){
MainBlock ta = (MainBlock) this.getParent();
TabHost th = ta.getMyTabHost();
th.setCurrentTab(0);
finish();
}
if (requestCode == 100)
{
showAccountOptions();
}
}
In the UserLogon class, I have the usual fare; TextView's and Button's. The intention is that if the user cancels the login, it will revert to the initial tab, or if login is successful, it will show the Account Options. And this is indeed what does happen.
All good so far.
The problem I'm having is that if I cancel the login and return to the first tab, when I select the Accounts tab again, I'm not presented with the UserLogon activity. I was under the impression that finish() would close the UserLogon activity, and the Accounts activity but it would appear not.
So, my question is simply, how do I, in effect, restart the Accounts activity so that the user would be presented with the option to login once more.
We're good people and all willing to help ;-) I'll give it a shot. Still, I'm not quite sure I get that all right.
Basically you have an TabActivity which you setup and where you do something like that:
myTabHost.setOnTabChangedListener(new OnTabChangeListener(){
#Override
public void onTabChanged(String tabId) {
if (tabId.equals("account") && !loggedIn) {
Intent logonActivity = new Intent(getBaseContext(), UserLogon.class);
startActivityForResult(logonActivity, 0);
}
}});
You're basically saying that the first Activity start of UserLogon works, but the second one doesn't, right? Did you debugged to that point to check whether you reach the code which starts the activity again?
Update based on comment
Your UserLogon should always provide a result information, here's a blueprint:
public class UserLogon extends Activity {
public void onCreate(Bundle bundle) {
// ... do something ...
// if activity is canceled this will be the "last" result
setResult(RESULT_CANCELED);
}
public void checkLoginOrSomethingLikeThat() {
Intent result = new Intent();
// put your results in this intent
setResult(RESULT_OK, intent);
// close activity since we have the information we need
finish();
}
}
The parent activity which is waiting for the result should do it like that:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// it's good practice to use a constant for 0 like LOGIN_REQUEST
// otherwise you will ask yourself later "What the hell did 0 stand for?"
if(requestCode == 0){
if (resultCode == RESULT_OK) {
// get needed data from data intent and react on that
} else {
// no success, react on that
}
}
// ... I don't know what your resultCode 100 is but handle itwith the same pattern
}

[Android]How to get results from intent launched from preference screen?

I need help in geting results back from intent launched from
preference screen
// Intent preference
DevicePref =
getPreferenceManager().createPreferenceScreen(this);
// Show a Screen with list of Devices Discovered
Intent i = new Intent(this,getDevice.class);
DevicePref.setIntent(i);
DevicePref.setTitle("Select Device");
DevicePref.setSummary(mSelectedDevice);
deviceOptionsCat.addPreference(DevicePref);
I want user to select device... In preference screeen I show "Select
Device" .. when user clicks that, another screen is launched by intent
where all devices are listed. User selects the device.
Now how do I know user selected which device? And I want to update
that in the summary.
Pls. let me know
Thanks
I got the answer, Hope it will help someone like me...
Do not mention intent while creating preference like I did in above code.. Mention intent on OnPreferenceClickListener and then do StartActivityForResult()
// Intent preference
DevicePref = getPreferenceManager().createPreferenceScreen(this);
// Show a Screen with list of Devices Discovered
DevicePref.setOnPreferenceClickListener(onPreferenceClick);
DevicePref.setTitle("Select Device");
DevicePref.setSummary(mSelectedDevice);
deviceOptionsCat.addPreference(DevicePref);
Then create OnPreferenceClickListner and here do StartActivityFromResult()
OnPreferenceClickListener onPreferenceClick = new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
if (preference ==DevicePref )
{
Intent i = new Intent(DevuiceOptions.this,getDevice.class);
DevicePref.setIntent(i);
startActivityForResult(i,CHOOSE_DEVICE);
}
return true;
}
};
Finally to get the result handle onActivityResult and update Summary field.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch (requestCode) {
case Constants.CHOOSE_DEVICE:
{
if (data!=null )
{
Bundle b = data.getExtras();
mSelectedDevice = (String) b.get("Name");
UpdatePreferences();
}
}
}
}
Thanks

Categories

Resources