I have 2 activities ,activity A is having webview and activity B is having button with transparent layout. I want close the activity B and refresh or do something in activity A when I press button from activity B.
I tried shared preferences but that not working without restarting activity A.
Have a look at the docs for Getting a Result from an Activity
Updated to include example
static final int PICK_CONTACT_REQUEST = 1; // The request code
...
private void pickContact() {
Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
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)
}
}
}
create a method as refreshmethod in Activity A and call it from Activity B something like this:
ActivityA activitya:
//stuff
activitya = new ActivityA();
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
activitya.refreshmethod();
}
});
hope it helps.
Related
This question already has answers here:
How to manage startActivityForResult on Android
(14 answers)
Closed 3 years ago.
I am using both an ImagePicker and a barcode reader in a single activity. The main problem is that both of these require onActivityResult() to display the result. As we know a single activity can only have a single onActivityResult() method in it. How can I display both of them?
I have tried using switch cases to assign multiple requestCodes in the onActivityResult() but can't seem to figure out the solution.
Here's the method I tried.
public class MainActivity extends AppCompatActivity{
private TextView mIdentificationNumber;
private IntentIntegrator scanQR;
//Authentication For Firebase.
private FirebaseAuth mAuth;
//Toolbar
private Toolbar mToolBar;
private DatabaseReference mUserRef;
private ImageView mAssetImg;
private EditText massetName, massetModel, massetBarcode, massetArea, massetDescription;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Getting the Present instance of the FireBase Authentication
mAuth = FirebaseAuth.getInstance();
//Finding The Toolbar with it's unique Id.
mToolBar = (Toolbar) findViewById(R.id.main_page_toolbar);
//Setting Up the ToolBar in The ActionBar.
setSupportActionBar(mToolBar);
if (mAuth.getCurrentUser() != null){
mUserRef = FirebaseDatabase.getInstance().getReference().child("Users")
.child(mAuth.getCurrentUser().getUid());
mUserRef.keepSynced(true);
}
massetBarcode = (EditText) findViewById(R.id.BarcodeAsset);
scanQR = new IntentIntegrator(this);
massetBarcode.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
scanQR.initiateScan();
}
});
mAssetImg = (ImageView) findViewById(R.id.asset_img);
mAssetImg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getImage();
}
});
}
//OnStart Method is started when the Authentication Starts.
#Override
public void onStart() {
super.onStart();
// Check if user is signed in (non-null).
FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser == null){
startUser();
} else {
mUserRef.child("online").setValue("true");
Log.d("STARTING THE ACTIVITY" , "TRUE");
}
}
#Override
protected void onPause() {
super.onPause();
FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser != null){
mUserRef.child("online").setValue(ServerValue.TIMESTAMP);
Log.d("STOPPING THE ACTIVITY" , "TRUE");
}
}
private void startUser() {
//Sending the user in the StartActivity If the User Is Not Logged In.
Intent startIntent = new Intent(MainActivity.this , AuthenticationActivity.class);
startActivity(startIntent);
//Finishing Up The Intent So the User Can't Go Back To MainActivity Without LoggingIn.
finish();
}
//Setting The Menu Options In The AppBarLayout.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
//Inflating the Menu with the Unique R.menu.Id.
getMenuInflater().inflate(R.menu.main_menu , menu);
return true;
}
//Setting the Individual Item In The Menu.(Logout Button)
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
if (item.getItemId() == R.id.main_logout_btn){
FirebaseAuth.getInstance().signOut();
startUser();
}
return true;
}
private void getImage() {
ImagePicker.Companion.with(this)
.crop() //Crop image(Optional), Check Customization for more option
.compress(1024) //Final image size will be less than 1 MB(Optional)
.maxResultSize(1080, 1080) //Final image resolution will be less than 1080 x 1080(Optional)
.start();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 0:
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if (result != null) {
if (result.getContents() == null) {
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
} else {
massetBarcode.setText(result.getContents());
Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
}
}
break;
case 1:
if (resultCode == Activity.RESULT_OK) {
assert data != null;
Uri imageURI = data.getData();
mAssetImg.setImageURI(imageURI);
}
break;
}
}
}
The rest of the answers told to use startActivityForResult() but that method requires Intent to go from one activity to another but I don't want to do this.
In both cases, the libraries you're using provide a way to specify a request code so you can distinguish the results in onActivityResult.
Your scanQR object should set a request code, per the source code:
massetBarcode.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
scanQR.setRequestCode(123).initiateScan();
}
});
You getImage() method should also specify a request code, again, per the library's source code.
private void getImage() {
ImagePicker.Companion.with(this)
.crop() //Crop image(Optional), Check Customization for more option
.compress(1024) //Final image size will be less than 1 MB(Optional)
.maxResultSize(1080, 1080) //Final image resolution will be less than 1080 x 1080(Optional)
.start(456); // Start with request code
}
Now, you can handle each request code as needed:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 123:
// HANDLE BARCODE
break;
case 456:
// HANDLE IMAGE
break;
}
}
Closing thought: I've never used either library. I found the solution by 1) assuming any library that provides an Activity you're supposed to invoke for a result would allow you to specify a request code for it and 2) looking through their documentation and source code for how to do that.
I'd encourage you to thoroughly study the documentation and source code for any open source library you intend to use since as soon as you do their code become your code and their bugs become your bugs, so you better know how to fix or workaround them.
Hope that helps!
In order to get results from fragments to your Activity, you can use an Interface to enable communication between them.
StartActivityForResult is used to start an activity and get a result back from it.
Please read more about it from here.
The startActivityForResult methos can use a second argument, a number so you can distinguish the resul
startActivityForResul(intent, 8)
You dont need to set the code back in the other activity, that is handled under the hood. So you probabbly want to add the number as a contant
private static final CAMERA_INTENT = 2
And then use it like this
startActivityForResul(intent, CAMERA_INTENT)
Finally in the onActivityResult implements the case basis
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
if (CAMERA_INTENT == requestCode) {
//DO PHOTO STUFF
}
}
The argument you need to eval is requestCode
This is my First Activity where i want to change button color by pressing button on another activity
public void colorchangeOnfirstActivity(){
Button btnA = (Button) findViewById(R.id.asmat_btn);
btnA.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
}
This is my second Activity where the second activity button is.
Button btnB = (Button) findViewById(R.id.rose_btn);
btnB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
asmat_activity secondActivity = new asmat_activity();
asmat_activity.colorchangeOnfirstActivity();
}
});
Activities should never directly interact with each other. Generally, if you want to do something in response to an action in another Activity, you should use the Activity Result APIs.
So, for example, you may start your secondary Activity with a request code:
// The request code can be any integer value you wish
startActivityForResult(activityIntent, MY_REQUEST_CODE);
Then in your new Activity, you can set a result to be delivered back to the Activity which started it. In your case, something like:
btnB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// This will deliver the result to the requesting Activity
setResult(RESULT_OK);
finish();
}
}
Then in your first Activity, you will override onActivityResult to handle the result:
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
if (requestCode == MY_REQUEST_CODE) {
btnA.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
Further to my previous post, I now want to invoke a child activity from the main activity a number of times. In my real project (as opposed to the noddy test below), when the child activity is invoked, its header displays, "Enter first data set" then invites the user to enter some data. This data is actually stored in a common class rather than being returned to the main activity. Then the child needs to be called again with a new prompt "Enter second data set", and the same thing happens.
What I cannot work out is how to do this. If I include two calls to the child, every time, only the second call appears to happen, the prompt appearing in the child activity being "Enter second data set" every time. This startActivityForResult() method is I believe, designed to be used when you want to call an activity and wait for the result (which you do with an onActivityResult() do you not), but it does not wait.
How on earth do I do this? Sample code follows.
Thank you to anyone who can clearly explain where I'm going wrong and what the right code should be.
MainActivity code extract
#Override
public void onResume(){
super.onResume();
TextView maintop = (TextView)findViewById(R.id.maintop);
maintop.setText(Common.mess1);
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button mainbutton = (Button)findViewById(R.id.mainbutton);
mainbutton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Intent intent1 = new Intent(MainActivity.this,Child.class);
intent1.putExtra("Prompt", "Enter first data set");
startActivityForResult(intent1,1);
onActivityResult(1,1,intent1);
}
});
mainbutton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Intent intent2 = new Intent(MainActivity.this,Child.class);
intent2.putExtra("Prompt", "Enter second data set");
startActivityForResult(intent2,1);
onActivityResult(1,1,intent2);
}
});
}
You can only have one click listener in the button, so when you call set for the 2nd time it replaces the listener.
What you need to do is set the click listener for the enter first data, don't call to onActivityResult(1,1,intent1) that's not how you do it, you need override the method, and in onActivityResult call the 2nd.
Something like this:
static final int FIRST_INTENT = 1;
static final int SECOND_INTENT = 2;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button mainbutton = (Button)findViewById(R.id.mainbutton);
mainbutton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Intent intent1 = new Intent(MainActivity.this,Child.class);
intent1.putExtra("Prompt", "Enter first data set");
startActivityForResult(intent1,FIRST_INTENT);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == FIRST_INTENT) {
if (resultCode == RESULT_OK) {
Intent intent2 = new Intent(MainActivity.this,Child.class);
intent2.putExtra("Prompt", "Enter second data set");
startActivityForResult(intent2,SECOND_INTENT);
}
}
}
And in your child activity
//DO SOMETHING
....
setResult(RESULT_OK)
finish();
}
For more check
[http://developer.android.com/intl/es/training/basics/intents/result.html]
[http://developer.android.com/intl/es/reference/android/app/Activity.html#setResult%28int%29]
hey every one i am sorry but i have to ask this question, it seems like a very easy issue but i just stuck! i have spent the last 2 hours going through the form and android developer resource site and i cant find the problem with my code.
first of all the startActivityForResult() will not send me the text back.
second every time i click on the Implicit Activation button the app crashes.
here is the main activity file:
public class ActivityLoaderActivity extends Activity {
static private final int GET_TEXT_REQUEST_CODE = 1;
static private final String URL = "http://www.google.com";
static private final String TAG = "Lab-Intents";
// For use with app chooser
static private final String CHOOSER_TEXT = "Load " + URL + " with:";
// TextView that displays user-entered text from ExplicitlyLoadedActivity runs
private TextView mUserTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loader_activity);
// Get reference to the textView
mUserTextView = (TextView) findViewById(R.id.textView1);
// Declare and setup Explicit Activation button
Button explicitActivationButton = (Button) findViewById(R.id.explicit_activation_button);
explicitActivationButton.setOnClickListener(new OnClickListener() {
// Call startExplicitActivation() when pressed
#Override
public void onClick(View v) {
startExplicitActivation();
}
});
// Declare and setup Implicit Activation button
Button implicitActivationButton = (Button) findViewById(R.id.implicit_activation_button);
implicitActivationButton.setOnClickListener(new OnClickListener() {
// Call startImplicitActivation() when pressed
#Override
public void onClick(View v) {
startImplicitActivation();
}
});
}
// Start the ExplicitlyLoadedActivity
private void startExplicitActivation() {
Log.i(TAG,"Entered startExplicitActivation()");
// TODO - Create a new intent to launch the ExplicitlyLoadedActivity class
Intent explicitIntent = new Intent (ActivityLoaderActivity.this, ExplicitlyLoadedActivity.class);
// TODO - Start an Activity using that intent and the request code defined above
startActivityForResult(explicitIntent, GET_TEXT_REQUEST_CODE);
}
// Start a Browser Activity to view a web page or its URL
private void startImplicitActivation() {
Log.i(TAG, "Entered startImplicitActivation()");
// TODO - Create a base intent for viewing a URL
// (HINT: second parameter uses Uri.parse())
Intent baseIntent = new Intent (Intent.ACTION_VIEW, Uri.parse(URL));
// TODO - Create a chooser intent, for choosing which Activity
// will carry out the baseIntent
// (HINT: Use the Intent class' createChooser() method)
Intent chooserIntent = null;
chooserIntent.createChooser(baseIntent, CHOOSER_TEXT);
Log.i(TAG,"Chooser Intent Action:" + chooserIntent.getAction());
// TODO - Start the chooser Activity, using the chooser intent
startActivity(chooserIntent);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "Entered onActivityResult()");
// TODO - Process the result only if this method received both a
// RESULT_OK result code and a recognized request code
// If so, update the Textview showing the user-entered text.
if (resultCode == RESULT_OK){
mUserTextView.setText(data.getStringExtra("resulttext"));
}}}
and here is the explicit intent file:
public class ExplicitlyLoadedActivity extends Activity {
static private final String TAG = "Lab-Intents";
private EditText mEditText;
String resulttext="still waiting";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.explicitly_loaded_activity);
// Get a reference to the EditText field
mEditText = (EditText) findViewById(R.id.editText);
// Declare and setup "Enter" button
Button enterButton = (Button) findViewById(R.id.enter_button);
enterButton.setOnClickListener(new OnClickListener() {
// Call enterClicked() when pressed
#Override
public void onClick(View v) {
enterClicked();
}
});
}
// Sets result to send back to calling Activity and finishes
private void enterClicked() {
Log.i(TAG,"Entered enterClicked()");
// TODO - Save user provided input from the EditText field
resulttext= mEditText.getText().toString();
// TODO - Create a new intent and save the input from the EditText field as an extra
Intent returntrip = new Intent ();
returntrip.putExtra("wayback", resulttext);
// TODO - Set Activity's result with result code RESULT_OK
setResult(RESULT_OK, returntrip);
// TODO - Finish the Activity
finish();
}
}
thank you guys so much i know i am a bother!
You are sending an extra data called "wayback" not "resulttext"
returntrip.putExtra("wayback", resulttext);
this will fix your code:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "Entered onActivityResult()");
if (resultCode == RESULT_OK){
mUserTextView.setText(data.getStringExtra("wayback"));
}
Well, you won't get the result back correct from your onActivityResult because you are not using the correct key. You look inside for data.getStringExtra("resulttext") but you originally set the key as "wayback". You need to grab with that key.
I have a TabActivity that has a TabHost with two tabs. Each tab has its own intent. It seems like the intent's onResume() fires before I can detect if a tab was changed. How can I resolve this?
TabActivity code:
public class TabHostActivity extends TabActivity {
static final int SHOW_SHARE_ACTIVITY = 0;
static final int SHOW_LOGIN_ACTIVITY = 1;
private TabHost tabHost;
private ImageButton composeImageButton;
private SharedPreferences prefs;
private Bundle b;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.tabhostactivity);
prefs = getSharedPreferences(Constants.PREFS_NAME, 0);
//Setup the ActionBar
composeImageButton = (ImageButton) findViewById(R.id.composeImageButton);
composeImageButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(prefs.getBoolean("isLoggedIn", false))
{
showShareActivity();
}
else
{
Intent intent = new Intent(TabHostActivity.this, LoginActivity.class);
startActivityForResult(intent, SHOW_LOGIN_ACTIVITY);
}
}
});
b = new Bundle();
//Setup the Tabs
Resources res = getResources(); // Resource object to get Drawables
tabHost = getTabHost(); // The activity TabHost
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
#Override
public void onTabChanged(String arg0) {
if(tabHost.getCurrentTab() == 0) //Check if the Watchlist tab was clicked so we can prompt login
{
//Toast toast = Toast.makeText(getApplicationContext(), "TRENDING = YES", Toast.LENGTH_SHORT);
//toast.show();
b.putBoolean("isTrendingTab",true);
}
else
{
Toast toast = Toast.makeText(getApplicationContext(), "TRENDING = NO", Toast.LENGTH_SHORT);
toast.show();
b.putBoolean("isTrendingTab",false);
}
}
});
TabHost.TabSpec spec; // Resusable TabSpec for each tab
Intent intent; // Reusable Intent for each tab
// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, ARActivity.class);
intent.putExtras(b);
// Initialize a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("trending").setIndicator("Trending",res.getDrawable(R.drawable.icon)).setContent(intent);
tabHost.addTab(spec);
// Do the same for the other tabs
intent = new Intent().setClass(this, WatchlistActivity.class);
intent.putExtras(b);
spec = tabHost.newTabSpec("watchlist").setIndicator("Watchlist",res.getDrawable(R.drawable.icon)).setContent(intent);
tabHost.addTab(spec);
tabHost.setCurrentTab(0);
}
private void showShareActivity()
{
Intent intent = new Intent(TabHostActivity.this, ShareActivity.class);
startActivityForResult(intent, SHOW_SHARE_ACTIVITY);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == SHOW_LOGIN_ACTIVITY)
{
//Login was successful so lets show the compose box!
if (resultCode == RESULT_OK) {
showShareActivity();
}
}
}
}
Here is the onResume in the Intent for one of my Activities:
public void onResume()
{
super.onResume();
Bundle bundle = getIntent().getExtras();
if(bundle.getBoolean("isTrendingTab"))
{
Toast toast = Toast.makeText(getApplicationContext(), "TRENDING!", Toast.LENGTH_SHORT);
toast.show();
}
else
{
Toast toast = Toast.makeText(getApplicationContext(), "WATCHLIST!", Toast.LENGTH_SHORT);
toast.show();
}
}
If i understood correctly the problem is that you try to put
b.putBoolean("isTrendingTab",true);
(or false) on the intent you're going to launch by detecting change.
That's the wrong approach.
The change event will always occur after the activity is launched, you should do the logic different. You have to rethink it.
Have you looked at Activity life cycle? The resume is being called when the activity is being created too and the line bundle.getBoolean("isTrendingTab") does not have a default value in case it has not been set yet...
Can you set it first in the onCreate to a default value? I think that is your issue. The code is a little sloppy. You are trying to pass variables to each activity but they still both exists in the tab activity. Views would be a better method so they all see the same variables in the tab activity.
The oncreate of your class ARActivity.class will be called before your onresume method of your tab host.
So do whatever the processing you want in your ARActivity.
Also since your tabHost.setCurrentTab(0); your starting tab will always be ARActivity.
And if you want to activate code depending your tab change, figure out which tab you are on using using the main tabhost ontabchange and use the id and then send a request to a inner broadcast receiver.
if (tabHost.getCurrentTab() == 0) {
i.setAction(getString(R.string.br_refresh_home_tab));
sendBroadcast(i);
} else {
i.setAction(getString(R.string.br_refresh_sports_tab));
sendBroadcast(i);
}
In your ARActivity,
protected class RefreshList extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(
getString(R.string.br_refresh_home_tab))) {
}
}
}
There's no need to use onTabChanged().
Here's how I do it in my app (with some of your values pasted in). I add the boolean flag to the intent, not an extra bundle:
Intent intent = new Intent(action) // see notes below about "action"
.setClass(this, ARActivity.class)
.putExtra("isTrendingTab", true);
TabHost.TabSpec spec = tabHost.newTabSpec("trending")
.setIndicator("trending", getResources().getDrawable(drawableId))
.setContent(intent);
tabHost.addTab(spec);
Then in onResume():
if (getIntent().getBooleanExtra("isTrendingTab", false)) {...
I found that when using the same class for multiple tabs, I had to differentiate them with a different action string in each Intent constructor, as above. Otherwise it wouldn't create a new activity when switching between tabs of the same class. You don't appear to be doing this (yet), so you can continue to leave it out. I thought I'd mention it, since passing isTrendingTab suggests you might be heading down this route.