How to install/update/remove APK using "PackageInstaller" class in Android L? How to install/update/remove APK using "PackageInstaller" class in Android L? android android

How to install/update/remove APK using "PackageInstaller" class in Android L?


It is possible without System permissions from Android M onwards.

if ((mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)        == PackageManager.PERMISSION_GRANTED)        || (installerUid == Process.ROOT_UID)        || mIsInstallerDeviceOwner) {    mPermissionsAccepted = true;} else {    mPermissionsAccepted = false;}

Silent install and uninstall of apps by Device Owner:

A Device Owner can now silently install and uninstall applications using the PackageInstaller APIs, independent of Google Play for Work.

More in this link.


This is possible from Android 6.0 and up.

  • Make your app the Device owner.

Once your app gets the Device owner permission, we can install, uninstall and update silently without any user intervention.

public static boolean installPackage(Context context, InputStream in, String packageName)        throws IOException {    PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();    PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(            PackageInstaller.SessionParams.MODE_FULL_INSTALL);    params.setAppPackageName(packageName);    // set params    int sessionId = packageInstaller.createSession(params);    PackageInstaller.Session session = packageInstaller.openSession(sessionId);    OutputStream out = session.openWrite("COSU", 0, -1);    byte[] buffer = new byte[65536];    int c;    while ((c = in.read(buffer)) != -1) {        out.write(buffer, 0, c);    }    session.fsync(out);    in.close();    out.close();    session.commit(createIntentSender(context, sessionId));    return true;}private static IntentSender createIntentSender(Context context, int sessionId) {        PendingIntent pendingIntent = PendingIntent.getBroadcast(                context,                sessionId,                new Intent(ACTION_INSTALL_COMPLETE),                0);        return pendingIntent.getIntentSender();    }

Uninstall:

String appPackage = "com.your.app.package";Intent intent = new Intent(getActivity(), getActivity().getClass());PendingIntent sender = PendingIntent.getActivity(getActivity(), 0, intent, 0);PackageInstaller mPackageInstaller = getActivity().getPackageManager().getPackageInstaller();mPackageInstaller.uninstall(appPackage, sender.getIntentSender());

Git repo here.


You cannot silently install a third party application in the newly created user with PackageInstaller.Session.commit() without specific "rights".
You either need :

  • the INSTALL_PACKAGES permission. But this permission is not available for third-party application. So even with your profile owner app, you won't have this specific permission.
  • Run the process as ROOT_UID. Which means you'll have to root the device.

From the Android source code:

if ((mPm.checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid) == PackageManager.PERMISSION_GRANTED)    || (installerUid == Process.ROOT_UID)) {    mPermissionsAccepted = true;} else {    mPermissionsAccepted = false;}

If you neither have root access and the INSTALL_PACKAGES permission, then a message will be prompted to the user to ask if he confirms the permissions. This confirmation is then used during the commit process of the PackageInstaller's session. Obviously, in this case, this is not transparent, since the user will have to manually confirm the installation of your apps.


The install method @amalBit provided did not work for me. It's strange since this is how it is implemented in the Google Sample.

This answer helped me to find a solution. I had to change some parts of the code. Here is my implementation:

public static void installPackage(Context context, InputStream inputStream)        throws IOException {    PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();    int sessionId = packageInstaller.createSession(new PackageInstaller            .SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL));    PackageInstaller.Session session = packageInstaller.openSession(sessionId);    long sizeBytes = 0;    OutputStream out = null;    out = session.openWrite("my_app_session", 0, sizeBytes);    int total = 0;    byte[] buffer = new byte[65536];    int c;    while ((c = inputStream.read(buffer)) != -1) {        total += c;        out.write(buffer, 0, c);    }    session.fsync(out);    inputStream.close();    out.close();    // fake intent    IntentSender statusReceiver = null;    Intent intent = new Intent(context, SomeActivity.class);    PendingIntent pendingIntent = PendingIntent.getBroadcast(context,            1337111117, intent, PendingIntent.FLAG_UPDATE_CURRENT);    session.commit(pendingIntent.getIntentSender());    session.close();}

This method can be called like this:

        InputStream inputStream = getActivity().getAssets().open("my_awesome_app.apk");        InstallationHelper.installPackage(getActivity(), inputStream);