android实现app更新

来源:互联网 发布:扮猪吃老虎 网游 知乎 编辑:程序博客网 时间:2024/05/17 06:44

首先是一个简易的activity

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"android:background="@android:color/holo_orange_dark" >    <ProgressBar        android:id="@+id/pb_bar"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:translationY="-50dp"        android:layout_marginTop="152dp" />    <TextView        android:id="@+id/tv_editin"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textColor="@android:color/white"        android:layout_centerInParent="true"        android:text="版本:" />    <TextView        android:id="@+id/tv_editin_edit"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textColor="@android:color/white"        android:layout_centerVertical="true"        android:layout_toRightOf="@+id/tv_editin"        android:text="122.1" /></RelativeLayout>

下载与安装的工具类,在这个类中要注意的是intent.addCategory("android.intent.category.DEFAULI");这个方法。有时用它会出现找不到intent的现象,可酌情使用

package cnjoanthan.updata;import java.io.File;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.net.Uri;import android.os.Environment;import android.util.Log;import android.widget.Toast;/* * 2016年8月19日 星期五 * jonathan * 获取版本号和安装apk */public class MyUtils {/* * 获取版本号 * return 版本号 */public static String getVersion(Context context){PackageManager manager = context.getPackageManager();//PackageManager可以获取文件的信息Log.i("VersionUpdateUtils", "manager:" + manager);try {PackageInfo packageInfo = manager.getPackageInfo(context.getPackageName(), 0);Log.i("VersionUpdateUtils", "packageInfo:" + packageInfo);return packageInfo.versionName;} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();Log.i("VersionUpdateUtils", "MyUtilsTryAbnormal :" + e.getMessage());return "";}}/* * 安装新版本 */ public static void installApk(Activity activity){Log.i("VersionUpdateUtils", "install activity:"+activity);try {String path = Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator+"mobilesafe"+File.separator+"mobilesafe.apk";//String path = "/sdcard/mobilesafe/mobilesafe.apk";Intent intent = new Intent();intent.setAction(Intent.ACTION_VIEW);//添加默认分类//intent.addCategory("android.intent.category.DEFAULI");//设置数据类型intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive");/* Uri.fromFile(new File(path))*///Uri.parse("file://"+path)intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);activity.startActivity(intent);//activity.startActivityForResult(intent, 0);} catch (Exception e) {// TODO: handle exceptionLog.i("VersionUpdateUtils", "install Excepyion:"+e.getMessage());}} }

连接下载与解析,其中下载使用了xutile 解析JSONObject都需要jar包

package cnjoanthan.updata;import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.File;import java.io.IOException;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.net.URLEncoder;import org.json.JSONException;import org.json.JSONObject;import android.annotation.SuppressLint;import android.app.Activity;import android.app.AlertDialog;import android.app.ProgressDialog;import android.content.DialogInterface;import android.os.Environment;import android.os.Handler;import android.util.Log;import android.widget.Toast;import cnjoanthan.updata.DownLoadUtils.MyCallBack;import com.lidroid.xutils.exception.HttpException;import com.lidroid.xutils.http.ResponseInfo;/* * 更新更新类 */public class VersionUpdateUtils {private static final String TAG = "VersionUpdateUtils";private static final int MESSAGE_NET_ERROR = 101;private static final int MESSAGE_IO_ERROR = 102;private static final int MESSAGE_JSON_ERROR = 103;private static final int MESSAGE_SHOW_DIALOG = 104;private static final int MESSAGE_ENTERHOME = 105;/* 本地版本号 */private String mVersion;private Activity context;private VersionEntity versionEntity;private ProgressDialog mProgressDialog;// private VersionVersionUpdateUtils(String Version, Activity activity) {mVersion = Version;this.context = activity;Log.i(TAG, "VersionUpdateUtils已重构");}/* 用于更新的UI */private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {Log.i(TAG, "handleMessage启动");switch (msg.what) {case MESSAGE_IO_ERROR:Toast.makeText(context, "IO异常", Toast.LENGTH_SHORT).show();enterHome();break;case MESSAGE_JSON_ERROR:Toast.makeText(context, "JSON异常", Toast.LENGTH_SHORT).show();enterHome();break;case MESSAGE_NET_ERROR:Toast.makeText(context, "网络异常", Toast.LENGTH_SHORT).show();enterHome();break;case MESSAGE_SHOW_DIALOG:Log.i(TAG, "接收到message:"+MESSAGE_SHOW_DIALOG);showUpdateDialog(versionEntity);break;case MESSAGE_ENTERHOME:Toast.makeText(context, "即将跳转", Toast.LENGTH_LONG).show();break;default:break;}}/** * 弹出提示框 *  * @param versionEntity */private void showUpdateDialog(final VersionEntity versionEntity) {// TODO Auto-generated method stubLog.i(TAG, "showUpdateDialog启动构建");/** * 创建dialog */AlertDialog.Builder builder = new AlertDialog.Builder(context);builder.setTitle("检测到新版本:" + versionEntity.versioncode);builder.setMessage(versionEntity.descripting);/** 服务器返回的描述信息 */builder.setCancelable(false);/** 设置手机不能点击返回键 */builder.setPositiveButton("立即升级",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stubinitProgressDialog();downloadNewAPK(versionEntity.apkurl);}/** 下载APK */@SuppressLint("SdCardPath") private void downloadNewAPK(String apkurl) {Log.i(TAG, "downloadApkurl:"+apkurl);// TODO Auto-generated method stubString fileName = Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator+"mobilesafe"+File.separator+"mobilesafe.apk";//getExternalStorageDirectory//String fileName = "/sdcard/mobilesafe/mobilesafe.apk";Log.i(TAG, "fileName:"+fileName);DownLoadUtils dowLoadUtils = new DownLoadUtils();dowLoadUtils.downapk(apkurl,fileName,new MyCallBack() {@Overridepublic void onSuccess(ResponseInfo<File> arg0) {// TODO Auto-generated method stubmProgressDialog.dismiss();Log.i(TAG, "Dialog关闭");MyUtils.installApk(context);}@Overridepublic void onLoadding(long total,long current,boolean isUploading) {// TODO Auto-generated method stubmProgressDialog.setMax((int) total);mProgressDialog.setMessage("正在下载...");mProgressDialog.setProgress((int) current);Log.i(TAG, "onLoadding");}@Overridepublic void onFailure(HttpException arg0, String arg1) {// TODO Auto-generated method stubmProgressDialog.setMessage("下载失败");mProgressDialog.dismiss();enterHome();Log.i(TAG, "onFailure->arg0:"+arg0+" arg1:"+ arg1);}});}private void initProgressDialog() {// TODO Auto-generated method stubLog.i(TAG, "initProgressDialog开始运行");mProgressDialog = new ProgressDialog(context);mProgressDialog.setMessage("准备下载...");mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);mProgressDialog.show();}});builder.setNegativeButton("暂不升级",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stubdialog.dismiss();enterHome();}});builder.show();};};/* * 获取服务器版本 */public void getCloudVersion() {try {new Thread(postThread).start();} catch (Exception e) {// TODO: handle exceptione.printStackTrace();Log.i(TAG, "线程异常:" + e.getMessage());}}private Thread postThread = new Thread() {public void run() {Log.i(TAG, "postThread线程启动");String target = "要提交的服务器的URL";URL url;try {url = new URL(target);HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();urlConn.setRequestMethod("POST");urlConn.setDoInput(true);urlConn.setDoOutput(true);urlConn.setUseCaches(true);// 禁止缓存urlConn.setInstanceFollowRedirects(true);urlConn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");DataOutputStream out = new DataOutputStream(urlConn.getOutputStream());String param = "字段="+ URLEncoder.encode("字段值","UTF-8") + "&" + "第二个字段="+ URLEncoder.encode("字段值", "UTF-8");out.writeBytes(param);out.flush();out.close();if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {InputStreamReader in = new InputStreamReader(urlConn.getInputStream(), "UTF-8");BufferedReader buffer = new BufferedReader(in);String inputLine = null;while ((inputLine = buffer.readLine()) != null) {Log.i(TAG, "inputLine:" + inputLine);try {JSONObject jsonObject = new JSONObject(inputLine);Log.i(TAG,"result_code:"+ jsonObject.getString("result_code"));if ((jsonObject.getString("result_code")).equalsIgnoreCase("2")) {/* 服务器是否返回成功 */JSONObject request = jsonObject.getJSONObject("data");versionEntity = new VersionEntity();String code = request.getString("code");Log.i(TAG, "code:"+code);versionEntity.versioncode = code;String des = request.getString("des");Log.i(TAG, "des:"+des);versionEntity.descripting = des;String apkurl = request.getString("apkurl");Log.i(TAG, "apkurl:"+apkurl);versionEntity.apkurl = apkurl;if (!mVersion.equalsIgnoreCase(versionEntity.versioncode)) {/* 版本号不一致的时候 */handler.sendEmptyMessage(MESSAGE_SHOW_DIALOG);Log.i(TAG, "进入版本不一致模式");} else {enterHome();}}} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}};};/* end */private void enterHome() {handler.sendEmptyMessageDelayed(MESSAGE_ENTERHOME, 2000);}}


下载的工具类

package cnjoanthan.updata;import java.io.File;import com.lidroid.xutils.HttpUtils;import com.lidroid.xutils.exception.HttpException;import com.lidroid.xutils.http.ResponseInfo;import com.lidroid.xutils.http.callback.RequestCallBack;/* * 下载工具类 * jonathan 2016年8月19日 星期五 */public class DownLoadUtils {public void downapk(String url,String targerFile, final MyCallBack myCallBack){//创建HttpUtils对象HttpUtils httpUtils = new HttpUtils();//调用HttpUtils 下载的方法下载指定文件httpUtils.download(url, targerFile,new RequestCallBack<File>(){@Overridepublic void onFailure(HttpException arg0, String arg1) {// TODO Auto-generated method stubmyCallBack.onFailure(arg0, arg1);}@Overridepublic void onSuccess(ResponseInfo<File> arg0) {// TODO Auto-generated method stubmyCallBack.onSuccess(arg0);}@Overridepublic void onLoading(long total, long current, boolean isUploading) {// TODO Auto-generated method stubsuper.onLoading(total, current, isUploading);myCallBack.onLoadding(total, current, isUploading);}});}interface MyCallBack{/* 下载成功时调用*/void onSuccess(ResponseInfo<File> arg0);/*下载失败时调用*/void onFailure(HttpException arg0,String arg1);/*下载中调用*/void onLoadding(long total, long current, boolean isUploading);}}



信息实体

package cnjoanthan.updata;import android.widget.TextView;public class VersionEntity {/* 服务器版本号*/public String versioncode;/*版本描述*/public String descripting;/*apk 下载地址*/public String apkurl;}


主函数

package cnjoanthan.updata;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.Window;import android.widget.TextView;public class MainActivity extends Activity {private String mVersion;//本地版本号private TextView mVersionTv;//应用版本号    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Log.i("VersionUpdateUtils", "正常");        mVersion = MyUtils.getVersion(getApplicationContext());        initView();                    }private void initView() {// TODO Auto-generated method stubmVersionTv = (TextView) findViewById(R.id.tv_editin_edit);mVersionTv.setText(mVersion);Log.i("VersionUpdateUtils", "mVersion:"+mVersion);final VersionUpdateUtils updateUtils = new VersionUpdateUtils(mVersion,MainActivity.this);Log.i("VersionUpdateUtils", "子线程启动");new Thread(){@Overridepublic void run() {// TODO Auto-generated method stub//super.run();Log.i("VersionUpdateUtils", "匿名子线程运行");updateUtils.getCloudVersion();}}.start();}}


manifest


<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="cnjoanthan.updata"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="19"        android:targetSdkVersion="19" />    <uses-permission android:name="android.permission.INTERNET"/>    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />        <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>            </application></manifest>

其中的存储目录是写了一个固定的可更改

0 0