Android的APP强制更新
来源:互联网 发布:三层交换机网络拓扑图 编辑:程序博客网 时间:2024/04/27 16:03
这是manager的代码,里面包含软件的下载以及安装流程
package com.sf.manager;import android.app.AlertDialog;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.net.Uri;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.widget.ProgressBar;import android.widget.TextView;import android.widget.Toast;import com.sf.R;import com.sf.MyActivityManager;import com.sf.MyApplication;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;/** * Created by Administrator on 2016/12/20. */public class UpdateManager { private Context mContext; //上下文 private String apkUrl = "**********************"; //apk下载地址 private String savePath; //apk保存到SD卡的路径 private String saveFileName; //完整路径名 private ProgressBar mProgress; //下载进度条控件 private TextView tvProgress; //下载进度条控件 private static final int DOWNLOADING = 1; //表示正在下载 private static final int DOWNLOADED = 2; //下载完毕 private static final int DOWNLOAD_FAILED = 3; //下载失败 private int progress; //下载进度 private boolean cancelFlag = false; //取消下载标志位 private String serverVersion; //从服务器获取的版本号 private String clientVersion; //客户端当前的版本号 private String updateDescription = "*****发现新版本,是否更新"; //更新内容描述信息 private boolean forceUpdate; //是否强制更新 private AlertDialog alertDialog1, alertDialog2; //表示提示对话框、进度条对话框 /** 构造函数 */ public UpdateManager(Context context,String serverVersion,String clientVersion,boolean forceUpdate) { this.mContext = context; this.serverVersion=serverVersion; this.clientVersion=clientVersion; this.forceUpdate=forceUpdate; } /** 显示更新对话框 */ public void showNoticeDialog() { //如果版本最新,则不需要更新 if (serverVersion.equals(clientVersion)) return; AlertDialog.Builder dialog = new AlertDialog.Builder(mContext); dialog.setTitle("发现新版本 :" + serverVersion); dialog.setMessage(updateDescription); dialog.setPositiveButton("现在更新", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { // TODO Auto-generated method stub arg0.dismiss(); showDownloadDialog(); } }); if (forceUpdate == true) { dialog.setNegativeButton("下次更新", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { MyActivityManager.finishAll(); MyApplication.exit(); } }); } //是否强制更新 if (forceUpdate == false) { dialog.setNegativeButton("待会更新", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { // TODO Auto-generated method stub arg0.dismiss(); } }); } alertDialog1 = dialog.create(); alertDialog1.setCancelable(false); alertDialog1.show(); } /** 显示进度条对话框 */ public void showDownloadDialog() { AlertDialog.Builder dialog = new AlertDialog.Builder(mContext); dialog.setTitle("正在更新"); final LayoutInflater inflater = LayoutInflater.from(mContext); View v = inflater.inflate(R.layout.softupdate_progress, null); mProgress = (ProgressBar) v.findViewById(R.id.update_progress); tvProgress = (TextView) v.findViewById(R.id.tv_progress); dialog.setView(v); //如果是强制更新,则不显示取消按钮 if (forceUpdate == false) { dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { // TODO Auto-generated method stub arg0.dismiss(); cancelFlag = false; } }); } alertDialog2 = dialog.create(); alertDialog2.setCancelable(false); alertDialog2.show(); //下载apk downloadAPK(); } /** 下载apk的线程 */ public void downloadAPK() { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { URL url = new URL(apkUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.connect(); int length = conn.getContentLength(); InputStream is = conn.getInputStream(); savePath = getSDPath()+"/updateAPK/"; File file = new File(savePath); if(!file.exists()){ file.mkdir(); } saveFileName = savePath +serverVersion+ "apkName.apk"; String apkFile = saveFileName; File ApkFile = new File(apkFile); FileOutputStream fos = new FileOutputStream(ApkFile); int count = 0; byte buf[] = new byte[1024]; do{ int numread = is.read(buf); count += numread; progress = (int)(((float)count / length) * 100); //更新进度 mHandler.sendEmptyMessage(DOWNLOADING); if(numread <= 0){ //下载完成通知安装 mHandler.sendEmptyMessage(DOWNLOADED); break; } fos.write(buf, 0, numread); }while(!cancelFlag); //点击取消就停止下载. fos.close(); is.close(); } catch(Exception e) { mHandler.sendEmptyMessage(DOWNLOAD_FAILED); e.printStackTrace(); Log.e("eeeeeeeeeee",e.getMessage()); } } }).start(); } /** * 获取SD path * * @return */ public String getSDPath() { File sdDir = null; boolean sdCardExist = Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED); // 判断sd卡是否存在 if (sdCardExist) { sdDir = Environment.getExternalStorageDirectory();// 获取跟目录 // Toast.makeText(this,sdDir.toString(),Toast.LENGTH_LONG).show(); return sdDir.toString(); } else { Toast.makeText(mContext, "没有SD卡", Toast.LENGTH_LONG).show(); } return null; } /** 更新UI的handler */ private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub switch (msg.what) { case DOWNLOADING: mProgress.setProgress(progress); tvProgress.setText(progress+"%"); break; case DOWNLOADED: if (alertDialog2 != null) alertDialog2.dismiss(); installAPK(); break; case DOWNLOAD_FAILED: Toast.makeText(mContext, "网络断开,请稍候再试", Toast.LENGTH_LONG).show(); break; default: break; } } }; /** 下载完成后自动安装apk */ public void installAPK() { File apkFile = new File(saveFileName); if (!apkFile.exists()) { return; } Intent intent = new Intent(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(Uri.parse("file://" + apkFile.toString()), "application/vnd.android.package-archive"); mContext.startActivity(intent); MyActivityManager.finishAll(); MyApplication.exit(); }}
//这是dialog布局代码
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ProgressBar android:id="@+id/update_progress" style="?android:attr/progressBarStyleHorizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/tv_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/update_progress" android:layout_alignParentRight="true" android:layout_margin="5dp" android:textSize="@dimen/app_bigtext" android:text="0%"/></RelativeLayout>
//这是主函数中调取manager的主要方法
if ("获取软件版本code" < "服务器获取的code") { SharedPreferencesUtils.saveBoolean(getApplicationContext(), "AppNew", true); mUpdateManager = new UpdateManager(IndexActivity.this, "服务器获取的版本号", "获取软件的版本号", true); mUpdateManager.showNoticeDialog();} else { SharedPreferencesUtils.saveBoolean(getApplicationContext(), "AppNew", false);}
//获取软件code
private int getAppCode() { try { String pkName = this.getPackageName(); int versionCode = this.getPackageManager().getPackageInfo( pkName, 0).versionCode; return versionCode; } catch (Exception e) { } return -1;}//获取软件版本号private String getAppInfo() { try { String pkName = this.getPackageName(); String versionName = this.getPackageManager().getPackageInfo( pkName, 0).versionName; return versionName; } catch (Exception e) { } return null;}
2 0
- Android的APP强制更新
- App开发:强制更新app
- Android 强制且彻底的退出app
- iOS-app更新和强制更新
- android强制更新APK
- Android更新app的版本
- 如何规避苹果审查,实现app store上的app版本强制更新
- iOS 规避苹果审查,实现app store上的app版本强制更新
- 手机App版本更新(强制更新/选择更新)
- 手机App版本更新(强制更新/选择更新)
- Android应用强制更新策略
- Android Framework学习记录 -- repo的强制更新
- Android检查更新(是否强制更新)
- Android检查更新(是否强制更新)
- android检查更新(强制更新)
- Android app的升级更新,安装,启动
- android中app的更新案例
- Android如何更新app的版本
- 一分钟了解负载均衡的一切
- 内连接、左外连接、右外连接、交叉连接区别
- 如何给FineReport设置自定义消息提醒工具
- Java比较计算日期,日期排序
- 表单高级标签
- Android的APP强制更新
- Grep 搜索内容高亮红色显示输出
- 数据结构经典面试题——练习2
- React中组件的生命周期
- 年末必啃清单!读完让你茅塞顿开!(建议收藏)
- 关于String转换成int类型的java.lang.NumberFormatException: Invalid int
- CI Weekly #8 | CI/CD 技能进阶路线
- 【maven】一个错误
- 浅析Hololens HoloToolkit中Utilities下通用脚本的用法