android新版本怎么下载安装,安卓应用检查更新并下载安装

在这篇文章中(参见 android中如何下载文件并显示下载进度  )我们讲到了如何下载文件的问题,今天我介绍如何实现应用的自动更新,其中下载apk模块用到了前一篇文章中的知识。当然这只是一个实现的框架,你需要根据自己的需求是改变一些细节。

自动更新的原理

其实就是客户端将自己的版本号与服务端的版本号进行比对,版本号小于服务端则意味着有新版本,当然服务端的版本号是需要人工放上去的。

先看看效果:

14174237007453.jpg

为了代码的简洁,我这里用原生的alert对话框。

点击下载之后:

141742382644.jpg

下载完成安装的界面我就不张贴了。

使用方法:

很简单,在需要检查更新的地方加入如下代码:updateChecker.setCheckUrl("http://jcodecraeer.com/update.php");

updateChecker.checkForUpdates();

其中http://jcodecraeer.com/update.php返回的是服务器段存放的版本信息。服务端的版本信息分为三部分:

1.版本号;

2.版本描述;

3.存放apk的url(告诉客户端,在哪里下载新版本的apk);

以http://jcodecraeer.com/update.php返回的结果为例,返回的字符串具体是这样的:{"url":"http://www.jcodecraeer.com/***.apk","versionCode":"2","updateMessage":"1.修改了app图标 2.设备详情的显示方式"}

这是一个json格式的字符串。

实现

有三个类:

14174245296366.jpg

其中

AppVersion是版本信息的模型类,基本上和服务端返回的东西是相对应的。

DownloadService是下载模块。

UpdateChecker是检查更新,调用下载模块,下载完安装的工具类。

AppVersionpackage com.jcodecraeer.jcode.update;

public class AppVersion {

private String updateMessage;

private String apkUrl;

private int apkCode;

public static final String APK_DOWNLOAD_URL = "url";

public static final String APK_UPDATE_CONTENT = "updateMessage";

public static final String APK_VERSION_CODE = "versionCode";

public void setUpdateMessage(String updateMessage) {

this.updateMessage = updateMessage;

}

public String getUpdateMessage() {

return updateMessage;

}

public void setApkUrl(String apkUrl) {

this.apkUrl = apkUrl;

}

public String getApkUrl() {

return apkUrl;

}

public void setApkCode(int apkCode) {

this.apkCode = apkCode;

}

public int getApkCode() {

return apkCode;

}

}

DownloadServicepackage com.jcodecraeer.jcode.update;

import java.io.BufferedInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.URL;

import java.net.URLConnection;

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

import org.jsoup.Jsoup;

import org.jsoup.nodes.Document;

import org.jsoup.nodes.Element;

import org.jsoup.select.Elements;

import com.jcodecraeer.PullToRefreshListView;

import android.annotation.SuppressLint;

import android.app.AlertDialog;

import android.app.IntentService;

import android.content.ContentResolver;

import android.content.ContentUris;

import android.content.Context;

import android.content.DialogInterface;

import android.content.Intent;

import android.content.res.TypedArray;

import android.database.Cursor;

import android.graphics.Rect;

import android.graphics.drawable.ColorDrawable;

import android.net.Uri;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.os.ResultReceiver;

import android.provider.ContactsContract;

import android.provider.MediaStore.Images;

import android.provider.MediaStore.Images.ImageColumns;

import android.support.v4.app.Fragment;

import android.util.DisplayMetrics;

import android.util.Log;

import android.util.SparseBooleanArray;

import android.view.LayoutInflater;

import android.view.Menu;

import android.view.MenuInflater;

import android.view.MenuItem;

import android.view.View;

import android.view.ViewGroup;

import android.view.ViewGroup.LayoutParams;

import android.widget.AbsListView;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.GridView;

import android.widget.ShareActionProvider;

import android.widget.TextView;

import android.widget.Toast;

import android.view.ActionMode;

public class DownloadService extends IntentService {

public static final int UPDATE_PROGRESS = 8344;

public DownloadService() {

super("DownloadService");

}

@Override

protected void onHandleIntent(Intent intent) {

String urlToDownload = intent.getStringExtra("url");

String fileDestination = intent.getStringExtra("dest");

ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");

try {

URL url = new URL(urlToDownload);

URLConnection connection = url.openConnection();

connection.connect();

// this will be useful so that you can show a typical 0-100% progress bar

int fileLength = connection.getContentLength();

// download the file

InputStream input = new BufferedInputStream(connection.getInputStream());

OutputStream output = new FileOutputStream(fileDestination);

byte data[] = new byte[100];

long total = 0;

int count;

while ((count = input.read(data)) != -1) {

total += count;

// publishing the progress....

Bundle resultData = new Bundle();

resultData.putInt("progress" ,(int) (total * 100 / fileLength));

receiver.send(UPDATE_PROGRESS, resultData);

output.write(data, 0, count);

}

output.flush();

output.close();

input.close();

} catch (IOException e) {

e.printStackTrace();

}

Bundle resultData = new Bundle();

resultData.putInt("progress" ,100);

receiver.send(UPDATE_PROGRESS, resultData);

}

}

UpdateChecker

package com.jcodecraeer.jcode.update;

import java.io.BufferedReader;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.HttpURLConnection;

import java.net.URL;

import java.util.ArrayList;

import java.util.Date;

import java.util.zip.GZIPInputStream;

import org.json.JSONException;

import org.json.JSONObject;

import com.jcodecraeer.jcode.Code;

import android.app.AlertDialog;

import android.app.ProgressDialog;

import android.content.Context;

import android.content.DialogInterface;

import android.content.Intent;

import android.content.pm.PackageManager;

import android.net.Uri;

import android.os.Bundle;

import android.os.Environment;

import android.os.Handler;

import android.os.Message;

import android.os.ResultReceiver;

import android.util.Log;

import android.widget.Toast;

public class UpdateChecker{

private static final String TAG = "UpdateChecker";

private Context mContext;

//检查版本信息的线程

private Thread mThread;

//版本对比地址

private String mCheckUrl;

private AppVersion mAppVersion;

//下载apk的对话框

private ProgressDialog mProgressDialog;

private File apkFile;

public void setCheckUrl(String url) {

mCheckUrl = url;

}

public UpdateChecker(Context context) {

mContext = context;

// instantiate it within the onCreate method

mProgressDialog = new ProgressDialog(context);

mProgressDialog.setMessage("正在下载");

mProgressDialog.setIndeterminate(false);

mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

mProgressDialog.setCancelable(true);

mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {

@Override

public void onCancel(DialogInterface dialog) {

}

});

mProgressDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {

@Override

public void onDismiss(DialogInterface dialog) {

// TODO Auto-generated method stub

}

});

}

public void checkForUpdates() {

if(mCheckUrl == null) {

//throw new Exception("checkUrl can not be null");

return;

}

final Handler handler = new Handler(){

public void handleMessage(Message msg) {

if (msg.what == 1) {

mAppVersion = (AppVersion) msg.obj;

try{

int versionCode = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode;

if (mAppVersion.getApkCode() > versionCode) {

showUpdateDialog();

} else {

//Toast.makeText(mContext, "已经是最新版本", Toast.LENGTH_SHORT).show();

}

}catch (PackageManager.NameNotFoundException ignored) {

//

}

}

}

};

mThread = new Thread() {

@Override

public void run() {

//if (isNetworkAvailable(mContext)) {

Message msg = new Message();

String json = sendPost();

Log.i("jianghejie","json = "+json);

if(json!=null){

AppVersion appVersion = parseJson(json);

msg.what = 1;

msg.obj = appVersion;

handler.sendMessage(msg);

}else{

Log.e(TAG, "can't get app update json");

}

}

};

mThread.start();

}

protected String sendPost() {

HttpURLConnection uRLConnection = null;

InputStream is = null;

BufferedReader buffer = null;

String result = null;

try {

URL url = new URL(mCheckUrl);

uRLConnection = (HttpURLConnection) url.openConnection();

uRLConnection.setDoInput(true);

uRLConnection.setDoOutput(true);

uRLConnection.setRequestMethod("POST");

uRLConnection.setUseCaches(false);

uRLConnection.setConnectTimeout(10 * 1000);

uRLConnection.setReadTimeout(10 * 1000);

uRLConnection.setInstanceFollowRedirects(false);

uRLConnection.setRequestProperty("Connection", "Keep-Alive");

uRLConnection.setRequestProperty("Charset", "UTF-8");

uRLConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");

uRLConnection.setRequestProperty("Content-Type", "application/json");

uRLConnection.connect();

is = uRLConnection.getInputStream();

String content_encode = uRLConnection.getContentEncoding();

if (null != content_encode && !"".equals(content_encode) && content_encode.equals("gzip")) {

is = new GZIPInputStream(is);

}

buffer = new BufferedReader(new InputStreamReader(is));

StringBuilder strBuilder = new StringBuilder();

String line;

while ((line = buffer.readLine()) != null) {

strBuilder.append(line);

}

result = strBuilder.toString();

} catch (Exception e) {

Log.e(TAG, "http post error", e);

} finally {

if(buffer!=null){

try {

buffer.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if(is!=null){

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if(uRLConnection!=null){

uRLConnection.disconnect();

}

}

return result;

}

private AppVersion parseJson(String json) {

AppVersion appVersion = new AppVersion();

try {

JSONObject obj = new JSONObject(json);

String updateMessage = obj.getString(AppVersion.APK_UPDATE_CONTENT);

String apkUrl = obj.getString(AppVersion.APK_DOWNLOAD_URL);

int apkCode = obj.getInt(AppVersion.APK_VERSION_CODE);

appVersion.setApkCode(apkCode);

appVersion.setApkUrl(apkUrl);

appVersion.setUpdateMessage(updateMessage);

} catch (JSONException e) {

Log.e(TAG, "parse json error", e);

}

return appVersion;

}

public void showUpdateDialog() {

AlertDialog.Builder builder = new AlertDialog.Builder(mContext);

//builder.setIcon(R.drawable.icon);

builder.setTitle("有新版本");

builder.setMessage(mAppVersion.getUpdateMessage());

builder.setPositiveButton("下载",

new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int whichButton) {

downLoadApk();

}

});

builder.setNegativeButton("忽略",

new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int whichButton) {

}

});

builder.show();

}

public void downLoadApk() {

String apkUrl = mAppVersion.getApkUrl();

String dir = mContext.getExternalFilesDir( "apk").getAbsolutePath();

File folder = Environment.getExternalStoragePublicDirectory(dir);

if(folder.exists() && folder.isDirectory()) {

//do nothing

}else {

folder.mkdirs();

}

String filename = apkUrl.substring(apkUrl.lastIndexOf("/"),apkUrl.length());

String destinationFilePath = dir + "/" + filename;

apkFile = new File(destinationFilePath);

mProgressDialog.show();

Intent intent = new Intent(mContext, DownloadService.class);

intent.putExtra("url", apkUrl);

intent.putExtra("dest", destinationFilePath);

intent.putExtra("receiver", new DownloadReceiver(new Handler()));

mContext.startService(intent);

}

private class DownloadReceiver extends ResultReceiver{

public DownloadReceiver(Handler handler) {

super(handler);

}

@Override

protected void onReceiveResult(int resultCode, Bundle resultData) {

super.onReceiveResult(resultCode, resultData);

if (resultCode == DownloadService.UPDATE_PROGRESS) {

int progress = resultData.getInt("progress");

mProgressDialog.setProgress(progress);

if (progress == 100) {

mProgressDialog.dismiss();

//如果没有设置SDCard写权限,或者没有sdcard,apk文件保存在内存中,需要授予权限才能安装

String[] command = {"chmod","777",apkFile.toString()};

try{

ProcessBuilder builder = new ProcessBuilder(command);

builder.start();

Intent intent = new Intent(Intent.ACTION_VIEW);

intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");

mContext.startActivity(intent);

}catch (Exception e){

}

}

}

}

}

}

所有代码都已经贴出来了。

这个代码是完全可以用的,但是有些细节问题需要改进。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值