I am stuck trying to figure out where exactly to put the finish() function in my code.
I have tried putting it on line 43 of ProfileActivity or lines 39 or 56 of MainActivity. I'm very new at this and have read what the purpose of finish() is but can't figure out where else in my code it should go.
These are just nippets of the code ... there is more (all the Activity lifecycle functions), but I omitted to save space.
public class MainActivity extends AppCompatActivity {
SharedPreferences sp;
EditText email;
public static final String ACTIVITY_NAME = "PROFILE_ACTIVITY";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
email = (EditText)findViewById(R.id.thisEmailIsPassedToPage2);
sp = getSharedPreferences("Lab3", Context.MODE_PRIVATE);
String savedString = sp.getString("Email", "0");
email.setText(savedString);
Log.e(ACTIVITY_NAME, "In Function onCreate() in MainActivity:");
Button login = (Button)findViewById(R.id.loginButton);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,
ProfileActivity.class);
EditText et =
(EditText)findViewById(R.id.thisEmailIsPassedToPage2);
intent.putExtra("typed", et.getText().toString());
startActivityForResult(intent, 2);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
int i = 0;
i++;
//if request code is 2, then we are coming back from ProfileActivity
if(requestCode == 2){
EditText et =
(EditText)findViewById(R.id.thisEmailIsPassedToPage2);
String fromProfile = data.getStringExtra("typed");
et.setText(fromProfile);
Log.i("Back", "Message");
}
}
public class ProfileActivity extends AppCompatActivity {
private SharedPreferences sp;
private ImageButton mImageButton;
public static final String ACTIVITY_NAME = "PROFILE_ACTIVITY";
public static final int REQUEST_IMAGE_CAPTURE = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profileactivity);
Log.e(ACTIVITY_NAME, "In Function onCreate() in ProfileActivity:");
Intent fromPrevious = getIntent();
String previousTyped = fromPrevious.getStringExtra("typed");
EditText enterText = (EditText) findViewById(R.id.editText6);
enterText.setText(previousTyped);
mImageButton = (ImageButton) this.findViewById(R.id.imageButton);
mImageButton.setOnClickListener(bt -> {
dispatchTakePictureIntent();
});
}
private void dispatchTakePictureIntent(){
Intent takePictureIntent = new
Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImageButton.setImageBitmap(imageBitmap);
}
}
These are the screenshots:
[MainActivity1stPage][1]
[ProfileActivity2ndPage][2]
[AfterImageButtonPressed][3]
[AfterTakingPictureAndPressingOK][4]
If I'm getting it right, your flow is MainActivity starts ProfileActivity for result, then in ProfileActivity you start the ACTION_IMAGE_CAPTUREfor result, so I'm guessing that with that result you want to trigger your MainActivity onActivityResult. So if that the case you need to setResult and finish at the onActivityResultof your ProfileActivity.
I have 3 activities : activity "valider" as 1st activity and the second is activivty "connexion" and finally the inscription activity , i hope to pass from 1st==> second==> third and viceversa from third==> second==>first activity.
Please someone can help me?
There are multiple ways to share data with different activities your question is repeated please check this: What's the best way to share data between activities?
To pass data in the First:
void send() {
Intent intent = new Intent(this, Second.class);
intent.putExtra("NAME",some_value);//your data
startActivityForResult(intent, yourSomeId);// if you want to retrieve callback data later
startActivity(intent);//or simply
}
in the Second
in
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if(extras == null) {
yourData = null;
} else {
yourData = extras.getString("NAME");
}
}
to send data back:
charge data in the second activity:
void back() {
Intent intent = new Intent();
intent.putExtra("NAME", yourdata);
setResult(RESULT_OK, intent);
finish();
}
and retrieve in the First:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null) {return;}
yourdata = data.getStringExtra("NAME");
}
you can send the data to the third activity in the same way.
I use ZXing library to scan QrCode.
From the drawer menu i call a new intent where i start a custom activity scan with a custom view :
integrator.setCaptureActivity(QrCodeCaptureActivity.class);
public class QrCodeActivity extends AppCompatActivity {
private static final String TAG = "QrCodeActivity";
private String message = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qrcode);
setToolbar();
scanBarcodeCustomLayout();
}
/** Set la toolbar */
private void setToolbar(){
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
public void scanBarcodeCustomLayout() {
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setOrientationLocked(false);
integrator.setCaptureActivity(QrCodeCaptureActivity.class);
integrator.initiateScan();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if(result != null) {
message = result.getContents();
if(result.getContents() == null) {
Log.d(TAG, "Cancelled scan");
finish();
// Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
} else {
showConfirmDialog();
Log.d(TAG, "Scanned: " + result.getContents());
// Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
}
} else {
// This is important, otherwise the result will not be passed to the fragment
super.onActivityResult(requestCode, resultCode, data);
}
}
private void showConfirmDialog(){
Intent confirmIntent = new Intent(QrCodeActivity.this, QrCodeConfirmActivity.class);
confirmIntent.putExtra(Constants.QR_CODE_MESSAGE, message);
startActivity(confirmIntent);
}
}
The capture activity looks like this :
public class QrCodeCaptureActivity extends CaptureActivity {
#Override
protected DecoratedBarcodeView initializeContent() {
setContentView(R.layout.capture_small);
return (DecoratedBarcodeView)findViewById(R.id.zxing_barcode_scanner);
}
}
You can see, when the scan is done i open a new activity with the result for confirmation :
private void showConfirmDialog(){
Intent confirmIntent = new Intent(QrCodeActivity.this, QrCodeConfirmActivity.class);
confirmIntent.putExtra(Constants.QR_CODE_MESSAGE, message);
startActivity(confirmIntent);
}
When i'm in this activity and when i close this, I return on a blank activity.
I think this blank activity is the Capture Activity for custom apparence :
integrator.setCaptureActivity(QrCodeCaptureActivity.class);
Where is the mistake ?
Thanks
Just a simple thing you have to add in it ::
Add one new line after ::
startActivity(confirmIntent);
finish();
So your last QR code activity will be no longer visible at all.
I found the mistake ...
I call a activity instead of call directly the method
integrator.initiateScan();
I need some help with my android app. I have two activities, first starts the second one with startActivityForResult(). When the second one closes it sends the intent as it should, however when i want to access extra from onActivityResult() i get a null instead of what I put in.
I also tried using bundle with
Bundle b = getIntent().getExtras();
b.getString(AddTable.EXTRA_NAME);
but it resulted in RuntimeException and failure delivering result.
Here's my code:
public class RunnerApp extends Activity {
private ListView listView;
private static ArrayList<String> values = new ArrayList<String>();
private ArrayAdapter<String> adapter;
private Intent newTable;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_runner_app);
listView = (ListView) findViewById(R.id.mylist);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, values);
listView.setAdapter(adapter);
}
public void addTable(View v){
newTable = new Intent(this, AddTable.class);
startActivityForResult(newTable, 1);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1 && resultCode == Activity.RESULT_OK && data != null){
data = getIntent();
Log.d("add", "got intent");
String newName = data.getStringExtra(AddTable.EXTRA_NAME);
Log.d("add", "string " + newName); //always prints string null
values.add(newName);
Log.d("add", "added to list");
}
}
#Override
public void onResume(){
super.onResume();
setContentView(R.layout.activity_runner_app);
adapter.notifyDataSetChanged();
}
}
Second activity started by startActivityForResult()
public class AddTable extends Activity {
public final static String EXTRA_NAME = "com.example.runnerapp.NAME";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_table);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_add_table, menu);
return true;
}
public void addThisTable(View v) {
Intent addTable = new Intent(this, RunnerApp.class);
EditText editText = (EditText) findViewById(R.id.addTableField);
String name = editText.getText().toString();
addTable.putExtra(EXTRA_NAME, name);
Log.d("intenyt", name);
setResult(Activity.RESULT_OK, addTable);
this.finish();
}
}
In your first activity your code reads
data = getIntent();
But the actual data you want is in
data.getData()
use this in the onActivityResult function..
data.getStringExtra(EXTRA_NAME)
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);