13

Problem when i am calling to enable gps programatically using GoogleApiClient into fragment... My code is..

 final Status status = result.getStatus();
                final LocationSettingsStates state = result.getLocationSettingsStates();
                switch (status.getStatusCode())
                {
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                        getCurrentLocation();
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the user
                        // a dialog.
                        try {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(getActivity(), REQUEST_ID_GPS_PERMISSIONS);
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        break;
                }

and my onActivityResult is

 final Status status = result.getStatus();
                final LocationSettingsStates state = result.getLocationSettingsStates();
                switch (status.getStatusCode())
                {
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                        getCurrentLocation();
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the user
                        // a dialog.
                        try {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(getActivity(), REQUEST_ID_GPS_PERMISSIONS);
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        break;
                }

but my onActicvityResult() not executing in fragment. Where is the problem??? Help me.....Thanks in advance.

Rakesh kushwaha
  • 709
  • 1
  • 10
  • 22
  • Create an onActivityResult in your Activity class of that fragment and put a debugger there an check – Rakshit Nawani Jul 14 '17 at 07:05
  • 1
    if you are starting your activity as **getActivity().startActivityForResult(...)** replace it with **startActivityForResult(...);**. – debugger Jul 14 '17 at 07:09
  • onActivityResult of Activity executed but when i call any function of fragment from activity always context is null – Rakesh kushwaha Jul 14 '17 at 07:12
  • 2
    @SubhechhuKhanal I'm not calling startActivityForResult, i'm calling startResolutionForResult. – Rakesh kushwaha Jul 14 '17 at 07:13
  • if your onActivityResult() of activity is being called, aren't you being able to call onActivityResult() of fragment from onActivityResult() of activity?? fragment.onActivityResult(requestCode, resultCode, data) – debugger Jul 14 '17 at 07:17

7 Answers7

13

Use this Line for Fragment to get result in onActivityResult

startIntentSenderForResult(status.getResolution().getIntentSender(), REQUEST_ID_GPS_PERMISSIONS, null, 0, 0, 0, null);

insted of

 status.startResolutionForResult(getActivity(), REQUEST_ID_GPS_PERMISSIONS);
Nikunj Paradva
  • 15,332
  • 5
  • 54
  • 65
12

As fragments are placed inside activities and their life cycle tightly coupled to the life cycle of the containing activity.

1) In Activity:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Fragment frg = getSupportFragmentManager().findFragmentById(R.id.fragment_container_main);
    if (frg != null) {
        frg.onActivityResult(requestCode, resultCode, data);
    }
}

Now container activity of fragment will provide intent data, request code and result to the fragment so to get data and result in fragment you have to override onActivityResult(int requestCode, int resultCode, Intent data) in fragment as well

2) In Fragment

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

}

there you will get callback from your parent activity.Do whatever you want to send or to get callback.

yashkal
  • 713
  • 5
  • 20
  • Save my time. Tq. – Shanmugavel GK Nov 09 '17 at 08:46
  • 35
    This is a good answer but the most accurate would be to replace the `status.startResolutionForResult(getActivity(), REQUEST_ID_GPS_PERMISSIONS);` in your fragment for `this.startIntentSenderForResult(status.getResolution().getIntentSender(), REQUEST_ID_GPS_PERMISSIONS, null, 0, 0, 0, null);`. That way you will not have to put an onActivityResult in your activity and your fragment would get the result directly – Jose Jet Jul 20 '18 at 11:30
  • @JoseJet Brilliant. If you had written yours as answer I'd upvote it. – shayan Sep 02 '18 at 20:31
  • @JoseJet This is what exactly I were looking. Thank a ton! – Chintan Soni Nov 13 '18 at 14:26
  • @JoseJet Your comment saved my day! Thanks a lot. It worked like a charm! – Birju Vachhani Nov 13 '18 at 14:26
12

When you need to resolve the Status or the ResolvableApiException, I suggest you to leverage the activity.registerForActivityResult API in place of startResolutionForResult:

val launcher = activity.registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            // User accepted
        } else {
            // User didn't accepted
        }
    }

val intentSenderRequest = IntentSenderRequest.Builder(exception.resolution).build()
launcher.launch(intentSenderRequest)
gianlucaparadise
  • 1,678
  • 20
  • 32
3

I just finished writing some of this same code today. You're on the right track with needing the onActivityForResult() method implemented, but unfortunately startResolutionForResult() doesn't call back to the fragment; it calls back to the activity that contains the fragment.

You must implement onActivityResult() in the calling activity (or wherever your fragments are being managed), and then forward that result to your fragment.

I did something like this in my activities onActivityResult (FragmentBase is just the base class I'm using for all my other fragments, make sure you tag your fragments when you add them):

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data){
        switch (requestCode){
            case LocationHelper.LOCATION_ENABLER_ID:
                FragmentBase mapFrag = (FragmentBase) fragmentManager.findFragmentByTag(FragmentBase.MAP_FRAGMENT);
                ((FragmentMap)mapFrag).returnFromSettings();
                break;
            default:
                super.onActivityResult(requestCode, resultCode, data);
        }
    }
swerly
  • 2,015
  • 1
  • 14
  • 14
2

Solution for 2019 [Kotlin] [AndroidX]

1. In Your Fragment:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    Log.d(context!!, "onActivityResult: [From Fragment]: " + requestCode + ", " + resultCode)
}

2. In Your Activity:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    Log.d(this, "onActivityResult: [From Activity]:  " + requestCode + ", " + resultCode)
    val navHostFragment = supportFragmentManager.fragments.first() as? NavHostFragment
    if(navHostFragment != null) {
        val childFragments = navHostFragment.childFragmentManager.fragments
        childFragments.forEach { fragment ->
            fragment.onActivityResult(requestCode, resultCode, data)
        }
    }
}

This will work if you're using Android Navigation Component.

Shariful Islam Mubin
  • 2,146
  • 14
  • 23
1

Follow the below steps :

1 . InActivity :

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        YourFragment fragment = (YourFragment ) getSupportFragmentManager().findFragmentByTag("TAG_NAME");
        if (fragment != null) {
            fragment .onActivityResult(requestCode, resultCode, data);
        }

    }
  1. In Fragment

     @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
     {
     // Now in fragment will triggger Here you can do work
    
    }
    
Rajasekhar
  • 2,345
  • 1
  • 13
  • 20
0

If you are running this code in Fragment than don't use startResolutionForResult(). Instead use startIntentSenderForResult(status.getResolution().getIntentSender(), REQUEST_CODE_LOCATION_SETTING, null, 0, 0, 0, null);

and overrider onaActivityResult() in your fragment. Result will be delivered to this method only.