I'm using a TabActivity that calls an ActivityGroup. Tipical approach that brings problems.
Now I'm facing a problem with onActivityResult
in my Activity I have..
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.place_buttontab_community_media);
Button ButtonClick =(Button) findViewById(R.id.addPicture);
ButtonClick.setOnClickListener(new OnClickListener (){
#Override
public void onClick(View view)
{
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
// request code
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "hi");
super.onActivityResult(requestCode, resultCode, data);
}
}
unfortunately onActivityResult is never invoked.
You should listen for the result in the ActivityGroup's onActivityResult(). When a result is received, you have to decide which Activity should receive it and call it's onActivityResult() method with the received values.
I recently encountered this, to consolidate Andras' and virtual82's answer and discussion above (Sorry I can't add comment due to my low rep):
If your activity is started inside an ActivityGroup, which is used by TabActivity for example, then only the ActivityGroup activity can receive method calls to onActivityResult when you start an activity with startActivityForResult(Intent intent, int requestCode) from an activity inside the ActivityGroup.
In my situation, I have a TabActivity that contains FragmentActivitys. A Fragment inside a FragmentActivity may start an activity for result.
In this case the Fragment needs to start the activity with TabActivity as the calling activity:
Intent doSomethingIntent = new Intent();
//getActivity() returns the FragmentActivity, so we need to get the TabActivity with getParent()
Activity tabActivity = getActivity().getParent();
doSomethingIntent .setClass(tabActivity , PostCommentActivity.class);
tabActivity.startActivityForResult(doSomethingIntent , DO_SOMETHING_REQ_CODE);
Then in onActivityResult of the TabActivity, pass the result back to the Fragment.
Activity currentActivity = getLocalActivityManager().getCurrentActivity();
//get the FragmentActivity in order to get the Fragment instance
if(currentActivity instanceof FragmentActivity){
FragmentActivity currentFragmentActivity = (FragmentActivity)currentActivity ;
//R.id.l_container is the layout/viewgroup that contains the Fragment
Fragment currentFragment = currentFragmentActivity.getSupportFragmentManager().findFragmentById(R.id.l_container);
if(currentFragment != null){
//pass result to the Fragment!
frag.onActivityResult(requestCode, resultCode, data);
}
}
I realize that ActivityGroup, TabActivity and LocalActivityManager are deprecated in favor of Fragment and FragmentManager, but my project time constraint didn't allow me enough time to fully upgrade.
Hopefully this post will help someone in this situation, instead of the usual "don't do it" kind of response you see else where.
Related
I'm using shared element transition when navigate from activity A to activity B.
My issue - calling of SupportFinishAfterTransition in activity B makes OnActivityResult called after OnTransitionEnd with small interval in activity A. So my UI (ImageView) in activity A is "flashing" because of image source updating with interval.
I need OnActivityResult to be called first to update my UI and then play exit transition.
My code:
Activity A:
protected override void OnCreate(Bundle savedInstanceState)
{
// Some code
Window.SharedElementExitTransition.AddListener(this);
}
This code called firstly:
public void OnTransitionEnd(global::Android.Transitions.Transition transition)
{
}
This code called secondly, but I would like to firstly:
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
}
Activity B:
SetResult(Result.Ok, intent);
SupportFinishAfterTransition();
use onActivityReenter instead of OnActivityResult. onActivityReenter executes before activity displayed, OnActivityResult executes after activity displayed.
#Override
public void onActivityReenter(int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
//do your work here
//example of getting data:
int someData = data.getIntExtra("EXTRA_CODE", -1);
}
}
You have to be aware of these things when you want have a transition after returning from startActivityForResult:
i.) you need to specify a windowSharedElementReenterTransition, usually only windowSharedElementEnterTransition and windowSharedElementEnterTransition are specified.
ii.) in the onActivityReenter of the reentered Activity you need to call postponeEnterTransition(), then update your views as desired and call again startPostponedEnterTransition().
onActivityResult is only called when the previous Activity is finished, whereas onActivityReenter is called when the previous Activity is still running (you can get the Intent there to update the UI).
Here is an article which brings light into the dark:
https://www.androiddesignpatterns.com/2015/03/activity-postponed-shared-element-transitions-part3b.html
My mainActivity contains 5 fragments which you can switch through with tabs. The main tab shown on start is the third one (the one in the middle). I have a button in fragment #1 which opens activityTwo. What should I put in the onBackPressed method in activityTwo in order for it to bring me back to mainActivity with selected tab #1. I currently have this, but it opens mainActivity and shows the main tab (#3)
#Override
public void onBackPressed() {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
ActivityTwo.this.finish();
}
How can I make it show tab #1 instead of tab #3?
Your first activity should still be on the activity stack, so you should not call startActivity again. Instead, you can use setResult to pass a value back to your first activity:
// Inside your second activity
#Override
public void onBackPressed() {
setResult(RESULT_OK);
finish();
}
Then, from your first activity, replace startActivity with startActivityForResult, with a request code (any integer you want, as long as it's unique):
startActivityForResult(intent, YOUR_REQUEST_CODE);
Then override onActivityResult:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == YOUR_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Code to select tab 1 here
// mTabLayout.getTabAt(0).select();
}
}
}
i think you are using view pager , so while you return from activity 2, use viewPager.setCurrentItem(page);
where page will be your tab no, (in this case it will be 2, since it starts with 0). Hope this helps, if not then please clarify a bit more.
I have a main activity that contains 3 fragments. In each fragment I have a listView, on clicking which it is diverted to a new activity.
In the new Activity, I am changing the list view content that is clicked and diverting back to the main activity using intent.
This opens a new main Activity fragment and when I press back button I again get back to the previous Main Activity that was opened earlier.
Save activity's context in static variable like this
public class MainActivity extends AppCompatActivity {
public static MainActivity mainActivityInstance;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_staff_login);
//finishing older loaded mainActivity
if(MainActivity.mainActivityInstance!=null){
MainActivity.mainActivityInstance.finish();
}
mainActivityInstance=this;
}
}
From other activities you can finish your older activity like this
if(MainActivity.mainActivityInstance!=null){
MainActivity.mainActivityInstance.finish();
}
Instead of using startActivity use startActivityForResult in your fragment and have onActivityResult to obtain result from new Activity you have started
In your fragment do like this
static final int NEXT_ACTIVITY = 100;
//insert in listview on click
Intent intent = new Intent(context,Activity2.class);
intent.putExtra("key","value");//if needed
startActivityForResult(intent,NEXT_ACTIVITY);
#Override //*Note* you must override this method in you parent Activity in order to reflect the data inside your fragment
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode,resultCode,data);//while using inside fragment
switch(requestCode) {
case NEXT_ACTIVITY:
if (resultCode == RESULT_OK) {
Bundle res = data.getExtras();
String result = res.getString("param_result");
Log.d("FIRST", "result:"+result);
}
break;
}
}
In your new Activity while finishing/onBackpressed
Bundle data = new Bundle();
data.putString("param_result", "Thanks Thanks");
setResult(RESULT_OK, data);
finish();
For fragments, instead of finish();, you should call
getActivity().finish();
I am trying to do the following:
Show dialog fragment from an Activity (not Fragment);
Retrieve result in the Activity.
The problem is that onActivityResult in the Activity is not being called.
Here is how I am showing a DialogFragment
DriverRatingDialogFragment dp = new DriverRatingDialogFragment();
// this solution works well in case of showing dialog from a fragment
// but I have to show it from the Activity
// dp.setTargetFragment(getSupportFragmentManager().findFragmentById(R.id.flContent), DriverRatingDialogFragment.REQUEST_CODE);
dp.show(getSupportFragmentManager(), DriverRatingDialogFragment.ARG_RATING);
And here is how I am trying to return result from DialogFragment:
Intent intent = new Intent();
// This solution works well in case of previously setting target Fragment,
// but I have to return result to Activity
// getTargetFragment().onActivityResult(
// getTargetRequestCode(), REQUEST_CODE, intent);
// and with this attempt App crashes
// this.onActivityResult(REQUEST_CODE, Activity.RESULT_OK, intent);
here is where I want to retrieve result in the Activity, but it doesn't get called:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == DriverRatingDialogFragment.REQUEST_CODE) {
// todo
}
super.onActivityResult(requestCode, resultCode, data);
}
What's wrong?
I start the DialogFragment the same way you do.
CreatePostDialog createPostDialog = new CreatePostDialog();
createPostDialog.show(getSupportFragmentManager(), "create_post_dialog");
And I send back data using a public method in the activity rather than with intents.
((MainActivity)mContext).logout(Utils.getLocation(v));
The snippets above are copy pasted examples of my working code. Logout in this case is a public method in MainActivity that takes in a point and does what is needs with it.
you can use callback
1.define a callback in you dialog fragment
public Call mCall;
public interface Call {
void returnData(Data data);
}
2.on dialog fragment life circle
#Override
public void onDetach() {
super.onDetach();
mCall = (Call) getActivity();
mCall.returnData(data);
}
3.activity just implements Call
activity implements DiaFragment.Call
onActivityResult is there to receive informations after startActivityForResult is called, which is not your case.
What kind of datas you need to get from the dialog ?
DialogFragment is usually used in a fragment, not an activity. Look at alert dialog.
On a click of a button within a fragment, is it possible to close the two fragments within the same activity and return the result of the fragment to another activity? One fragment is expecting input while the other fragment has information for the user to view and is not expecting input.
Also, my code worked prior to using fragments in the activity, however the fragments are no longer showing up when clicking the intent to go to the activity (NextActivity.class) that holds the fragments...does any happen to know why the fragments are not appearing?
Here is some of my code below
A piece from the original activity:
public class MessageList extends ListActivity {
private void createMessage() {
Intent i = new Intent(this, NextActivity.class);
startActivityForResult(i, ACTIVITY_CREATE); //this line is incorrect, right?
}}
Here is a snippet from a fragment class:
public class MessageEditorFragment extends Fragment {
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
getActivity().finish();
}}
Also here is the activity class that holds the fragments, just incase you want a look:
public class NextActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_next);
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Tab one = actionBar.newTab().setText("Message Editor");
Tab two = actionBar.newTab().setText("Information");
one.setTabListener(new MyTabListener(new MessageEditorFragment()));
two.setTabListener(new MyTabListener(new InformationFragment()));
actionBar.addTab(one);
actionBar.addTab(two);
}
public class MyTabListener implements TabListener{
Fragment fragment;
public MyTabListener(Fragment f){
fragment = f;
}}}
I deeply appreciate all and any help!! Please let me know if you need to see more code as well.. Thank you :)
When the Activity is destroyed by calling finish , both the fragments will be destroyed/closed.
So, Before you finish the Activity from fragment, you can pass the values to the Activity which started it.
When you start the Activity , You need to start the Activity for Result , to return back the result data from the Fragment/Activity
In your Activity declare a integer request code
int FRAGMENT_REQUEST_CODE = 1000;
Start the activity , as per your logic
Intent intent = new Intent(this,MainActivityEx.class);
startActivityForResult(intent, FRAGMENT_REQUEST_CODE);
Add a callback method onActivityResult to receive the result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == FRAGMENT_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
TextView textView = (TextView)findViewById(R.id.textView1);
textView.setText(data.getExtras().getString("DATA"));
}
}
}
Now. In your Fragment, When you close the two Fragments , You can pass the data back to the caller Activity
Intent intent = new Intent();
intent.putExtra("DATA","Hai");
getActivity().setResult(Activity.RESULT_OK,intent);
getActivity().finish();