my problem is simple, I'm trying to pass an arraylist from my second activity to my mainActivity.
However when my onRestart() in my main activity is called when the user presses back from secondActivity the arraylist seems to be null.
IN MAIN ACTIVITY
#Override public void onRestart() {
super.onRestart();
DefaultLocations = (ArrayList<String>) getIntent().getSerializableExtra("updated");
///default locations is null
}
SECOND ACTIVITY
#Override public void onPause() {
super.onPause();
Intent intent = new Intent(ManageLocations.this, MainActivity.class);
intent.putExtra("updated",locationsavailable)///size is 2 currently;
this.setIntent(intent);
}
I've looked around as I know there are many examples but none helped me pass an arraylist BACK to my mainActivity.
All help is appreciated!
In second activity:
ArrayList < String > locationsavailable = new ArrayList < String > ();
locationsavailable.add("location1");
locationsavailable.add("location2");
Intent sentIntent = new Intent(SecondActivity.this, FirstActivity.class);
sentIntent.putExtra("string-array", locationsavailable);
startActivity(sentIntent);
In first activity:
Intent intent = getIntent();
String [] DefaultLocations = intent.getStringArrayExtra("string-array");
Edited:
In your case, I suggest use startActivityForResult to start second activity
and override onActivityResult in first activity.
The best solution for your situation would be to start the Second Activity using the startActivityForResult method. Here is an example of what you should do:
MainActivity
public class MainActivity extends AppCompatActivity {
private static final int GET_LOCATIONS_REQUEST_CODE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout layout = findViewById(R.id.mylayout);
Intent intent = new Intent(this, SecondActivity.class);
startActivityForResult(intent, GET_LOCATIONS_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == GET_LOCATIONS_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
ArrayList<String> locations = data.getStringArrayListExtra("result");
for(String location : locations) {
System.out.println(String.format("Location from SecondActivity %1$s", location));
}
}
if (resultCode == Activity.RESULT_CANCELED) {
//Write your code if there's no result
}
}
}
}
SecondActivity
public class SecondActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<String> locationsavailable = new ArrayList<>();
locationsavailable.add("location1");
locationsavailable.add("location1");
Intent returnIntent = new Intent();
returnIntent.putExtra("result", locationsavailable);
setResult(Activity.RESULT_OK, returnIntent);
finish();
}
}
If you don't want to start it as an Activity for result, you should override your #OnStart method in the MainActivity.
you just have to write simple code of some lines to solve your problem.
step 1:
while sending intent from main activity to second activity use startActivityForResult().
//Main Activity
private static final int GET_LOCATION_LIST=1; //you can give any value to variable
Intent intent = new Intent(context,SecondActivity.class);
startActivityForResult(intent,GET_LOCATION_LIST);
step 2: now in Second Activity you have to send the location list back in Main Activity.
//Second Activity
Intent intent = new Intent();
intent.putExtra("updated", locationsavailable);
setResult(Activity.RESULT_OK, intent);
SubmissionMailerClientContactList.this.finish();
step 3: now again in main activity you have to receive that intent using onActivityResult()
//Main Activity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
DefaultLocations=(ArrayList<String>)getIntent().getSerializableExtra("updated");
}
Related
I have two activities that should pass data back and forth to each other using intents. I'm not sure where to place some of the puts and gets though.
For Activity1 (MainActivity), I have a button, and on press it creates an intent, and then puts it to Activity2, then starts it using startActivity(intent).
btn.setOnClickListener((v) -> {
Intent intent = new Intent(this, Activity2.class);
intent.putExtra("test", testClass);
startActivity(intent);
});
Then in Activity2, I get that information in the onCreate() function using getIntent.
Now what I want to do is have a button in Activity2 that will pass data to Activity1, but won't necessarily "start/show" the activity.
So I'm wondering how this can be done.
My idea is to have the following similar to before:
Activity2:
btn.setOnClickListener((v) -> {
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("info", info);
});
But I'm confused about two things
Can I do this without starting the activity right away
Where would I do the getIntent call in MainActivity to retrieve this data
You can use startActivityForResult to start Activity2 and receive a result back to Activity1
Activity 1
int LAUNCH_ACTIVITY_TWO = 1;
Intent i = new Intent(this, Activity2.class);
i.putExtra("test", testClass);
startActivityForResult(i, LAUNCH_ACTIVITY_TWO);
//onActivityResult
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == LAUNCH_ACTIVITY_TWO) {
if(resultCode == Activity.RESULT_OK){
String result=data.getStringExtra("result");
}
}
}
Activity 2
Intent returnIntent = new Intent();
returnIntent.putExtra("result", result);
setResult(Activity.RESULT_OK, returnIntent);
finish();
Full Activity 1 code:
public class MainActivity extends AppCompatActivity {
public static int LAUNCH_ACTIVITY_TWO = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener((v) -> {
Intent i = new Intent(this, Activity2.class);
i.putExtra("test", testClass);
startActivityForResult(i, LAUNCH_ACTIVITY_TWO);
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == LAUNCH_ACTIVITY_TWO) {
if(resultCode == Activity.RESULT_OK){
String result= data.getStringExtra("result");
}
}
}
}
Full Activity 2 code:
public class Activity2 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(getIntent().getExtras() != null) {
// Get intent extras from Activity 1
}
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener((v) -> {
Intent returnIntent = new Intent();
returnIntent.putExtra("result", result);
setResult(Activity.RESULT_OK, returnIntent);
finish();
});
}
}
You can for example create a list in activity2 to which you add the data you want to pass to activity1. Before starting activity1 you get the values out of your array and add them as extras to the input.
You can have the data added to a JSONObject and use a serializer so you don't have to add your items all by yourself.
If you want to pass your data to activity1 without starting it,so activity1 processes the data, that is not possible. Activity doesnt execute anything while you are in activity2, for such cases you use fragments.
If you use fragments you can put all data in a viewmodel which is bound to the activity instead of each fragment.
There are several ways you can achieve this pending on what type of data you're looking at passing.
If it's an entire class object then make the class parcable. You can copy and paste the class in this website http://www.parcelabler.com/ and it auto formats it for you. All you do is pass it as an intent extra.
If you're looking at data that needs an action performed on it and then passed to another activity I would suggest using and intent service. You can perform certain actions pending the intents received in the service.
If you're looking at performing certain actions only after XYZ has occurred in your application then used shared preferences. These can be accessed anywhere quite easily.
Lastly, if you're using bulk data consistently that needs to remain persistent, use a local database storage and just query when you need to.
You can use SharedPreferences or static variables/fields for that.
I have two classes Class "A" and Class "B". In class A i have declared a
String password ="admin" .Now in class B i am taking value from user and i
want to change that value of string in class A and want to store value that
user entered. How can i do that? Any help please?
class A
forgetpassword.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent j = new Intent(MainActivity.this,newpassword.class);
startActivity(j);
Class B
EditText newpassword;
Button change;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_password);
newpassword = (EditText)findViewById(R.id.newpassword);
change = (Button)findViewById(R.id.chnage);
change.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MainActivity.b= newpassword.getText().toString();
Intent y= new Intent(NewPassword.this,MainActivity.class);
startActivity(y);
}
});
Use StartActivityForResult()
When you intend to get some result back from an Activity you should start activity using startActivityForResult(intent,requestcode)
Its easy Follow these steps
StartActivity
Intent i = new Intent(MainActivity.this, ForgotPasswordActivity.class);
startActivityForResult(i, 1);
Set new password in ForgotPasswordActivity
Now you are in ForgotPasswordActivity, set your new password and return back to MainActivity on Button click like this.
change.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent y= new Intent(NewPassword.this,MainActivity.class);
y.putExtra("someKey",newpassword.getText().toString()); //set new password
setResult(Activity.RESULT_OK, returnIntent); // set your result
finish(); // return back to MainActivity
}
});
Retrive new Password in MainActivity
Now you navigated back to MainActivty to retrieve your new password override onActivityResultMethod().
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == Activity.RESULT_OK){
String newPassword=data.getStringExtra("someKey");
}
if (resultCode == Activity.RESULT_CANCELED) {
//Write your code if there's no result
}
}
}
Here a link on startActivityForResult()
You can send data from one activity to another in the intent, Use the putExtra() methods the intent class to pass data.Send the data like this
Intent y= new Intent(NewPassword.this,MainActivity.class);
y.putExtra("yourKey",newpassword.getText().toString())
startActivity(y);
and in the onCreate() of MianActivity you can retrieve the value using getStringExtra("yourKey") like this
Intent callingIntent = getIntent();
String password = callingIntent.getStringExtra("yourKey");
and use the password.
Or you can start the NewPassword activity for a result and get the data back in onActivityResult()
Intent newPasswordIntent = new Intent(this,NewPassword.class);
startActivityForResult(newPasswordIntent ,REQUEST_CODE);
and in the change button click handler,
Intent intent= new Intent();
intent.putExtra("yourKey",newpassword.getText().toString());
setResult(Activity.RESULT_OK, intent);
finish();
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
String password = data.getStringExtra("yourKey")
}
Public static variables are easy to call, be aware that they can cause memory leaks
This can lead to context leaking or NPE when you finish the activity.
Instead use an Application class and initialize the string variable in it and with the use of getters() and setters() you can access the variable.
public class BaseApplication extends android.app.Application{
private String admin;
#Override
onCreate(...){
this.admin = "";
}
public String getAdmin(){
return this.admin;
}
public void setAdmin(String admin){
this.admin = admin;
}
}
classA:
...
((BaseApplication) getApplicationContext()).setAdmin("!mpr355!v3");
...
classB:
...
String myAdmin = ((BaseApplication) getApplicationContext()).getAdmin();
...
Also in your manifest file.
<application
android:name=".BaseApplication"
` ...>
UPDATE
Before startActivity(y);
just call
y.putExtra("pass", password);
and in your MainActivity, call getIntent().getStringExtra("pass");
Check for null pointers and you are good to go! :)
Muhammad,
There are many ways to do that and some of the listing here,
Use Broadcast receiver
Use start activity for result
Use static variable
From all of this if you want to change much time then I think broadcast receiver is good one,
Here is the example of broadcast receiver,
In your activity A register broadcast receiver with specific action,
private BroadcastReceiver brodcastRec=new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(intent!=null && intent.getAction().equals("changePassword")){
String newPassword=intent.getStringExtra("newPassword");
//do whatever you want to do here after getting new password
}
}
};
And then after write following code in your on create of activity A
IntentFilter intentFilter=new IntentFilter("changePassword");
registerReceiver(brodcastRec,intentFilter);
And In your activity B or click event of Button
Intent intent=new Intent();
intent.setAction("changePassword");
intent.putExtra("newPassword","yourValue");
sendBroadcast(intent);
i have these two Activity and each in the separate file:
public class MainActivity extends AppCompatActivity {
public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
}
public class DisplayMessageActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
ViewGroup layout = (ViewGroup) findViewById(R.id.activity_display_message);
layout.addView(textView);
}
}
in MainActivity we create Intent object and hold him some data ,
in the DisplayMessageActivity we get this intent using getIntent() method ,
and this method return to us Intent object
my question is how this method return to us the same Intent that we create in MainActivity ??
According to official documentation, get intent is used to
Return the intent that started this activity.
It means it is a function that returns the intent that originally started that activity.
That answers your query.
Android Developers Documentation - Activity - getIntent()
It is always a good practice to read official documentation.
The general syntax to add extras is:
Intent intent = new Intent(context, activity.class); //Create intent to start activity
intent.putExtra("key", data); //adding data
startActivity(intent);
To receive that data, from the Activity you started:
Intent intent = getIntent();
String data = intent.getExtra("key");
The String variable - data will hold the value that you attached with the previous activity. This means, you can only use this method till the next activity.
You have to implement onActivityResult in you MainActivity and start DisplayMessageActivity with startActivityForResult:
... sendMessage(View view) {
...
startActivityForResult(intent, MESSAGE_RESULT_CODE);
}
public void onActivityResult(int requestcode, int resultcode, Intent data) {
//You can get your result intent data here
if (requestcode == MESSAGE_RESULT_CODE && resultcode == RESULT_OK) {
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
}
}
and just add in DisplayMessageActivity in onPause, onStop or onBackPressed and onSupportNavigateUp:
//in your case maybe 'your_intent_sent_back_to_mainactivity = getIntent();'
setResult(RESULT_OK, your_intent_sent_back_to_mainactivity);
ADDITIONALLY
The source in Android Developer Community:
https://developer.android.com/training/basics/intents/result.html
I have 3 Activities. Intent is passed from Activity 1 to Activity 2 with some data which is to be used for DB transactions. From Activity 2 data and Intent are passed to Activity 3.
Now, i want to transfer from Activity 3 to Activity 2 but as activity 2 gets intent from Activity 1 , it returns some error which results in null exceptions :/
So , i want to refresh activity 2 on returning from Activity 3 , but without intent or proper use of intent which does not affect data
Start Activity2 from Acivity1 as:
Intent i = new Intent(this, Activity2.class);
startActivityForResult(i, 1);
in Activity2 use setResult for sending data back :
Intent intent = new Intent();
intent.putExtra("edittextvalue","value_here")
setResult(RESULT_OK, intent);
finish();
and in First Activity receive data as onActivityResult:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
if(resultCode == RESULT_OK){
String stredittext=data.getStringExtra("edittextvalue");
}
}
}
OR
You can use this
In Activity2,
#Override
public void onBackPressed() {
String data = mEditText.getText();
Intent intent = new Intent();
intent.putExtra("MyData", data);
setResult(resultcode, intent);
}
In Activity1,
onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == RESULT_OK) {
String myStr=data.getStringExtra("MyData");
mTextView.setText(myStr);
}
}
}
OR
you can use SharedPreferences also for Sharing data Between Activities
You can use interfaces to achieve this. Example: in your Activity3, create an interface:
interface Communicator {
void receiveData(Object toSend);
}
Then you implement your Activity2 as follows:
public class Activity2 extends Activity implements Activity3.Communicator, Serializable {
//You'll have to implement the method
public void receiveData(Object toSend) {
//do what you have to do with your object once it's been sent back.
}
}
In order to use this pattern, you'll have to use an intent to start Activity3 like you did. I used Serializable because you want to pass an instance of the Activity through the Intent:
Intent intent = new Intent(this, Activity3.class);
intent.putExtra("activity2", this);
startActivity(intent);
You retrieve the Activity2 object in Activity3 in its onCreate method:
public class Activity3 extends Activity {
private Communicator mActivity2; //your activity
private Object mData; //Whatever object you want to send
public void onCreate(Bundle bundle) {
//...
Intent intent = getIntent();
Serializable object = intent.getSerializableExtra("activity2");
if (object != null && object instanceof Communicator) {
//make sure the object is not null and implements the Communicator
mActivity2 = (Communicator) object;
}
}
}
Once you are done in your Activity3 (once it is closed), you implement a method like onBackPressed or onDestroy as follows:
#Override
public void onDestroy() { //better if the back button is not pressed
super.onDestroy();
if (mActivity2 != null) { //check if is not null
mActivity2.receiveData(mData);
}
}
And your Activity should be updated without using intents.
By the way, using Fragments using this pattern is MUCH better than Activities. You should use fragments instead.
I would terminate my app and cancel it from the list of recent task.
finishAndRemoveTask() is available only on API 21.
What should I use on API lower than 21??
Make an intent to the first activity in the stack and finish the current activity:
Intent intent = new Intent(this, FirstActivity.class);
intent.putExtra(EXTRA_FINISH, true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
And, in the onResume method of the FirstActivity, something like this to finish the last activity in the stack (and hopefully removing the app from the recent apps list):
if (getExtras() != null && getIntentExtra(EXTRA_FINISH, false)) {
finish();
}
I had a similar use case where I needed to finish all activities. Here is one way to do it without finishAndRemoveTask().
Make all your activities extend a base class with the following things in it:
private Boolean mHasParent = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mHasParent = extras.getBoolean("hasParent", false);
}
}
// Always start next activity by calling this.
protected void startNextActivity(Intent intent) {
intent.putExtra("hasParent", true);
startActivityForResult(intent, 199);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == 199 && resultCode == FINISH_ALL) {
finishAllActivities();
}
}
protected void finishAllActivities() {
if (mHasParent) {
// Return to parent activity.
setResult(FINISH_ALL);
} else {
// This is the only activity remaining on the stack.
// If you need to actually return some result, do it here.
Intent resultValue = new Intent();
resultValue.putExtra(...);
setResult(RESULT_OK, resultValue);
}
finish();
}
Simply call finishAllActivities() in any activity, and all the activities will unwind. Ofcourse if you don't care what result the last activity returns, the code can be made much simpler.