Skip to content

Instantly share code, notes, and snippets.

@WanghongLin
Created December 31, 2017 11:46
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save WanghongLin/12eb8c0a6880c6b63dc476a78ef9eb72 to your computer and use it in GitHub Desktop.
Save WanghongLin/12eb8c0a6880c6b63dc476a78ef9eb72 to your computer and use it in GitHub Desktop.
Install split apk
private static void installMultiple(Context context) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
try {
final int sessionId = packageInstaller.createSession(sessionParams);
Log.d(TAG, "installMultiple: sessionId " + sessionId);
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
File[] apks = new File("/data/local/tmp/slices/slices").listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getAbsolutePath().endsWith(".apk");
}
});
for (File apk : apks) {
InputStream inputStream = new FileInputStream(apk);
OutputStream outputStream = session.openWrite(apk.getName(), 0, apk.length());
byte[] buffer = new byte[65536];
int count;
while ((count = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, count);
}
session.fsync(outputStream);
outputStream.close();
inputStream.close();
Log.d(TAG, "installMultiple: write file to session " + sessionId + " " + apk.length());
}
try {
IIntentSender target = new IIntentSender.Stub() {
@Override
public int send(int i, Intent intent, String s, IIntentReceiver iIntentReceiver, String s1) throws RemoteException {
int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE);
Log.d(TAG, "send: status " + status);
return 0;
}
};
session.commit(IntentSender.class.getConstructor(IIntentSender.class).newInstance(target));
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
session.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void installMultipleCmd() {
File[] apks = new File("/data/local/tmp/slices/slices").listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getAbsolutePath().endsWith(".apk");
}
});
long total = 0;
for (File apk : apks) {
total += apk.length();
}
Log.d(TAG, "installMultipleCmd: total apk size " + total);
long sessionID = 0;
try {
Process pmInstallCreateProcess = Runtime.getRuntime().exec("/system/bin/sh\n");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(pmInstallCreateProcess.getOutputStream()));
writer.write("pm install-create\n");
writer.flush();
writer.close();
int ret = pmInstallCreateProcess.waitFor();
Log.d(TAG, "installMultipleCmd: pm install-create return " + ret);
BufferedReader pmCreateReader = new BufferedReader(new InputStreamReader(pmInstallCreateProcess.getInputStream()));
String l;
Pattern sessionIDPattern = Pattern.compile(".*(\\[\\d+\\])");
while ((l = pmCreateReader.readLine()) != null) {
Matcher matcher = sessionIDPattern.matcher(l);
if (matcher.matches()) {
sessionID = Long.parseLong(matcher.group(1));
}
}
Log.d(TAG, "installMultipleCmd: pm install-create sessionID " + sessionID);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
StringBuilder pmInstallWriteBuilder = new StringBuilder();
for (File apk : apks) {
pmInstallWriteBuilder.append("cat " + apk.getAbsolutePath() + " | " +
"pm install-write -S " + apk.length() + " " + sessionID + " " + apk.getName() + " -");
pmInstallWriteBuilder.append("\n");
}
Log.d(TAG, "installMultipleCmd: will perform pm install write \n" + pmInstallWriteBuilder.toString());
try {
Process pmInstallWriteProcess = Runtime.getRuntime().exec("/system/bin/sh\n");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(pmInstallWriteProcess.getOutputStream()));
// writer.write("pm\n");
writer.write(pmInstallWriteBuilder.toString());
writer.flush();
writer.close();
int ret = pmInstallWriteProcess.waitFor();
Log.d(TAG, "installMultipleCmd: pm install-write return " + ret);
checkShouldShowError(ret, pmInstallWriteProcess);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
try {
Process pmInstallCommitProcess = Runtime.getRuntime().exec("/system/bin/sh\n");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(pmInstallCommitProcess.getOutputStream()));
writer.write("pm install-commit " + sessionID);
writer.flush();
writer.close();
int ret = pmInstallCommitProcess.waitFor();
Log.d(TAG, "installMultipleCmd: pm install-commit return " + ret);
checkShouldShowError(ret, pmInstallCommitProcess);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
private static void checkShouldShowError(int ret, Process process) {
if (process != null && ret != 0) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String l;
while ((l = reader.readLine()) != null) {
Log.d(TAG, "checkShouldShowError: " + l);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
@kissonchan
Copy link

hello, does it works?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment