每个程序都会随着时间的推移更新新的版本,下面来介绍一下检测到新的版本并提示更新
思路:首先检测当前版本是否是最近版本,是无需任何操作,不是,就需要下载新的程序版本替换旧版本,并安装(大概就是这么个思路,下面就是具体的操作)
package cn.xu.test;import android.app.Dialog;import android.app.ProgressDialog;import android.content.Intent;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import .Uri;import android.os.Build;import android.os.Environment;import android.support.v4.content.FileProvider;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.TextView;import android.widget.Toast;import java.io.BufferedInputStream;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import .HttpURLConnection;import .URL;import cn.xu.momDialog;public class UpdateVersionActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_update_version);//实际开发中请求网络,对比服务器上的版本和当前本地上的版本 ,不同的提示版本更新//我本地的版本号是1,我将版本号写3,大于他try {if (3 > getCurrentVersionCode()) {//todo 这里是一个自定义弹出框,我在上一篇文章中有介绍是怎么封装的,不知道怎么写的小伙伴可以看我的上一篇文章在这里我附上上一章的地址/qq_42221857/article/details/100518167new CommomDialog(UpdateVersionActivity.this, R.style.dialog, "这里写提示更新的内容",new CommomDialog.OnCloseListener() {@Overridepublic void onClick(Dialog dialog, boolean confirm) {if (confirm) {dialog.dismiss();//下载apk安装 todo注这里需要换上自己下载apk的地址downLoadApk("这里放下载apk安装包的地址,这个也是后台返回过来的地址");}}}).setTitle("版本更新").show();}} catch (Exception e) {e.printStackTrace();}}/***下载apk*@param url 下载的地址*/protected void downLoadApk(final String url) {//进度条final ProgressDialog pd;pd = new ProgressDialog(this);pd.setProgressNumberFormat("%1d M /%2d M");pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);pd.setMessage("正在下载更新");pd.setCanceledOnTouchOutside(false);pd.setCancelable(true);//todo 点击返回取消pd.show();new Thread() {@Overridepublic void run() {try {File file = getFileFromServer(url, pd);//安装APKinstallApk(file);pd.dismiss(); //结束掉进度条对话框} catch (Exception e) {}}}.start();}/*** 下载apk具体操作** @param path 下载的地址* @param pd 下载进度条* @return* @throws Exception*/public static File getFileFromServer(String path, ProgressDialog pd) throws Exception {//如果相等的话表示当前的sdcard挂载在手机上并且是可用的if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(5000);//获取到文件的大小pd.setMax(conn.getContentLength() / 1024 / 1024);InputStream is = conn.getInputStream();File file = new File(Environment.getExternalStorageDirectory(), "soujianzhu.apk");FileOutputStream fos = new FileOutputStream(file);BufferedInputStream bis = new BufferedInputStream(is);byte[] buffer = new byte[1024];int len;int total = 0;while ((len = bis.read(buffer)) != -1) {fos.write(buffer, 0, len);total += len;//获取当前下载量pd.setProgress(total / 1024 / 1024);}fos.close();bis.close();is.close();return file;} else {return null;}}//安装程序protected void installApk(File file) {if (!file.exists()) {Toast.makeText(this, "下载的安装包不存在", Toast.LENGTH_SHORT).show();return;}//判读版本是否在7.0以上 todo 这里是7.0安装是会出现解析包的错误if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {// todo 在AndroidManifest中的android:authorities值 当前应用的包名:cn.xu.test+FileProvider(数据共享)Uri apkUri = FileProvider.getUriForFile(this,"cn.xu.test.FileProvider", file);Intent install = new Intent(Intent.ACTION_VIEW);install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//添加这一句表示对目标应用临时授权该Uri所代表的文件install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);install.setDataAndType(apkUri, "application/vnd.android.package-archive");this.startActivity(install);} else {Intent install = new Intent(Intent.ACTION_VIEW);install.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);this.startActivity(install);}}/*** 获取当前版本系统的版本号** @return* @throws Exception*/private int getCurrentVersionCode() throws Exception {//获取packagemanager的实例PackageManager packageManager = getPackageManager();//getPackageName()是你当前类的包名,0代表是获取版本信息PackageInfo packageInfo = packageManager.getPackageInfo(getPackageName(), 0);return packageInfo.versionCode;}}
AndroidManifest中的配置
<!-- 7.0安装 --><providerandroid:name="android.support.v4.content.FileProvider"android:authorities="cn.xu.test.FileProvider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /></provider>
在res下创建一个xml文件,在xml文件下创建file_paths.xml文件
<paths><external-pathname="files_root"path="Android/data/cn.soujianzhu/" /><external-pathname="external_storage_root"path="." /></paths>
到这里就基本上完成了,如果安装上还是出现解析包错误的话,就在AndroidManifest加上一下权限
<!-- 8.0手机安装软件 --><uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /><!-- 允许装载和卸载文件系统权限 --><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
好啦,到这里就完成了,我在开发中遇到解析包出现错误就是这么操作的,然后解决了,今天拿出来和大家分享,共同成长!