Interacting with component within same application and component contributed by other application is made possible with the use of intent. Android supports Explicit (define the component to be called by using java class as identifier) and Implicit intents (define components by action). Using implicit intents, android system identify components of the intents, presenting a list to the user to select a preferred component to use or just launch the intent if the list is of 1 item.

These component list differs from one system to another (because of varieties of application installed on the user’s device). The system only fetches component that supports the action provided when calling the intents.

Example

To get components that support opening web page (browsers preferably) use :

Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com"));
startActivity(i);

Libraries like android-intents are there to make it easier to access frequently used ones. However, you might want to alter this list or perform certain operations. I have broken down the common operations into :

  • Merging
  • Categorising
  • Appending
  • Ignore
  • LookUp
  • Preference
  • Target

Note
This list is in no definite order

You can see some of these examples in apps like whatsapp.

Drawing

Operation Use Cases.

Merging

Merging here means being able to merge components from different actions. So assuming you need an image to complete an operation,you might want to complete this action by picking an image with the help of gallery intent. But you might also want give the user the option of taking a selfie by using the camera. This involves pulling apps from the device that supports both action. There are so many use-cases of this and most times, you wish you can just merge different components and present to the user in 1 dialog.

Categorising

This is mainly for better presentation when more than one intent components is merged or just giving extra information about intents component.

Appending

The whatsapp image example shows how the save to gallery action was added to the list of components that supports image action. Appending means being able to add explicit intent to the list.

Ignore

Well, for some reason, you might want to ignore a particular component or components that matches a naming pattern from the list presented by the system.

LookUp

Lookup is more like a search through the list of components returned by the android system. You might want search for a particular component on the list and only present those to the use. There are several questions of stackoverflow on achieving this.

Preference

There are times you want certain component to be on top of the list or even arrange the components in a certain order. This is what I mean by preference. Considering preferred components aboved others

Target

Target is more like a lookUp, except that it only look for one component. So assuming you only want to complete sending an image with whatsapp. You know, using the image intent might return more than one component. Target in this scenerio means been able to fetch only whatsapp from the component list and continue with your action

IntentManip - My Approach

Having considered those possible operations, I came up Intent Manip. A simple lightweight library based on android-intents (saves you from writing the same intent creation code again) and Bottom Sheet ( to present redefined components to a user is with bottom sheets.

More about the library: more details on including this library and using it can be found on the github page. Let’s take a look on how to achieve all I have said with code.

Merging Intents
private void runMerge() {
        List<ResolveIntent> resolveIntentList = mergeIntents(this, MediaIntents.newSelectPictureIntent(), GeoIntents.newNavigationIntent(""));
        LaunchIntent.withButtomSheetAsList(this, resolveIntentList, "launch using", new ResolvedIntentListener<ResolveIntent>() {
            @Override
            public void onIntentSelected(ResolveIntent resolveIntent) {


            startActivity(ManipUtils.getLaunchableIntent(resolveIntent));

            }
        });
    }

Yes, merging more than one intent is as easy as that. As you can see, there is an onIntentSelected callback. This is called when the user selects as item from the list presented. To launch the intent selected,

ManipUtils.getLaunchableIntent(resolveIntent); .

This returns the intent that is launchable by the android system.

okei! Now that we know how to getLaunchableIntents, let take a look at snippet on implementing other operations.

Categorising Intents
private void categorised() {
        ResolveCategory pixResolveCategory = CategorisedIntent.categorized(this, MediaIntents.newSelectPictureIntent(), "picture", 1);
        List<ResolveIntent> merge = new MergeIntent().mergeIntents(this, MediaIntents.newSelectPictureIntent(), GeoIntents.newNavigationIntent(""));
        ResolveCategory mergeResolveCategory = CategorisedIntent.categorized(merge, "Geo and Media", 2);
        List<ResolveCategory> resolveCategories = new ArrayList<>();
        resolveCategories.add(pixResolveCategory);
        resolveCategories.add(mergeResolveCategory);
        LaunchIntent.categorised(this, resolveCategories, "Share With", new ResolvedIntentListener<ResolveIntent>() {
            @Override
            public void onIntentSelected(ResolveIntent resolveIntent) {
                startActivity(ManipUtils.getLaunchableIntent(resolveIntent));
            }
        });
    }
Appending Explicit Intents
    private void appendIntent() {
        PreparedIntent preparedIntent = new PreparedIntent(new Intent(this, Sample.class), R.string.sample, R.mipmap.ic_launcher);
        List<ResolveIntent> resolveIntentList = IntentAppend.appendCustomIntent(this, MediaIntents.newSelectPictureIntent(), preparedIntent);
        LaunchIntent.withButtomSheetAsList(this, resolveIntentList, "launch using", new ResolvedIntentListener<ResolveIntent>() {
            @Override
            public void onIntentSelected(ResolveIntent resolveIntent) {
                startActivity(ManipUtils.getLaunchableIntent(resolveIntent));
            }
        });
    }
Ignoring Components
    private void ignore() {
        List<ResolveIntent> resolveIntentList = mergeIntents(this, MediaIntents.newSelectPictureIntent(), GeoIntents.newNavigationIntent(""));
        IntentIgnore.IgnoreIntentWithName(this, resolveIntentList, new ArrayList<String>(Arrays.asList(new String[]{"Maps"})));
        LaunchIntent.withButtomSheetAsList(this, resolveIntentList, "launch using", new ResolvedIntentListener() {
            @Override
            public void onIntentSelected(Object resolveIntent) {

            }
        });
    }
Looking Up Components
    private void lookUp() {
        List<ResolveIntent> resolveIntentList = mergeIntents(this, MediaIntents.newSelectPictureIntent(), GeoIntents.newNavigationIntent(""));
        IntentLookUp.lookUpAppsByAppName(this, resolveIntentList, "Maps");
        LaunchIntent.withButtomSheetAsList(this, resolveIntentList, "launch using", new ResolvedIntentListener() {
            @Override
            public void onIntentSelected(Object resolveIntent) {

            }
        });
    }
Preferences Among Components
    private void arrangeInPreference() {
        List<ResolveIntent> resolveIntentList = mergeIntents(this, MediaIntents.newSelectPictureIntent(), GeoIntents.newNavigationIntent(""));
        PreferenceIntent.preferredIntent(this, PreferenceType.CUSTOM_APPNAME, new ArrayList<String>(Arrays.asList(new String[]{"Maps"})), resolveIntentList);
        LaunchIntent.withButtomSheetAsList(this, resolveIntentList, "launch using", new ResolvedIntentListener() {
            @Override
            public void onIntentSelected(Object resolveIntent) {

            }
        });
    }
Targeting a Component
    private void target() {
        List<ResolveIntent> resolveIntentList = mergeIntents(this, MediaIntents.newSelectPictureIntent(), GeoIntents.newNavigationIntent(""));
        ResolveIntent resolveIntent = TargetIntent.targetByAppName(this, resolveIntentList, "Photo");
        if (resolveIntent != null) {
            startActivity(ManipUtils.getLaunchableIntent(resolveIntent));
        }

    }

Okei… What should you expect running those snipet?

Something similar to the video below:

Wrapping Up

Note
There are so much that can still be done with the library.
Get on the Github Page for more information
Contributions are welcome and I am looking forward to seeing interest on how best this can be.

I would love to know if this article helped anyone and I honestly want to see wonderful stuff it helped you churn out.
Thanks.
Belvi - I Beliv