3

Android new version - "Lollipop" (API 21) brings quite a few changes with it, but it comes with some price if you wish to target your app to that API.

When we started adapting our apps to the new API, one of the first problems we've encountered is the IllegalArgumentException: Service Intent must be explicit

If you have encountered the problem, and you are actually intending to use your intent in explicit way (meaning that when starting the service you are expecting to hit exactly 1 service action), here's a quick fix for turning implicit --> explicit:

public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
        // Retrieve all services that can match the given intent
        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);

        // Make sure only one match was found
        if (resolveInfo == null || resolveInfo.size() != 1) {
            return null;
        }

        // Get component info and create ComponentName
        ResolveInfo serviceInfo = resolveInfo.get(0);
        String packageName = serviceInfo.serviceInfo.packageName;
        String className = serviceInfo.serviceInfo.name;
        ComponentName component = new ComponentName(packageName, className);

        // Create a new intent. Use the old one for extras and such reuse
        Intent explicitIntent = new Intent(implicitIntent);

        // Set the component to be explicit
        explicitIntent.setComponent(component);

        return explicitIntent;
    }

That should do it. Please feel free to comment for additional insights on this new issue.

sonida
  • 4,411
  • 1
  • 38
  • 40
  • 5
    It's fine to answer your own question. But put the answer in the answer area. – weston Nov 28 '14 at 06:35
  • 1
    The whole point of requiring explicit service intents is to ensure you are actually starting the service you think you are (rather than a malicious service which happens to have the same implicit filter). While this approach fixes the surface issue, it does not solve the underlying issue. In fact, it makes it even harder to debug as your method returns `null` if more than one service exists, meaning your app may just stop working (no service gets started) based on when other apps are installed/uninstalled. – ianhanniballake Nov 28 '14 at 07:20
  • Possible duplicate of [Google In-App billing, IllegalArgumentException: Service Intent must be explicit, after upgrading to Android L Dev Preview](http://stackoverflow.com/questions/24480069/google-in-app-billing-illegalargumentexception-service-intent-must-be-explicit) – regisd Feb 20 '16 at 22:08

1 Answers1

5

Start the service explicitely

intent = new Intent(context, Service.class);

OR explicitly provide the package in an implicit intent

intent = new Intent("com.example.intent.ACTION");
intent.setPackage("com.example")
rds
  • 26,253
  • 19
  • 107
  • 134