android实现app更新

首先是一个简易的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 block
			e.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 exception
			Log.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 Version
	VersionUpdateUtils(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 stub
			Log.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() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							// TODO Auto-generated method stub
							initProgressDialog();
							downloadNewAPK(versionEntity.apkurl);
						}

						/** 下载APK */
						@SuppressLint("SdCardPath") private void downloadNewAPK(String apkurl) {
							Log.i(TAG, "downloadApkurl:"+apkurl);
							// TODO Auto-generated method stub
							String 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() {

										@Override
										public void onSuccess(
												ResponseInfo<File> arg0) {
											// TODO Auto-generated method stub
											mProgressDialog.dismiss();
											Log.i(TAG, "Dialog关闭");
											MyUtils.installApk(context);
										}

										@Override
										public void onLoadding(long total,
												long current,
												boolean isUploading) {
											// TODO Auto-generated method stub
											mProgressDialog.setMax((int) total);
											mProgressDialog
													.setMessage("正在下载...");
											mProgressDialog
													.setProgress((int) current);
											Log.i(TAG, "onLoadding");
										}

										@Override
										public void onFailure(
												HttpException arg0, String arg1) {
											// TODO Auto-generated method stub
											mProgressDialog.setMessage("下载失败");
											mProgressDialog.dismiss();
											enterHome();
											Log.i(TAG, "onFailure->arg0:"+arg0+" arg1:"+ arg1);
										}
									});

						}

						private void initProgressDialog() {
							// TODO Auto-generated method stub
							Log.i(TAG, "initProgressDialog开始运行");
							mProgressDialog = new ProgressDialog(context);
							mProgressDialog.setMessage("准备下载...");
							mProgressDialog
									.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
							mProgressDialog.show();
						}
					});
			builder.setNegativeButton("暂不升级",
					new DialogInterface.OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							// TODO Auto-generated method stub
							dialog.dismiss();
							enterHome();
						}
					});
			builder.show();

		};
	};

	/*
	 * 获取服务器版本
	 */
	public void getCloudVersion() {
		try {
			new Thread(postThread).start();
		} catch (Exception e) {
			// TODO: handle exception
			e.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 block
							e.printStackTrace();
						}
					}
				}

			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.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>(){

			@Override
			public void onFailure(HttpException arg0, String arg1) {
				// TODO Auto-generated method stub
				myCallBack.onFailure(arg0, arg1);
			}

			@Override
			public void onSuccess(ResponseInfo<File> arg0) {
				// TODO Auto-generated method stub
				myCallBack.onSuccess(arg0);
			}
			
			@Override
			public void onLoading(long total, long current, boolean isUploading) {
				// TODO Auto-generated method stub
				super.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 stub
		mVersionTv = (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(){
			@Override
			public 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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值