Android Lollipop - PackageInstaller.Session commit()
A

2

7

I'm trying to install packages on my device (from a device-owner app that runs on it) only by using the PackageInstaller and PackageManager APIs. I have been looking for examples but couldn't find anything that fit my need.

Here is a sample of my code to install the Facebook app:

PackageManager pm = getPackageManager();
PackageInstaller mPackageInstaller = pm.getPackageInstaller();
PackageInstaller.SessionParams mSessionParams = new PackageInstaller.SessionParams(SessionParams.MODE_FULL_INSTALL);

mSessionParams.setReferrerUri(Uri.parse("file:///mnt/sdcard/Download/Facebook.apk"));
int mSessionId = mPackageInstaller.createSession( mSessionParams );

PackageInstaller.Session mPkgSession = PackageInstaller.openSession(mSessionId);
OutputStream mOStream = mPkgSession.openWrite("com.facebook.katana", 0, -1);
mPkgSession.fsync(mOStream);

I guess, the next function I need to launch is a "commit(IntentSender statusReceiver)".

So Please tell me how to use commit() and especially how to declare a proper IntentSender to install the APK which is stored in /sdcard.

Thanks !!

Aegyptus answered 16/9, 2015 at 12:15 Comment(0)
O
5

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;
}

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());
Oodles answered 14/6, 2016 at 15:10 Comment(6)
can i update a app2 from app1 by using this functionality through OTA(Over The Air) ?Cakewalk
Yes sir. @beginner. In fact, there is an example on github that does the same(testdpc on github).. There is a guide as well.. codelabs.developers.google.com/codelabs/cosu/#0Oodles
The whole code is running without errors..but I could not see the app installed in my device.Remount
@sandeep ? if you run this code, your app will be uninstalled. So its working as expected right? am i missing somethingOodles
I am trying the installPackage method.. I gave admin permission to the app and its a system app now. but this method does not work. there is no app installed.Remount
One the app receives admin permission, it becomes a device owner app, not a system app. I cannot figure out what could be the reason without seeing ur code. Can you post some gist on github? @sandeepOodles
A
1

So after a few days looking for a way to use a IntentSender, I figured out that it is actually contained in a PendingIntent.

Here is a code that can be used:

Intent coucou = new Intent(this, ReceivedCommitActivity.class);
coucou.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

PendingIntent pCoucou = PendingIntent.getActivity(this, 0, coucou,0);
IntentSender mIntentSender = pCoucou.getIntentSender();

mPkgSession.commit(mIntentSender);
Aegyptus answered 18/9, 2015 at 14:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.