Search code examples
androidandroid-activityandroid-intentresolve

issue with resolving activity for an intent - resolveActivityInfo()


I am using resolveActivityInfo to determine if my app was set as a home launcher:

    PackageManager pm = getPackageManager();

    Intent intent = new Intent(Intent.ACTION_MAIN, null);
    intent.addCategory(Intent.CATEGORY_HOME);   

    userHomePackage = intent.resolveActivityInfo(pm, 0).packageName;
    userHomeActivityClass = intent.resolveActivityInfo(pm, 0).name;     
currentHomeLauncherName = intent.resolveActivityInfo(pm, 0).loadLabel(pm).toString();

it works great on emulator and three android devices I have on hands.

Recently I started getting error reports from my users and error log shows that resolveActivityInfo is failing. This happens only on a few phones running on android 2.1 update 1 as I can see. I've received already many positive comments on my app and a few negative because of this issue.

Any advice what could be wrong?

java.lang.NullPointerException
    at android.os.Parcel.readException(Parcel.java:1224)
    at android.os.Parcel.readException(Parcel.java:1206)
    at android.content.pm.IPackageManager$Stub$Proxy.resolveIntent(IPackageManager.java:1418)
    at android.app.ApplicationContext$ApplicationPackageManager.resolveActivity(ApplicationContext.java:2046)
    at android.content.Intent.resolveActivityInfo(Intent.java:3790)
    at com.myapp.myappname.Launcher.setAsHomeApplicationBeforeFroyo(Launcher.java:336)

OR

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.myappname/com.myapp.myappname.Launcher}: java.lang.NullPointerException
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2497)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2513)
    at android.app.ActivityThread.access$2200(ActivityThread.java:119)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1864)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:4370)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
    at android.os.Parcel.readException(Parcel.java:1224)
    at android.os.Parcel.readException(Parcel.java:1206)
    at android.content.pm.IPackageManager$Stub$Proxy.resolveIntent(IPackageManager.java:1418)
    at android.app.ApplicationContext$ApplicationPackageManager.resolveActivity(ApplicationContext.java:2046)
    at android.content.Intent.resolveActivityInfo(Intent.java:3790)
    at com.myapp.myappname.Launcher.showHomeChooserDialog(Launcher.java:141)
    at com.myapp.myappname.Launcher.showNextActivity(Launcher.java:122)
    at com.myapp.myappname.Launcher.onCreate(Launcher.java:59)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2460)
    ... 11 more
java.lang.NullPointerException
    at android.os.Parcel.readException(Parcel.java:1224)
    at android.os.Parcel.readException(Parcel.java:1206)
    at android.content.pm.IPackageManager$Stub$Proxy.resolveIntent(IPackageManager.java:1418)
    at android.app.ApplicationContext$ApplicationPackageManager.resolveActivity(ApplicationContext.java:2046)
    at android.content.Intent.resolveActivityInfo(Intent.java:3790)
    at com.myapp.myappname.Launcher.showHomeChooserDialog(Launcher.java:141)

Solution

  • did some research with android source and i tend to agree now with Commonsware that my code is right. I actually redesigned it 3 weeks ago to use packagemanager.resolveActivity instead of intent.resolveactivity:

    this.pm = context.getPackageManager();
    
        try {
            Intent homeintent = new Intent(Intent.ACTION_MAIN);
            homeintent.addCategory(Intent.CATEGORY_HOME);
            homeintent.addCategory(Intent.CATEGORY_DEFAULT);// seems not needed here since This is a synonym for
                                    // including
            // the CATEGORY_DEFAULT in your supplied Intent per doc
    
            this.resolveInfo = pm.resolveActivity(homeintent, PackageManager.MATCH_DEFAULT_ONLY);
    
            ActivityInfo activityInfo = resolveInfo.activityInfo;
    
            userHomeLauncherPackage = activityInfo.packageName;
            userHomeLauncherClass = activityInfo.name;
    
            userHomeLauncherName = activityInfo.loadLabel(pm).toString();
    
            if (userHomeLauncherClass.contains("ResolverActivity"))
            userHomeLauncherName = "";
    
        } catch (Exception e) {
            throw new Exception(e);
        }
    

    It did not help so still getting these errors occasionally...

    Based on the source code,

    ComponentName Intent.resolveActivity (PackageManager pm)

    or

    ActivityInfo Intent.resolveActivityInfo (PackageManager pm, int flags)

    call the same method defined in android.app.ContextImpl class:

    ResolveInfo info = pm.resolveActivity(this, PackageManager.MATCH_DEFAULT_ONLY)

    and it is defined like:

            @Override
        public ResolveInfo resolveActivity(Intent intent, int flags) {
            try {
                return mPM.resolveIntent(
                    intent,
                    intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                    flags);
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }
    

    so at this point i came to conclusion that I cannot do anything about this :(