Search code examples
androidonactivityresult

issue in onActivityResult with sony xperia


i start activity for result to open GPS then recieve in OnACtivityResult .. it is work fine in some mobiles , but with sony not work , i don't know why i use nested fragment start activity

Intent callGPSSettingIntent = new Intent(
                                        android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                                startActivityForResult(
                                        callGPSSettingIntent, openGPSRequest);

then receive in fragment

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == openGPSRequest) {
            try {
                activity.hideProgress();
            } catch (Exception e) {

            }
            activity.replaceCurrentFragment(
                    FramentNavigationMapInside.getInstance(branche), true, true);
        }
    }

in main activity

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);



    }

and in every fragment override onActivityResult

and i test it in lenove and samsung and work fine ,, but with sony xperia not work, only onActivityResult which in main activity call


Solution

  • solve my issue by

    One of the common problem we always meet in the world of Fragment is: although we could call startActivityForResult directly from Nested Fragment but it appears that onActivityResult would never been called which brought a lot of trouble to handle Activity Result from Nested Fragment.

    the solution

    So we will call getActivity().startActivityForResult(...) from Fragment instead of just startActivityResult(...) from now on. Like this:

    // In Fragment
    Intent intent = new Intent(getActivity(), SecondActivity.class);
    getActivity().startActivityForResult(intent, 12345);
    

    As a result, all of the result received will be handled at the single place: onActivityResult of the Activity that Fragment is placed on.

    Question is how to send the Activity Result to Fragment? Due to the fact that we couldn't directly communicate with all of the nested fragment in the normal way, or at least in the easy way. And another fact is, every Fragment knows that which requestCode it has to handled since it is also the one that call startActivityForResult. So we choose the way to "broadcast to every single Fragment that is active at time. And let those Fragments check requestCode and do what they want."

    Talk about broadcasting, LocalBroadcastManager could do the job but the mechanic is the way too old. I choose another alternative, an EventBus, which has a lot of choices out there. The one that I chose was Otto from square. It is really good at performance and robustness.

    dependencies {
      compile 'com.squareup:otto:1.3.6'
    }
    

    In the Otto way, let's create a Bus Event as a package carry those Activity Result values.

    import android.content.Intent;
    
    /**
     * Created by nuuneoi on 3/12/2015.
     */
    public class ActivityResultEvent {
    
        private int requestCode;
        private int resultCode;
        private Intent data;
    
        public ActivityResultEvent(int requestCode, int resultCode, Intent data) {
            this.requestCode = requestCode;
            this.resultCode = resultCode;
            this.data = data;
        }
    
        public int getRequestCode() {
            return requestCode;
        }
    
        public void setRequestCode(int requestCode) {
            this.requestCode = requestCode;
        }
    
        public int getResultCode() {
            return resultCode;
        }
    
        public void setResultCode(int resultCode) {
            this.resultCode = resultCode;
        }
    
        public Intent getData() {
            return data;
        }
    
        public void setData(Intent data) {
            this.data = data;
        }
    }
    
    import android.os.Handler;
    import android.os.Looper;
    
    import com.squareup.otto.Bus;
    
    /**
     * Created by nuuneoi on 3/12/2015.
     */
    public class ActivityResultBus extends Bus {
    
        private static ActivityResultBus instance;
    
        public static ActivityResultBus getInstance() {
            if (instance == null)
                instance = new ActivityResultBus();
            return instance;
        }
    
        private Handler mHandler = new Handler(Looper.getMainLooper());
    
        public void postQueue(final Object obj) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    ActivityResultBus.getInstance().post(obj);
                }
            });
        }
    
    }
    

    And in activity

    public class MainActivity extends ActionBarActivity {
    
        ...
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            ActivityResultBus.getInstance().postQueue(
                        new ActivityResultEvent(requestCode, resultCode, data));
        }
    
        ...
    
    }
    

    and in the end handle back data onActivityResult in fragment

    public class BodyFragment extends Fragment {
    
        ...
    
        @Override
        public void onStart() {
            super.onStart();
            ActivityResultBus.getInstance().register(mActivityResultSubscriber);
        }
    
        @Override
        public void onStop() {
            super.onStop();
            ActivityResultBus.getInstance().unregister(mActivityResultSubscriber);
        }
    
        private Object mActivityResultSubscriber = new Object() {
            @Subscribe
            public void onActivityResultReceived(ActivityResultEvent event) {
                int requestCode = event.getRequestCode();
                int resultCode = event.getResultCode();
                Intent data = event.getData();
                onActivityResult(requestCode, resultCode, data);
            }
        };
     @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            // Don't forget to check requestCode before continuing your job
            if (requestCode == 12345) {
                // Do your job
                tvResult.setText("Result Code = " + resultCode);
            }
        }
        ...
    
    }
    

    hope this code help any one face this problem