So I have 3 activities: MainActivity, AddEntryActivity, and CategoryActivity. I want to use startActivityForResult from Main -> AddEntry, and then AddEntry -> Category and have the data from Category passed back to AddEntry where it's used as a field in the Entry object result I'm sending back to Main. The problem is, when I call finish() in AddEntryActivity (after returning from CategoryActivity), CategoryActivity opens again. I think it may be a problem with the intents/contexts but I'm new to android dev so I can't figure out what the problem is. Any help would be appreciated!
I am currently calling startActivityForResult() from MainActivity (on button press) to get to AddEntry.
case R.id.addEntryButton:
Intent in = new Intent(this, AddEntryActivity.class);
startActivityForResult(in, 111);
break;
Then from AddEntryActivity, I call another startActivityForResult to get to CategoryActivity (on button press again).
case R.id.chooseCategory:
Intent catAct = new Intent(this, CategoryActivity.class);
startActivityForResult(catAct, 222);
break;
From CategoryActivity, the user can choose a category and it's sent back to AddEntryActivity (I've checked that this works).
In CategoryActivity:
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Intent i = getIntent();
String category = (String) getListAdapter().getItem(position);
i.putExtra("Category", category);
setResult(RESULT_OK, i);
finish();
}
In AddEntryActivity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 222 && resultCode == RESULT_OK) {
String cat = data.getStringExtra("Category");
category.setText(cat);
categoryString = cat;
}
}
Then, in AddEntryActivity, when the confirm button is pressed I want to return to MainActivity with a new Entry object containing the category field that was returned from CategoryActivity. So I have this:
case R.id.confirmEntryButton:
Entry entry = new Entry(descString, amountString, date.getText().toString(), categoryString);
Intent main = new Intent(this, MainActivity.class);
main.putExtra("newEntry", entry);
setResult(RESULT_OK, main);
finish();
The problem is, when the confirm button is pressed, the CategoryActivity screen pops up again. The weird thing is, the onActivityResult method in MainActivity (below) actually runs as when you close the CategoryActivity screen via the back button, you can see that the entry object has been added so I can't seem to figure out what's causing the category screen to pop up.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 111 && resultCode == RESULT_OK) {
Entry entry = data.getParcelableExtra("newEntry");
entries.add(entry);
entryListView.setAdapter(eAdapter);
}
}
Check your switch case statement to make sure it isn't missing a break and falling through to the next part.
Related
I am creating a notes app, and I've all but finished it. My app starts on the main activity, which shows a recylcerView displaying all of the saved notes. To create a new note, you press a button, which sends you to another activity where you write your note. You then press a button that saves the note as an instance of the Note class and sends that object instance back to the main activity where it updates the recyclerView.
My problem is, every time I press the save button for my note, it just updates the Note instance instead of creating an entirely new one. How do I get it to create a new instance of the Note class so that I can have more than one saved note?
Here is my code for the save button:
Intent intent = new Intent(AddNoteActivity.this, MainActivity.class);
String mTitle = title.getText().toString();
String mContent = content.getText().toString();
intent.putExtra("notePar", new Note(mTitle, mContent));
startActivity(intent);
Here is my code for the mainactivity:
Intent intent = getIntent();
Note sentParcNote = intent.getParcelableExtra("notePar");
if(sentParcNote != null) {
notes.add(sentParcNote);
}
You are using startActivity(intent) to navigate from AddNoteActivity to MainActivity, this method is used to start a new activity, which means, the system will create a new instance of MainActivity class and put it at the top of the activity stack. This way you will always have 0 or 1 note (when sentParcNote != null)
I would suggest to use startActivityForResult when you navigate from MainActivity to AddNoteActivity and call setResult in your AddNoteActivity
Example:
MainActivity:
Declare this static int at the top of your class (e.g: just before onCreate method)
private static final int ADD_NOTE_ACTIVITY_REQUEST_CODE = 2;
Then add this piece of code on your button action to start AddNoteActivity:
Intent addNoteIntent = new Intent(this, AddNoteActivity.class);
startActivityForResult(addNoteIntent, ADD_NOTE_ACTIVITY_REQUEST_CODE);
Then to catch the new note from AddNoteActivity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ADD_NOTE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Note sentParcNote = data.getParcelableExtra("notePar");
if(sentParcNote != null) {
notes.add(sentParcNote);
}
}
}
}
AddNoteActivity:
add this piece of code to your save button action
String mTitle = title.getText().toString();
String mContent = content.getText().toString();
Intent intent = new Intent();
intent.putExtra("notePar", new Note(mTitle, mContent));
setResult(RESULT_OK, intent);
// finish closes the current activity which means in this case it goes back to the MainActivity
finish();
I would suggest using local storage to save your notes otherwise if you restart the app you will always have 0 notes.
I am trying to get an arraylist in ScanLocate activity from an UpdateLocation activity.
I'm using startActivityForResult method to call the scan method which populates the ArrayList wifiList, I then want to send the ArrayList to the Update Location class.
I start by calling startActivityForResult in Update Location:
private void getScan(){
//Create an intent to start ScanLocate
final Intent i = new Intent(this, ScanLocate.class);
//Start scanLocate with request code
startActivityForResult(i, REQUEST_READINGS);
}
Next, in ScanLocate I created the sendData method (note: the check confirms that the ArrayList data is intact at that point):
private void sendData(){
//create a new intent as container for the result
final Intent readings = new Intent(this, UpdateLocation.class);
//check that data is in wifiList
for(String s:wifiList){
Log.v(TAG,"List Items: " + s);
}
//create bundle for string array
Bundle b = new Bundle();
b.putStringArrayList(key, wifiList);
//add readings to send to updateLoc
readings.putExtras(b);
//set code to indicate success and attach Intent
setResult(RESULT_OK, readings);
//call finish to return
finish();
}
The final part is back in UpdateLocation with the onActivityResult:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent readings){
super.onActivityResult(requestCode, resultCode, readings);
//check if request code matches the one set above
if(requestCode == REQUEST_READINGS){
//check if sendData() in ScanLocate was successful
if(resultCode == RESULT_OK){
//get the readings from the Intent
Log.v(TAG, "HERE");
result = getIntent().getExtras().getStringArrayList(ScanLocate.key);
Log.v(TAG, "HERE2");
for(String s : result) {
Log.v(TAG, "Location 5: " + s);
}
}else{
//ScanLocate was unsuccessful
}
}
}
The first "Here" is displayed however it then falls down on the next line, getStringArrayList() throws a null pointer exception.
I have looked through the documentation and at previous questions on here and I cannot see what is going wrong.
Any advice would be appreciated, thanks.
Previous questions:
startactivityforResult not working
How to pass an ArrayList to the StartActivityForResult activity
You don't need to call getIntent(), use the parameter provided by the method:
result = readings.getStringArrayListExtra(ScanLocate.key);
My MainActivity has an EditText with the hint "Weight (lb)", as well as a button that goes to the SettingsActivity. In SettingsActivity, the user is able to change the units used from US to metric. Upon exiting SettingsActivity via the built-in back button on the phone, I want the hint for the EditText to immediately change from "Weight (lb)" to "Weight (kg)".
The farthest I've gotten is using the onBackPressed() method in SettingsActivity. The button press is detected, and the code inside it is executed, but I don't want to change anything related to MainActivity's inside the SettingsActivity class.
Is there an on___() method that I should be using here that I don't know about? Any help would be appreciated.
You can use startActivityForResult for SettingsActivity and after that handle the return result as:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
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)
}
}
More detail: https://developer.android.com/training/basics/intents/result.html
You can use startActivityForResult for SettingsActivity and after that handle the return result as:
In your MainActivity:
public static int CALL_SETTINGS = 1000;
startActivityForResult(new Intent(this,SettingsActivity.class),CALL_SETTINGS);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
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)
}
}
In your Settings Activity:
on backpressed write this:
Intent returnIntent = new Intent();
returnIntent.putExtra("result",data);
setResult(Activity.RESULT_OK,returnIntent);
finish();
Easy option is to store the waitUnit in shared preference and on OnResume() of the Main activity read it from there and update the widget.
You can update the preferences in your Settings activity like below:
preferences = context.getSharedPreferences(context.getString(R.string.preference_file_key),
Context.MODE_PRIVATE);
preferences.edit().putString("unit", "kg");
And you can read this changed value in OnResume() of your Main Activity
preferences.getString("unit", "default unit")
I have 2 Activities the main activity I have called Map activity and the second that I have called Question activity when the app launch the Map activity is shown then you click the play button and the Question activity is launched with StartActivityForResult(), then when you have answered the question right the Question activity should be destroyed and created again and check the number of right answered questions and change the layout. then if you have scored 5 then Question activity should be destroyed and the Map activity will be shown but this is not happen. Here is my code
Map.class
public void OnClick_Question(View v){
Intent i = new Intent(MapActivity.this, QuestionActivity.class);
startActivityForResult(i, 1);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(SharedPrefs.TAG, "OnActivityResult Entry");
if (resultCode == RESULT_OK) {
Log.d(SharedPrefs.TAG, "MAPActivity OnActivityResult Entry resultCode");
AssignContentView(requestCode);
}
}
Question.class
public void Next() {
Intent i = new Intent(this, QuestionActivity.class);
startActivity(i);
finish();
}
public void LevelUp() {
Log.e(SharedPrefs.TAG, "LevelUp");
super.finish();
finish(); /*This don't happen*/
}
When I see LogCat shows me this message:
09-01 11:23:03.911 901-1485/? W/ActivityManager﹕ startActivity called from finishing ActivityRecord{43386100 u0 com.example.gbb/.QuestionActivity t50 f}; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: Intent { cmp=com.example.gbb/.QuestionActivity }
Why I am doing this, is because I want to change the layout of Map Activity depending in your score.
What I'm doing wrong?
I had the same problem. I solved it by adding android:launchMode="singleTask" in the Android Manifest. Hope it works for you too.
I solved this by turning off Instant Run and re-running my code.
You can try the below code:
We need to keep the request code to be in global and static variable to access in onActivityResult method
private static final int REQUEST_CODE = 111;
public void OnClick_Question(View v){
Intent i = new Intent(MapActivity.this, QuestionActivity.class);
startActivityForResult(i, REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
Log.d(SharedPrefs.TAG, "OnActivityResult Entry");
if (resultCode == RESULT_OK) {
switch (requestCode) {
case REQUEST_CODE:
Log.d(SharedPrefs.TAG, "MAPActivity OnActivityResult Entry resultCode");
AssignContentView(requestCode);
break;
default:
break;
}
}
}
I think there is no problem in your Map class, the problem is in second class.i.e., you need to set the RESULT_OK in that intent and then you can check if (resultCode == RESULT_OK) in onActivityResult method. Below you can find the code for that
Intent intent = new Intent();
setResult(activity.RESULT_OK, intent);
finish();
Hope this is helpful:)
I have an MainActivity which has two TextView. User has an option to start another activity and choose data from ListView to fill those TextView. My main activity has an OnClickListener which starts an Activty from which user can select data and come back to main activity.My OnClickListener code looks likes this:
private static final int PICK_START = 0;
private static final int PICK_END = 1;
#Override
public void onClick(View v) {
Log.i(MainActivity, "view clicked");
int id = v.getId();
if (id == R.id.searchR) {
//do nothing
} else if (id == R.id.startSearch) {
Intent startIntent = new Intent(this, SList.class);
startActivityForResult(startIntent, PICK_START);
} else if (id == R.id.endSearch) {
Intent startIntent = new Intent(this, SList.class);
startActivityForResult(startIntent, PICK_END);
}
}
When the above onClick method gets called and after that its starts another activity SList.class.In that I have a listview from which user can select the value and upon selecting value the result will be set and activity will finish itself.Code for this is:
sListview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Station selectedS = sArray.get(position);
Intent returnIntent = new Intent();
returnIntent.putExtra("_id", selectedS.getId());
returnIntent.putExtra("name", selectedS.getName());
setResult(RESULT_OK, returnIntent);
finish();
}
});
In above code activity sets the result and finishes itself.Till here everything is working accordingly.But after that when the previous activity is started, the onActivityResult() method nevers gets called.The code for onActivityResult() is :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(MainActivity, "" + requestCode);
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// Check which request we're responding to
if (requestCode == PICK_START) {
//data.getStringExtra("_id");
Log.i(MainActivity, data.getStringExtra("name"));
} else if (requestCode == PICK_END) {
Log.i(MainActivity, data.getStringExtra("name"));
}
}
}
I dont know why onActivityResult is never triggered .Someone even
wrote on his blog that There is bug in android API. In
startActivityForResult(intent, requestCode); This function does work
as long as requestCode = 0. However, if you change the request code to
anything other than zero, the ApiDemos will fail (and onActivityResult()
won't be called).
I found the solution to my problem.I just needed to restart my eclipse and my code started working.