前言:
我们App是定制的Pad,所以已经进行过系统签名,但是静默安装这个操作我找了好久才找到合适的,然后就是代码
首先是Apk下载的方法
// 文件保存路径
private String mSavePath;
// 版本名称
private String mVersion_name = "/名称.apk";
/*
* 开启新线程下载apk文件
*/
private void downloadAPK(String mUrl) {
new Thread(new Runnable() {
@Override
public void run() {
try {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String sdPath = Environment.getExternalStorageDirectory() + "/";
// 文件保存路径
// mSavePath = sdPath + "jikedownload";
mSavePath = "/data/user/0/包名/files";
// mSavePath = "/data/local/tmp/";
File dir = new File(mSavePath);
if (!dir.exists()) {
dir.mkdir();
}
// 下载文件
HttpURLConnection conn = (HttpURLConnection) new URL(mUrl).openConnection();
conn.connect();
InputStream is = conn.getInputStream();
int length = conn.getContentLength();
File apkFile = new File(mSavePath, mVersion_name);
FileOutputStream fos = new FileOutputStream(apkFile);
int count = 0;
byte[] buffer = new byte[1024];
while (!mIsCancel) {
int numread = is.read(buffer);
count += numread;
// 计算进度条的当前位置
mProgress = (int) (((float) count / length) * 100);
Log.e("Base", "下载进度" + mProgress);
// 下载完成
if (numread < 0) {
Log.e("Base", "下载完成");
// mUpdateProgressHandler.sendEmptyMessage(2);
//静默安装
StringBuilder append = new StringBuilder().append(mSavePath).append(mVersion_name);
boolean installResult = Install.silentInstallApk(mContext,append.toString());
Log.e("Base", "安装结果" + installResult);
// break;
}
fos.write(buffer, 0, numread);
}
fos.close();
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
然后就是静默安装的代码
/**
* 静默安装
*/
public class Install {
private final static SynchronousQueue<Intent> mInstallResults = new
SynchronousQueue<>();
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static synchronized boolean silentInstallApk(Context context,
final String apkFilePath) {
boolean ret = false;
File apkFile = new File(apkFilePath);
PackageInstaller installer = context.getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams sessionParams = new
PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
sessionParams.setSize(apkFile.length());
int sessionId = createSession(installer, sessionParams);
if (sessionId != -1) {
boolean isCopyOk = copyInstallApkFile(sessionId, installer, apkFilePath);
if (isCopyOk) {
boolean isInstalled = installPackage(context, sessionId,
installer, apkFilePath);
if (isInstalled) {
ret = true;
}
}
}
return ret;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static int createSession(PackageInstaller installer,
PackageInstaller.SessionParams sessionParams) {
int sessionId = -1;
try {
sessionId = installer.createSession(sessionParams);
} catch (IOException e) {
e.printStackTrace();
}
return sessionId;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static boolean copyInstallApkFile(int sessionId, PackageInstaller installer,
String apkFilePath) {
InputStream in = null;
OutputStream out = null;
PackageInstaller.Session session = null;
boolean ret = false;
try {
File apkFile = new File(apkFilePath);
session = installer.openSession(sessionId);
out = session.openWrite("base.apk", 0, apkFile.length());
in = new FileInputStream(apkFile);
File file = new File(String.valueOf(apkFile));
if (file.exists()) {
Log.i("Base", "存在");
}
int count;
byte[] buffer = new byte[65536];
while ((count = in.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
session.fsync(out);
ret = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
session.close();
}
return ret;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static boolean installPackage(Context context, int sessionId,
PackageInstaller installer, String filePath) {
PackageInstaller.Session session = null;
boolean ret = false;
try {
session = installer.openSession(sessionId);
Intent intent = new Intent();
intent.setAction("com.example.install");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
session.commit(pendingIntent.getIntentSender());
final Intent intentResult = mInstallResults.poll(60, TimeUnit.SECONDS);
//这个地方返回的*intentResult *为null,所以导致代用静默安装方法返回的值为**false**,但是app已经成功静默安装成功了,至于原因
//笔者也暂时没有找到,如果有哪位看官懂,麻烦评论下,感谢
if (intentResult != null) {
final int status = intentResult.getIntExtra(PackageInstaller.EXTRA_STATUS,
PackageInstaller.STATUS_FAILURE);
if (status == PackageInstaller.STATUS_SUCCESS) {
ret = true;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
return ret;
}
}
最后是权限,一定不要忘了
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.BIND_DEVICE_ADMIN" />
这就是全部的代码,有几个点我要声明一下,首先就是放置Apk的地址以及Apk的名字,大家要自行改一下;其次是调用静默安装后的的返回值,其实返回的是 false,但是App确实是静默安装成功的,至于原因我打断点也没找到具体的原因,如果有哪位看官懂,麻烦评论下,感谢。最后,以上便是我根据自己的经验以及参考网上的一些文章得出来的结论,敬请参考