Search code examples
androidmortar

How to handle onActivityResult() with Mortar


I am looking to integrate an application with Google Play Services and Mortar to retrieve the user's current location.

https://developer.android.com/training/location/retrieve-current.html#CheckServices

This requires handling onActivityResult() in the case that Google Play Services is not available.

My first instinct on how to do this is to make getFirstScreen() in Main.java return a blank loading screen. https://github.com/square/mortar/blob/master/mortar-sample/src/main/java/com/example/mortar/core/Main.java

After injection, during onCreate() perform the check to see if Google Play Services is available. If it is, then call flow.goTo(<location using screen>), if not, do nothing and wait for onActivityResult() to be called. Then, when onActivityResult() fires, simply call flow.goTo(<location using screen>).

The above seems slightly hacky to me. (Let me know if you need clarification). So I'm thinking the other solution might be to do something similar to this Mortar + Flow with third party libraries hooked to activity lifecycle and hook up onActivityResult() to the presenter. The problem with this is that I won't have access to the Activity from a presenter which makes it impossible to call GooglePlayServicesUtil.getErrorDialog(...) because it requires Activity.

I think onActivityResult() is very important. Perhaps it should be a part of the Mortar library?


Solution

  • Here's how we generally deal with startActivityForResult in Square Register.

    public SomePresenter extends Presenter<SomePresenter.Activity> {
      public interface Activity {
        void startActivityForResult(android.content.Intent intent, int requestCode);
      }
    
      public final void onActivityResult(int requestCode, int resultCode, Intent data) {
        // Make sure it's the expected requestCode and resultCode and do your thing.
        // If it isn't, no-op, someone else will handle it.
      }
    }
    

    And the activity looks something like:

    public MyActivity extends Activity implements SomePresenter.Activity {
    
    
      @Override protected void onCreate(Bundle bundle) {
        // Do the usual mortar init stuff
    
        somePresenter.takeView(this);
      }
    
      @Override protected void onActivityResult(int requestCode, int   resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        somePresenter.onActivityResult(requestCode, resultCode, data);
      }
    
      @Override protected void onDestroy() {
        somePresenter.dropView(this);
        super.onDestroy();
      }
    }
    

    That doesn't help you with the error dialog, but that sounds like a separate concern to me anyway. Seems like you can use a Popup / PopupPresenter pair there. (I'm not thrilled with Popup, but it gets the job done until we have a better idea.) Or maybe the activity should just go ahead and deal with it itself? I'm not super familiar with the Play Services, haven't dealt with them yet.