I have my main Activity with a fragment, which has a Recyclerview retrieving all the data populated from the database. In this fragment I got a button which calls another activity to insert an object into the database.
The problem is when the Activity ends and returns to the Main Activity the Recyclerview doesn't show the new item I just created. I tried with this piece of code:
#Override
public void onResume() {
super.onResume();
adapterItem.addItem(MyApplication.getWritableDatabase().getAllItems());
listProjectsView.scrollToPosition(0);
}
The function getAllItems retrieve all the data from sqlite.
On my adapterItem from my Recyclerview I got this:
public void addItem(ArrayList<Item> listItems) {
this.listItems = listItems;
notifyItemInserted(0);
}
It works "fine". The main problem is when I switch to another application in progress in my mobile and I return to my developed app the onResume method switches on and show again my last insert, populating twice this item (and so on if I do it again).
Thanks
Pass the new item back to MainActivity, then deal with it yourself.
1.In MainActivity, use startActivityForResult to start the second Activity, like this:
startActivityForResult(new Intent(this, SecondActivity.class), REQUEST_CODE);
REQUEST_CODE is an int.
2.In second Activity, override finish like this:
#Override
public void finish() {
Intent returnIntent = new Intent();
returnIntent.putExtra("passed_item", itemYouJustCreated);
// setResult(RESULT_OK);
setResult(RESULT_OK, returnIntent); //By not passing the intent in the result, the calling activity will get null data.
super.finish();
}
3.In MainActivity, override onActivityResult like this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
YourItem passedItem = data.getExtras().get("passed_item");
// deal with the item yourself
}
}
You can create static recyclerview (let say mRecyclerview) in the activity(let say firstActivity) which displays your recyclerview .
And when you add new item to your list in the other activity(let say secondActivity), you can just use
firstActivity.mRecyclerview.getAdapter().notifyDataSetChanged();
I use this way for a while and didn't encounter any performance drawback but test it with your own code for sure.
If it may help someone...
I had the same:
"I have my MainActivity with a fragment, which has a RecyclerView retrieving all the data populated from the database. In this fragment, I got a button that calls another activity(insertA) to insert an object into the database.
The problem was when the activity(insertA) ends and returns to the Main Activity the RecyclerView doesn't show the new item I just created."
So I used this in Fragment button which calls another activity(insertA) I just called
btn_addNew.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent myIntent = new Intent(context, insertA.class);
startActivity(myIntent);
}
});
WITHOUT FINISHING with finish(); !!!!!!!!!!!!
In insertA Activity in the method AddNewThingToTheDataBase() insted of finish(); or startActivity(Intent); just put onBackPressed();
public void AddNewThingToTheDataBase(){
*****Inserting in DB code;
onBackPressed();
}
And in Main Activity add this code
#Override
public void onResume() {
super.onResume();
*YourUpdateRecyleViewFunction();*
}
Try Like this,
Intent intent = new Intent(Context, YourClass);
startActivityForResult(intent, ADD_ITEM);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == ADD_ITEM){
adapterItem.addItem(MyApplication.getWritableDatabase().getAllItems());
listProjectsView.scrollToPosition(0);
}
}
}
hope it will work for you
You can make the recyclerView static and initialize it in onCreate method
public class MainActivity extends AppCompatActivity {
protected static RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.notes_recycler_view);
displayDataOnRecyclerView(this);
}
Then create a method in MainActivity to display the data in the recyclerView
public static void displayDataOnRecyclerView(Context context) {
//using a Linear Layout Manager
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
//data that will be displayed in the adapter from sqlite database
DatabaseHandler databaseHandler = new DatabaseHandler(context);
List<Model> data = databaseHandler.getAllData();
//specifying the adapter
RecyclerView.Adapter adapter = new RecyclerViewAdapter(data,context);
recyclerView.setAdapter(adapter);
}
Finally, call the displayDataOnRecyclerView method in the other Activity
MainActivity.displayDataOnRecyclerView(otherActivity.this);
Related
How flow goes?
Activity 1 -----> Activity 2 (containing/inside) ------> Fragment
WhatI want to achieve?
Fragment (sends some data back to Activity 2) ----> Activity 2 (onBackPressed : collects that data & send it back to Activity 1) ---> Activity 1
How should I achieve above. I really don't want to use any variables/constants to cache the fragment data. Need to know any in-built method to handle this?
Moreover,
Activity 2 loads Fragment inside it.
In onBackPressed, I'm using setResult in Activity 2 to do standard data passing using startActivityForResult from Activity 1.
Also, if I write any method inside Fragment & call from Activity 2 using then due to that to/fro process a WHITE screen appears. So, really don't want to write own method & need to manage it while leaving the Fragment.
You should start Activity2 with startActivityForResult as below;
Intent i = new Intent(this, Activity2.class);
startActivityForResult(i, requestCode);
And in Activity2/fragment, you should finish acitivity as below;
Intent returnIntent = new Intent();
returnIntent.putExtra("result",result);
getActivity().setResult(Activity.RESULT_OK,returnIntent);
getActivity().finish()
And get result in Activity1 as below;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (this.requestCode == requestCode) {
if(resultCode == Activity.RESULT_OK){
//Get result
}
}
}
Hope it helps.
To pass data from Activity 2 to Activity 1 you can use startActivityForResult() in Activity 1 to start Activity 2, and onActivityResult() in Activity 1 to receive that data.
To pass data from Fragment to Activity 2, I'd suggest to use some interface like
interface OnSomeDataListener {
void onSomeData(SomeData data);
}
Then implement a setter method for this interface to a fragment like
public void setOnSomeDataListener(OnSomeDataListener listener) {
this.listener = listener;
}
And then in Activity, when instantiating a Fragment:
YourFragment fragment = new YourFragment();
fragment.setOnSomeDataListener(new OnSomeDataListener() {
void onSomeData(SomeData data) {
//return the result
Intent intent = new Intent();
intent.putExtra("data", data);
setResult(RESULT_OK, intent);
finish();
}
}
And finally, in the fragment, when you want to return some data to Activity:
if(listener != null) {
listener.onSomeData(dataToReturn);
}
From your FirstActivity call the SecondActivity using startActivityForResult() method
Intent i = new Intent(this, SecondActivity.class);
startActivityForResult(i, 1);
In your SecondActivity set the data which you want to return back to FirstActivity onBackPressed of SecondActivity.
#Override
public void onBackPressed() {
super.onBackPressed();
Intent returnIntent = new Intent();
returnIntent.putExtra("result",result);
returnIntent.putExtra("bool",true);
setResult(Activity.RESULT_OK,returnIntent);
finish();
}
Now in your FirstActivity class write following code for the onActivityResult() method.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == Activity.RESULT_OK){
String result=data.getStringExtra("result");
boolean bool = data.getBooleanExtra("bool");
}
if (resultCode == Activity.RESULT_CANCELED) {
//Write your code if there's no result
}
}
}//
To send data from Fragment to Second activity, you can use interface callback
public interface sendDataListener
{
void sendData(boolean foo);
}
Implement this listener to Second activity
Try to do this:
public class MyFragment extends Fragment{
private MyFragmentCommunicator myFragmentCommunicator;
....
myFragmentCommunicator.sendDataToActivity(name, image, isSend);
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
myFragmentCommunicator = (MyFragmentCommunicator)activity;
}
}
then declare your interface:
public interface MyFragmentCommunicator{
void sendDataToActivity(String name, String image, boolean isSend);
}
and then in your Activity do this:
public class MyActivity extends AppCompatActivity implements MyFragmentCommunicator{
#Override
public void sendDataToActivity(String name, String image, String price) {
//Manipulate the data
}
}
Hope it helps!!!
i acheived in Following way
In Activity write setters and getters
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
and in Fragment
filePath = ((YourActivity) getActivity()).getFilePath();
fileName=((YourActivity) getActivity()).getFileName();
if You are Using Same Fragment in More Than 1 Activity You can Create a constructor for that fragment and Pass context and check context is of which activity
public class BookmarkFragment extends Fragment {
private String filePath;
private String fileName;
Context contextCheckClass;
public BookmarkFragment(Context ctx ) {
this.contextCheckClass=ctx;
}
#SuppressLint("InflateParams")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
group= (View)inflater.inflate(R.layout.fragment_bookmark, null);
if(contextCheckClass instanceof FirstReaderScreen){
filePath = ((FirstReaderScreen) getActivity()).getFilePath();
fileName=((FirstReaderScreen) getActivity()).getFileName();
// ispurchased=((FirstReaderScreen) getActivity()).isIspurchased();
}
else if(contextCheckClass instanceof MainReaderScreen){
filePath = ((MainReaderScreen) getActivity()).getFilePath();
fileName=((MainReaderScreen) getActivity()).getFileName();
// ispurchased=((MainReaderScreen) getActivity()).isIspurchased();
}
return group;
}
for calling fragment
BookmarkFragment bookmarkFragment=new BookmarkFragment(FirstReaderScreen.this);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.LL_Fragment, bookmarkFragment)//LL_fragment is container
.addToBackStack(null)
.commit();
I have a fragment that throws an activity in which user can insert some details.
When the user terminate to fill data the activity close. Then the previous fragment is showed and I want it to be updated (with the data provided by user in the activity).
If it was an activity, instead of fragment, i could use this:
#Override
public void onResume(){
super.onResume();
recreate();
}
How to do the same with fragment?
You would override onResume in the Activity which this Fragment belong, and recreate (restarted) this Fragment in this Activity. For example
public class ActivityA extends Activity {
#Override
public void onResume() {
// here you can get the Fragment instance , so you can recreated this fragment here or invoke this fragment's function to set data or refresh data
}
}
You can throw an Activity in calling startActivityForResult (Intent intent, int requestCode) method in your fragment.
also you need to provide onActivityResult (int requestCode, int resultCode, Intent data) in your fragment,the data is in the Intent parameter.
public class YourFragment extends Fragment {
public void throwActivity() {
// start activity
Intent intent = new Intent();
intent.setClass(getActivity(), YourActivity.class);
int requestCode = 1;
startActivityForResult(intent,requestCode);
}
// callback
#Override
public void onActivityResult (int requestCode, int resultCode, Intent data) {
recreate();
}
public void recreate() {
// your refresh code
}
}
public class YourActivity extends Activity {
public void yourMethod() {
int resultCode = 2;
setResult(resultCode); // goback to your fragment with your data
}
}
i'm learning how to change Single item with resultActivity in in my custom Adapter listview. how it's can work ?
this my code when startActivityForResult in custom adapter listview
holder.isi_layout.setOnClickListener(new android.view.View.OnClickListener(){
public void onClick(View v)
{
Intent i = null;
i = new Intent(activity, DetailLaporanActivity.class);
Bundle b = new Bundle();
b.putString("position", Integer.toString(position));
i.putExtras(b);
activity.startActivityForResult(i, mRequestCode);
activity.overridePendingTransition (R.anim.push_left_in, R.anim.push_left_out);
}
});
and this OnResultActivity
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode==mRequestCode) {
if(resultCode == RESULT_OK){
String position = data.getStringExtra("position");
String status_favorite = data.getStringExtra("status_favorite");
String jumlah_favorite = data.getStringExtra("jumlah_favorite");
String jumlah_komentar = data.getStringExtra("jumlah_komentar");
}
Toast.makeText(getApplicationContext(), "This code Success get Result", Toast.LENGTH_LONG).show();
}
}
When i put OnResultActivity in Adapter, code is error, RESULT_OK get notice Cannot be resolved to a variable,
but if i put in MainActivity , this not error but not get value result, i check with Toast.makeText(getApplicationContext(), "This code Success get Result", Toast.LENGTH_LONG).show(); but no toast,....
anybody help me ? how it's work ?
sorry, for my english...
You added unresolved RESULT_OK so you should set it in DetailLaporanActivity.class like that.
public class DetailLaporanActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setResult(RESULT_OK);
}
}
and than you can use RESULT_OK in your onActivityResult method.
That's because RESULT_OK is a constant of the Activity class. So, you need to qualify it in your Adapter class as so:
Activity.RESULT_OK
I use a TabActivity with some tabs,each tab contain a ActvityGroup,each ActivityGroup manage more than one Activity.one of ActivtyGroups have three Activies:A,B and C.
At first A is created,when user click a button in A,it jump to B.
in B there are some important data which can be edited in C,when click a "edit"button in B,it jump to C.
if some data is edited in C,when i click back button,i want modify the same data in B.
what drive me crazy is when i use "finish()" in class C,my app exit directly.
I had searched many solutions on the net,bu none of them fit for my case,I don't know where is wrong,please help me or give me a example of how to use startActivityForResult() in ActivityGroup
here is my group:
public class MyGroup extends ActivityGroup
{
private int ID=0;
private AlertDialog dialog;
private Stack<View>history;
private LocalActivityManager manager;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
history = new Stack<View>();
manager = getLocalActivityManager();
Intent intent = new Intent(this,A.class);
startActivity(intent);
}
#Override
public void startActivity(Intent intent)
{
View view = manager.startActivity(""+ID++,intent).getDecorView();
history.push(view);
setContentView(view);
}
#Override
public void startActivityForResult(Intent intent,int requestCode)
{
// super.startActivityForResult(intent, requestCode);
View view = manager.startActivity(""+ID++,intent).getDecorView();
history.push(view);
setContentView(view);
}
/*
* if user edited data in C.class.
* when C.class finished,refresh data in the B.class
*/
#Override
protected void onActivityResult(int requestCode,int resultCode,Intent data)
{
Log.e("MyGroup","running");
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==RESULT_OK)
{
//modify data in B.java
B subActivity=(B)(manager.getCurrentActivity());
subActivity.handleActivityResult(requestCode, resultCode, data);
}
}
/*
* when press back button, manage which page to show next
* if there is one page in stack,that means when press back button it will
* exit the app,so we add a dialog to notify user whether exit app or not
*/
#Override
public void onBackPressed()
{
int size=history.size();
if ( history.size()>= 2)
{
history.remove(size-1);
setContentView(history.get(size-2));
}
else
{
if(dialog==null)
{
createDialog();
}
dialog.show();
}
}
}
in B.class:
public void nextPage()
{
Intent intent=new Intent(B.this,C.class);
intent.putExtra("name", productAdapter.getName(position));
intent.putExtra("id", productAdapter.getID(position));
B.this.getParent().startActivityForResult(intent,11);
}
/*
* modify data in modifyItem
*/
public void handleActivityResult(int requestCode,int resultCode,Intent data)
{
String price=data.getExtras().getString("price");
String name=data.getExtras().getString("name");
String quantity=data.getExtras().getString("quantity");
productAdapter.setName(name, modifyItem);
productAdapter.setPrice(price, modifyItem);
productAdapter.setQuantity(quantity, modifyItem);
productAdapter.notifyDataSetChanged();
}
in C.class:
#Override
public void onBackPressed()
{
if(price!=null)
{
Bundle bundle=new Bundle();
bundle.putString("name",name);
bundle.putString("price",price);
bundle.putString("quantity",quantity);
this.getParent().setResult(RESULT_OK,new Intent().putExtras(bundle));
this.finish();
Log.e("C","inner");
}
Log.e("C","outer");
this.getParent().onBackPressed();
}
Why do you call finish? Pressing back means it will destroy
Your Activity from a ActivityGroup will not get the response calls directly.
You need to redirect from ActivityGroup.
Please see the below answer
Here is the solution. Please try this
https://stackoverflow.com/a/15047518/1403112
I have two activities: main activity and child activity.
When I press a button in the main activity, the child activity is launched.
Now I want to send some data back to the main screen. I used the Bundle class, but it is not working. It throws some runtime exceptions.
Is there any solution for this?
There are a couple of ways to achieve what you want, depending on the circumstances.
The most common scenario (which is what yours sounds like) is when a child Activity is used to get user input - such as choosing a contact from a list or entering data in a dialog box. In this case, you should use startActivityForResult to launch your child Activity.
This provides a pipeline for sending data back to the main Activity using setResult. The setResult method takes an int result value and an Intent that is passed back to the calling Activity.
Intent resultIntent = new Intent();
// TODO Add extras or a data URI to this intent as appropriate.
resultIntent.putExtra("some_key", "String data");
setResult(Activity.RESULT_OK, resultIntent);
finish();
To access the returned data in the calling Activity override onActivityResult. The requestCode corresponds to the integer passed in the startActivityForResult call, while the resultCode and data Intent are returned from the child Activity.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case (MY_CHILD_ACTIVITY) : {
if (resultCode == Activity.RESULT_OK) {
// TODO Extract the data returned from the child Activity.
String returnValue = data.getStringExtra("some_key");
}
break;
}
}
}
Activity 1 uses startActivityForResult:
startActivityForResult(ActivityTwo, ActivityTwoRequestCode);
Activity 2 is launched and you can perform the operation, to close the Activity do this:
Intent output = new Intent();
output.putExtra(ActivityOne.Number1Code, num1);
output.putExtra(ActivityOne.Number2Code, num2);
setResult(RESULT_OK, output);
finish();
Activity 1 - returning from the previous activity will call onActivityResult:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ActivityTwoRequestCode && resultCode == RESULT_OK && data != null) {
num1 = data.getIntExtra(Number1Code);
num2 = data.getIntExtra(Number2Code);
}
}
UPDATE:
Answer to Seenu69's comment, In activity two,
int result = Integer.parse(EditText1.getText().toString())
+ Integer.parse(EditText2.getText().toString());
output.putExtra(ActivityOne.KEY_RESULT, result);
Then in activity one,
int result = data.getExtra(KEY_RESULT);
Sending Data Back
It helps me to see things in context. Here is a complete simple project for sending data back. Rather than providing the xml layout files, here is an image.
Main Activity
Start the Second Activity with startActivityForResult, providing it an arbitrary result code.
Override onActivityResult. This is called when the Second Activity finishes. You can make sure that it is actually the Second Activity by checking the request code. (This is useful when you are starting multiple different activities from the same main activity.)
Extract the data you got from the return Intent. The data is extracted using a key-value pair.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final int SECOND_ACTIVITY_REQUEST_CODE = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// "Go to Second Activity" button click
public void onButtonClick(View view) {
// Start the SecondActivity
Intent intent = new Intent(this, SecondActivity.class);
startActivityForResult(intent, SECOND_ACTIVITY_REQUEST_CODE);
}
// This method is called when the second activity finishes
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Check that it is the SecondActivity with an OK result
if (requestCode == SECOND_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Get String data from Intent
String returnString = data.getStringExtra("keyName");
// Set text view with string
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText(returnString);
}
}
}
}
Second Activity
Put the data that you want to send back to the previous activity into an Intent. The data is stored in the Intent using a key-value pair.
Set the result to RESULT_OK and add the intent holding your data.
Call finish() to close the Second Activity.
SecondActivity.java
public class SecondActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
// "Send text back" button click
public void onButtonClick(View view) {
// Get the text from the EditText
EditText editText = (EditText) findViewById(R.id.editText);
String stringToPassBack = editText.getText().toString();
// Put the String to pass back into an Intent and close this activity
Intent intent = new Intent();
intent.putExtra("keyName", stringToPassBack);
setResult(RESULT_OK, intent);
finish();
}
}
Other notes
If you are in a Fragment it won't know the meaning of RESULT_OK. Just use the full name: Activity.RESULT_OK.
See also
Fuller answer that includes passing data forward
Naming Conventions for the Key String
FirstActivity uses startActivityForResult:
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivityForResult(intent, int requestCode); // suppose requestCode == 2
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2)
{
String message=data.getStringExtra("MESSAGE");
}
}
On SecondActivity call setResult() onClick events or onBackPressed()
Intent intent=new Intent();
intent.putExtra("MESSAGE",message);
setResult(Activity.RESULT_OK, intent);
Call the child activity Intent using the startActivityForResult() method call
There is an example of this here:
http://developer.android.com/training/notepad/notepad-ex2.html
and in the "Returning a Result from a Screen" of this:
http://developer.android.com/guide/faq/commontasks.html#opennewscreen
UPDATE Mar. 2021
As in Activity v1.2.0 and Fragment v1.3.0, the new Activity Result APIs have been introduced.
The Activity Result APIs provide components for registering for a result, launching the result, and handling the result once it is dispatched by the system.
So there is no need of using startActivityForResult and onActivityResult anymore.
In order to use the new API, you need to create an ActivityResultLauncher in your origin Activity, specifying the callback that will be run when the destination Activity finishes and returns the desired data:
private val intentLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
result.data?.getStringExtra("key1")
result.data?.getStringExtra("key2")
result.data?.getStringExtra("key3")
}
}
and then, launching your intent whenever you need to:
intentLauncher.launch(Intent(this, YourActivity::class.java))
And to return data from the destination Activity, you just have to add an intent with the values to return to the setResult() method:
val data = Intent()
data.putExtra("key1", "value1")
data.putExtra("key2", "value2")
data.putExtra("key3", "value3")
setResult(Activity.RESULT_OK, data)
finish()
For any additional information, please refer to Android Documentation
I have created simple demo class for your better reference.
FirstActivity.java
public class FirstActivity extends AppCompatActivity {
private static final String TAG = FirstActivity.class.getSimpleName();
private static final int REQUEST_CODE = 101;
private Button btnMoveToNextScreen;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnMoveToNextScreen = (Button) findViewById(R.id.btnMoveToNext);
btnMoveToNextScreen.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent mIntent = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(mIntent, REQUEST_CODE);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK){
if(requestCode == REQUEST_CODE && data !=null) {
String strMessage = data.getStringExtra("keyName");
Log.i(TAG, "onActivityResult: message >>" + strMessage);
}
}
}
}
And here is SecondActivity.java
public class SecondActivity extends AppCompatActivity {
private static final String TAG = SecondActivity.class.getSimpleName();
private Button btnMoveToPrevious;
private EditText editText;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
editText = (EditText) findViewById(R.id.editText);
btnMoveToPrevious = (Button) findViewById(R.id.btnMoveToPrevious);
btnMoveToPrevious.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String message = editText.getEditableText().toString();
Intent mIntent = new Intent();
mIntent.putExtra("keyName", message);
setResult(RESULT_OK, mIntent);
finish();
}
});
}
}
In first activity u can send intent using startActivityForResult() and then get result from second activity after it finished using setResult.
MainActivity.class
public class MainActivity extends AppCompatActivity {
private static final int SECOND_ACTIVITY_RESULT_CODE = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// "Go to Second Activity" button click
public void onButtonClick(View view) {
// Start the SecondActivity
Intent intent = new Intent(this, SecondActivity.class);
// send intent for result
startActivityForResult(intent, SECOND_ACTIVITY_RESULT_CODE);
}
// This method is called when the second activity finishes
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// check that it is the SecondActivity with an OK result
if (requestCode == SECOND_ACTIVITY_RESULT_CODE) {
if (resultCode == RESULT_OK) {
// get String data from Intent
String returnString = data.getStringExtra("keyName");
// set text view with string
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText(returnString);
}
}
}
}
SecondActivity.class
public class SecondActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
// "Send text back" button click
public void onButtonClick(View view) {
// get the text from the EditText
EditText editText = (EditText) findViewById(R.id.editText);
String stringToPassBack = editText.getText().toString();
// put the String to pass back into an Intent and close this activity
Intent intent = new Intent();
intent.putExtra("keyName", stringToPassBack);
setResult(RESULT_OK, intent);
finish();
}
}
All these answers are explaining the scenario of your second activity needs to be finish after sending the data.
But in case if you don't want to finish the second activity and want to send the data back in to first then for that you can use BroadCastReceiver.
In Second Activity -
Intent intent = new Intent("data");
intent.putExtra("some_data", true);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
In First Activity-
private BroadcastReceiver tempReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// do some action
}
};
Register the receiver in onCreate()-
LocalBroadcastManager.getInstance(this).registerReceiver(tempReceiver,new IntentFilter("data"));
Unregister it in onDestroy()
Another way of achieving the desired result which may be better depending on your situation is to create a listener interface.
By making the parent activity listen to an interface that get triggered by the child activity while passing the required data as a parameter can create a similar set of circumstance
There are some ways of doing this.
1. by using the startActivityForResult() which is very well explained in the above answers.
by creating the static variables in your "Utils" class or any other class of your own. For example i want to pass studentId from ActivityB to ActivityA.First my ActivityA is calling the ActivityB. Then inside ActivityB set the studentId (which is a static field in Utils.class).
Like this Utils.STUDENT_ID="1234"; then while comming back to the ActivityA use the studentId which is stored in Utils.STUDENT_ID.
by creating a getter and setter method in your Application Class.
like this:
public class MyApplication extends Application {
private static MyApplication instance = null;
private String studentId="";
public static MyApplication getInstance() {
return instance;
}
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public void setStudentId(String studentID){
this.studentId=studentID;
}
public String getStudentId(){
return this.studentId;
}
}
so you are done . just set the data inside when u are in ActivityB and after comming back to ActivityA , get the data.
Just a small detail that I think is missing in above answers.
If your child activity can be opened from multiple parent activities then you can check if you need to do setResult or not, based on if your activity was opened by startActivity or startActivityForResult. You can achieve this by using getCallingActivity(). More info here.
Use sharedPreferences and save your data and access it from anywhere in the application
save date like this
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
And recieve data like this
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
String savedPref = sharedPreferences.getString(key, "");
mOutputView.setText(savedPref);