Siddharthan Asokan Siddharthan Asokan - 5 months ago 35
Android Question

Check if application is installed - Android

I'm trying to install apps from the Google play. I can understand that on opening the google play store url, it opens the google play and when i press the back button, the activity resumes.

Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(appURL));
marketIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
startActivity(marketIntent);


When I went back to the activity, I tried calling this onResume() to check if the app is installed, but i receive an error:

@Override
protected void onResume() {
super.onResume();
boolean installed = false;
while (!installed) {
installed = appInstalledOrNot(APPPACKAGE);
if (installed) {
Toast.makeText(this, "App installed", Toast.LENGTH_SHORT).show();
}
}
}

private boolean appInstalledOrNot(String uri) {
PackageManager pm = getPackageManager();
boolean app_installed = false;
try {
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
app_installed = true;
}
catch (PackageManager.NameNotFoundException e) {
app_installed = false;
}
return app_installed ;
}


The error is as follows:

E/AndroidRuntime(796): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.appinstaller/com.example.appinstaller.MainActivity}: android.content.ActivityNotFoundException:
No Activity found to handle Intent { act=android.intent.action.VIEW dat=market://details?id=com.package.name flg=0x40080000 }


I guess the activity is onPause(). Is there a better way to implement? I'm trying to check if the app has finished installing.

Answer

Try this:

private boolean isPackageInstalled(String packagename, Context context) {
    PackageManager pm = context.getPackageManager();
    try {
        pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
        return true;
    } catch (NameNotFoundException e) {
        return false;
    }
}

It attempts to fetch information about the package whose name you passed in. Failing that, if a NameNotFoundException was thrown, it means that no package with that name is installed, so we return false.


Note: we might want to pass in a PackageManager instead of a Context, so that the method is slightly more flexibly usable. You can now use the method without access to a Context instance, as long as you have a PackageManager instance.

private boolean isPackageInstalled(String packagename, PackageManager packageManager) {
    try {
        packageManager.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
        return true;
    } catch (NameNotFoundException e) {
        return false;
    }
}

Use it like this:

public void someMethod() {
    // ...

    PackageManager pm = context.getPackageManager();
    boolean isInstalled = isPackageInstalled("com.somepackage.name", pm);

    // ...
}

Or maybe

public void someMethod(PackageManager pm) {
    // ...

    boolean isInstalled = isPackageInstalled("com.somepackage.name", pm);

    // ...
}