Multi-Window Simple Examples: Part 3 – Launching another app
Introduction
This is the last part of the series about Multi-Window simple examples. And it’s indeed very simple. This time, we will focus on launching another application from our app. The point is that this new application will not replace our app on the screen but will be displayed next to it or below it. There is only one condition to meet – we have to be in split-screen mode.
Just one more flag
To simplify this example to the maximum we explicitly tell MultiWindowCatch app to open MultiWindowDropAdjacent app after clicking on some Pokemon.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class MainActivity extends AppCompatActivity implements MainView, Adapter.OnClickListener { @BindView(R.id.recyclerview) RecyclerView mRecyclerView; private MainPresenter mPresenter; private Adapter mAdapter; //... @Override public void onPokemonClick(final String pokemonId) { mPresenter.onPokemonClick(pokemonId); } @Override public void showAppWithPokemonDetails(final String pokemonId) { Intent intent = getPackageManager().getLaunchIntentForPackage("com.example.makor.multiwindowsdropadjacent"); if (intent == null) { return; } intent.putExtra(PokemonConstants.POKEMON_ID, pokemonId); intent.addCategory(Intent.CATEGORY_LAUNCHER); intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); } } |
1 2 3 4 5 6 | public class MainPresenter { //... public void onPokemonClick(final String pokemonId) { mMainView.showAppWithPokemonDetails(pokemonId); } } |
The result of sending that kind of Intent is to open the Launcher Activity of the app as we pointed out by passing the full package name to PackageManager.getLaunchIntentForPackage() method that will create this Intent for us. You can, of course, use different, more sophisticated way to open another app and you can read about it in Allowing Other Apps to Start Your Activity.
Take a look at flags that we pass. Especially at Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT. By passing this flag, we just say to Android system: “If it’s possible, please open this app next to me or below me, but if it’s not, just show it instead of me.”
The last thing that left is to get that Intent in MultiWindowDropAdjacent app and show selected Pokémon.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | public class MainActivity extends AppCompatActivity implements MainView { //... @Override protected void onCreate(Bundle savedInstanceState) { //... checkIfAdjacentAndShowDetails(); } @Override protected void onStart() { super.onStart(); mPresenter.setView(this); } @Override protected void onStop() { super.onStop(); mPresenter.clearView(); } private void checkIfAdjacentAndShowDetails() { final Bundle extras = getIntent().getExtras(); if (extras != null) { mPresenter.onPokemonIdFromAdjacent(extras.getString(PokemonConstants.POKEMON_ID)); } } @Override public void loadPokemonImage(final String pokemonImageUrl) { Picasso.with(this).load(pokemonImageUrl).fit().centerCrop().into(mImagePokemon, new Callback() { @Override public void onSuccess() { mPresenter.onPokemonImageLoaded(); } @Override public void onError() { Log.d("loadPokemonImage", "onError()"); } }); } @Override public void showPokemonImage() { mProgressBar.setVisibility(View.INVISIBLE); mImagePokemon.setVisibility(View.VISIBLE); } @Override public void showProgressBar() { mProgressBar.setVisibility(View.VISIBLE); mImagePokemon.setVisibility(View.INVISIBLE); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public class MainPresenter { private MainView mMainView = new MainView.Empty(); private int currentPokemonId = 1; public void setView(final MainView mainView) { mMainView = mainView; loadPokemonImage(); } private void loadPokemonImage() { mMainView.showProgressBar(); mMainView.loadPokemonImage(PokemonUrlCreator.createImageUrl(currentPokemonId)); } public void clearView() { mMainView = new MainView.Empty(); } public void onPokemonIdFromAdjacent(final String pokemonId) { currentPokemonId = Integer.parseInt(pokemonId); } public void onPokemonImageLoaded() { mMainView.showPokemonImage(); } } |
1 2 3 4 5 6 | public class PokemonUrlCreator { public static String createImageUrl(final int pokemonId) { return "http://pokeapi.co/media/sprites/pokemon/" + pokemonId + ".png"; } } |
As you can see we simply get the Extras, set current Pokémon id, wait for Activity.onStart() method and show the image.
Summary
Launching another app in Multi-Window mode comes down to adding one more flag to Intent object. We are able to start another app in a couple of ways and it’s up to us how we will handle it.
My complete two projects can be found in MultiWindowCatch and MultiWindowDropAdjacent repositories
Ready to take your business to the next level with a digital product?
We'll be with you every step of the way, from idea to launch and beyond!
Thanks