Intro

I am writing class that provides me current localization only once if its able to, and returns default coordinats if can not do it for any reason. Class will be used in many places so I wanted to make it as simple to implement for others as it can be. So code would look like

LocationFinder locationFinder = new LocationFinder(this);
locationFinder.setLocationResolvedCallback(new LocationFinder.LocationResolvedCallback() {
        @Override
        public void onLocationFound(double latitude, double longitude) {
            Log.e("Activity", latitude + " " + longitude);
        }
    });
locationFinder.findCurrentLocation();

but there is a case when locations settings are turned off, and I have to request user to turn them on.

task.addOnFailureListener(activity, new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            int statusCode = ((ApiException) e).getStatusCode();
            switch (statusCode) {
                case CommonStatusCodes.RESOLUTION_REQUIRED:
                    try {
                        // Show the dialog and check result
                        ResolvableApiException resolvable = (ResolvableApiException) e;
                        resolvable.startResolutionForResult(activity, REQUEST_LOCATION_SETTINGS);
                    } catch (IntentSender.SendIntentException sendEx) {}
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    break;
            }
        }
    });

So now I have to go into activity and @Override onActivityResult(), handle it from activity level which makes my class less independent.

I wrote method that handle result code within my LocationFinder

 public void onActivityResult(int requestCode, int resultCode) {
    if (REQUEST_LOCATION_SETTINGS == requestCode) {
        if (resultCode == Activity.RESULT_OK) {
            requestCurrentLocation();
        } else {
            locationResolvedCallback.onLocationFound(DEFAULT_LAT, DEFAULT_LONG);
        }
    }
}

but I still have to @Override any activity that uses this class and call this method from it.

So my question is.

Why does android architects did not provide onActivityResult(...) callback as they did in case of permissions? So i could handle any request from within a class by just having reference to activity like

activity.onActivityResultCallback(...){///code}

There must be a reason but I may be missing something very obvious.

2

There are 2 answers

0
Brian On

Activities have a lifecycle, and are therefore instantiated in a different way from an ordinary class.

However the functionality you are looking for can be provided by startActivityForResult(Intent). After the started activity is finished or removed from the stack, an intent is passed hack to the calling activity with a bundle you can use to pass back information

0
Bhuvanesh BS On

onActivityResult() called when you start activity for the result from the current Activity.

if you set the onActivityResult callback somewhere else following will happen.

  1. Your fragments which are hosted in the activity can't get onActivityResult callback.
  2. If you call multiple activities for the result you can't get a result properly (in one place).

For your reference see the below code. This will be never executed if you not called super.onActivityResult().

FragmentActivity onActivityResult:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        mFragments.noteStateNotSaved();
        int requestIndex = requestCode>>16;
        if (requestIndex != 0) {
            requestIndex--;
        String who = mPendingFragmentActivityResults.get(requestIndex);
        mPendingFragmentActivityResults.remove(requestIndex);
        if (who == null) {
            Log.w(TAG, "Activity result delivered for unknown Fragment.");
            return;
        }
        Fragment targetFragment = mFragments.findFragmentByWho(who);
        if (targetFragment == null) {
            Log.w(TAG, "Activity result no fragment exists for who: " + who);
        } else {
            targetFragment.onActivityResult(requestCode & 0xffff, resultCode, data);
        }
        return;
    }

Due to this factors android not provided anonymous callback of onActivityResult()

Suggestion: In my case, I have used BroadcastReceiver to get onActivityResult on my class.

Hope it helps:)