Android 9以上,Android静默安装不能再用反射的方法了。改为使用Session。不多说,直接上代码。
private void runInstallSession(Context context, File apkSource) {
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
InputStream is = null;
OutputStream os = null;
boolean succeed = false;
try {
Log.d(TAG, "runInstallSession start");
PackageManager pm = context.getPackageManager();
PackageInstaller packageInstaller = pm.getPackageInstaller();
PackageInfo info = pm.getPackageArchiveInfo(apkSource.getAbsolutePath(),
PackageManager.GET_ACTIVITIES);
Log.d(TAG, "runInstallSession packageName=" + info.packageName);
params.setAppPackageName(info.packageName);
int sessionId = packageInstaller.createSession(params);
byte[] buffer = new byte[65536];
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
is = new FileInputStream(apkSource);
long sizeBytes = apkSource.length();
Log.d(TAG, "runInstallSession sizeBytes=" + String.valueOf(sizeBytes));
os = session.openWrite("PackageInstaller", 0, sizeBytes);
int c = 0;
while ((c = is.read(buffer)) != -1) {
os.write(buffer, 0, c);
}
session.fsync(os);
os.close();
os = null;
Intent intent = new Intent("com.android.preinstall");
intent.putExtra("pkgname", info.packageName);
int index = info.packageName.hashCode();
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, index, intent,
PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT);
session.commit(pendingIntent.getIntentSender());
succeed = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.close();
}
if (is != null) {
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
Log.d(TAG, "runInstallSession " + (succeed?"success":"failed"));
}
}
|