4

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?

Nelson Osacky
  • 599
  • 2
  • 12

1 Answers1

9

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.

Laimiux
  • 533
  • 5
  • 13
rjrjr
  • 3,892
  • 1
  • 22
  • 18
  • Since SomePresenters extends Presenter, how do you override the protected abstract BundleService extractBundleService(V view); – Laimiux Jun 17 '15 at 16:39
  • I ended up implementing something similar to how HandlesBack is implemented – Markymark Aug 25 '15 at 05:32