Android silent installation implementation

There are many schemes for Android silent installation, such as using ProcessBuilder or Runtime.getRuntime().exec() to run the PM istall command, but this method needs su first, root permission, or reflection to get PackageManager.installPackage(), which is also cumbersome to use. At the same time, system permission needs to be obtained. Above API21, packageinstaller.section can be used to achieve silent installation For installation, the interface also needs to obtain the system permission android.permission.INSTALL_PACKAGES, not to mention, directly code.

 public void install(@NonNull Context context,@NonNull String path) throws Exception {
        File file=new File(path);
        String apkName=path.substring(path.lastIndexOf(File.separator)+1,path.lastIndexOf(".apk"));
		//Get PackageInstaller
		PackageInstaller packageInstaller = context.getPackageManager()
                .getPackageInstaller();
        PackageInstaller.SessionParams params=new PackageInstaller
                .SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
        PackageInstaller.Session session=null;
        OutputStream outputStream=null;
        FileInputStream inputStream=null;
        try {
			//Create Session
            int sessionId = packageInstaller.createSession(params);
			//Open Session
            session=packageInstaller.openSession(sessionId);
			//Get the output stream to write apk to session
            outputStream = session.openWrite(apkName, 0, -1);
            inputStream=new FileInputStream(file);
            byte[] buffer=new byte[4096];
            int n;
			//Read apk file and write session
            while ((n=inputStream.read(buffer))>0){
                outputStream.write(buffer,0,n);
            }
			//You need to close the flow after writing, otherwise the exception "files still open" will be thrown
            inputStream.close();
            inputStream=null;
            outputStream.flush();
            outputStream.close();
            outputStream=null;
			//Configure the intent initiated after the installation is completed, usually to open the activity
            Intent intent=new Intent();
            PendingIntent pendingIntent=PendingIntent.getActivity(mContext,0,intent,0);
            IntentSender intentSender = pendingIntent.getIntentSender();
			//Submit to start installation
            session.commit(intentSender);

        } catch (IOException e) {
            throw new RuntimeException("Couldn't install package", e);
        } catch (RuntimeException e) {
            if (session != null) {
                session.abandon();
            }
            throw e;
        }finally {
            closeStream(inputStream);
            closeStream(outputStream);
        }

    }

The comments have been explained clearly, so we won't explain them much. To get the status of the installation process, you can register the SessionCallback for PackageInataller before creating session

packageInstaller.registerSessionCallback(new PackageInstaller.SessionCallback() {
            @Override
            public void onCreated(int sessionId) {
                
            }

            @Override
            public void onBadgingChanged(int sessionId) {

            }

            @Override
            public void onActiveChanged(int sessionId, boolean active) {

            }

            @Override
            public void onProgressChanged(int sessionId, float progress) {

            }

            @Override
            public void onFinished(int sessionId, boolean success) {

            }
        });

 

Keywords: Session Android

Added by Drebin on Mon, 16 Dec 2019 18:37:57 +0200