android 自动更新资源,实现Android应用自动更新

新建一个Android工程,如我的工程文件目录为:

e644db27a27841172300960ef75dd4ab.png

在工程文件中新建一个activity,用于呈现自动更新提示对话框。如上图工程中的AutoUpdateActivity,该activity代码如下:

//一个用于呈现提示用于进行更新的页面

public class AutoUpdateActivity extends Activity {

private static final String TAG = "AutoUpdateActivity";    //日志打印标志

private static int localVersionCode, serverVersionCode = 0;   //本地和服务器端应用版本号

private String fileName, filePath;    //应用程序保存文件名和文件路径

private Context context;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//设置当前activity的布局文件,任意布局文件皆可

setContentView(R.layout.activity_auto_update);

context = this;

filePath = "Star";

}

@Override

protected void onResume() {

super.onResume();

// 检查是否需要进行版本更新,该函数必须在onResume或者onStart中调用,否则可能报错

checkUpdate();

}

// 检查是否有新的版本

private void checkUpdate() {

// 获取本地应用程序版本号

try {

localVersionCode = context.getPackageManager().getPackageInfo(

context.getPackageName(), 0).versionCode;

} catch (NameNotFoundException e) {

e.printStackTrace();

}

// 比较本地版本号与服务器端版本号,判断是否需要更新

if (getServerVersionCode() > localVersionCode) {

fileName = "Star.apk";

showUpdateDialog();

}

}

// 获取服务器端应用程序版本号

private int getServerVersionCode() {

RequestParams params = new RequestParams();

StringBuilder versionCode = new StringBuilder();

versionCode.append("{\"getVersionCode\"}");

params.put("param", versionCode.toString());

AsyncHttpClient client = new AsyncHttpClient();

//向服务器请求最新版本号的URL地址

String urlString = utils.Constants.SERVER_BASE_URL

+ utils.Constants.GET_VERSION_CODE;

client.post(urlString, params, new AsyncHttpResponseHandler() {

@Override

public void onSuccess(String response) {

serverVersionCode = Integer.parseInt(JsonUtil

.getResult(response));

}

@Override

public void onFailure(Throwable error, String content) {

serverVersionCode = 0;

Log.d(TAG, content + " ");

}

});

return serverVersionCode;

}

// 显示应用程序更新对话框

private void showUpdateDialog() {

//创建一个对话框

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

//设置对话框标题、显示信息等

builder.setTitle("版本更新").setMessage("Star有新版本啦,快下载体验吧~")

.setIcon(com.star.R.drawable.ic_update_dialog);

//设置对话框的响应按钮

builder.setPositiveButton("下载", new OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

dialog.dismiss();

//DownTask是一个我自己写的AsyncTask类,用于下载最新版的应用程序

DownTask downTask = new DownTask(context, filePath, fileName);

downTask.execute(Constants.SERVER_BASE_URL

+ Constants.GET_NEW_VERSION);

}

});

builder.setNegativeButton("以后再说", new OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

dialog.dismiss();    //对话框消失

}

});

builder.show();    //必须调用该函数,否则创建的对话框将不会显示

}

}

上面代码中的checkUpdate()函数包含了上述原理一中的1、2、3步,当if条件判断为真时,显示应用更新提示对话框,即调用showUpdateDilaog()方法,用户选择“下载”,则下载该应用程序,并进行更新(这部分为调用DownTask进行处理);

DownTask类代码如下:

//DownTask是通过一部任务进行应用下载的,也可以开启一个新的工作线程进行下载

public class DownTask extends AsyncTask {

private static final String TAG = "DownTask";

private Context mContext;

private AlertDialog aDialog;

private String filePath;

private String fileName;

/**

* 构造函数

*

* @param ctx

* @param savePath

*            :下载资源保存路径

@param fileName

*            :下载资源保存文件名

*/

public DownTask(Context ctx, String savePath, String fileName) {

mContext = ctx;

filePath = savePath;

this.fileName = fileName;

}

@SuppressWarnings("unused")

@Override

protected String doInBackground(String... params) {

//FileUtils是自己写的一个文件工具

FileUtils fileUtil = new FileUtils();

String result = null;

File file;

try {

file = new File(fileUtil.getSDPATH() + filePath + "/" + fileName);

if (file.exists()) {

result = "File exist!";

Log.i(TAG, result);

} else {

fileUtil.createSDDir(filePath);

file.createNewFile();

URL url = new URL(params[0]);

HttpURLConnection urlConnection = (HttpURLConnection) url

.openConnection();

fileUtil.write2SDFromInput(filePath, fileName,

urlConnection.getInputStream());

if (file != null) {

result = "success";

} else {

result = "Fail";

}

}

} catch (IOException e1) {

e1.printStackTrace();

}

Log.i(TAG, result);

return result;

}

@Override

protected void onPostExecute(String result) {

Toast.makeText(mContext, "最新版Star已经下载好啦,赶快试用吧!",

Toast.LENGTH_LONG);

Log.i(TAG, "Finish download");

aDialog.dismiss();

installApk();

}

// 安装apk文件

private void installApk() {

File apkfile = new File(filePath + "/" + fileName);

if (!apkfile.exists()) {

return;

}

//调用安装应用程序的Intent

Intent i = new Intent(Intent.ACTION_VIEW);

i.setDataAndType(Uri.parse("file://" + apkfile.toString()),

"application/vnd.android.package-archive");

mContext.startActivity(i);

}

@Override

protected void onPreExecute() {

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

builder.setTitle("下载Star").setMessage("新版本下载中...")

.setIcon(R.drawable.ic_update_dialog).show();

aDialog = builder.create();

}

}

FileUtils代码:

public class FileUtils {

private String SDPATH;

private int FILESIZE = 4 * 1024;

public String getSDPATH() {

return SDPATH;

}

public FileUtils() {

// 得到当前外部存储设备的目录( /SDCARD )

SDPATH = Environment.getExternalStorageDirectory() + "/";

}

/**

* 在SD卡上创建文件

*

* @param fileName

* @return

* @throws IOException

*/

public File createSDFile(String fileName) throws IOException {

File file = new File(SDPATH + fileName);

file.createNewFile();

return file;

}

/**

* 在SD卡上创建目录

*

* @param dirName

* @return

*/

public File createSDDir(String dirName) {

File dir = new File(SDPATH + dirName);

dir.mkdir();

return dir;

}

/**

* 判断SD卡上的文件夹是否存在

*

* @param fileName

* @return

*/

public boolean isFileExist(String fileName) {

File file = new File(SDPATH + fileName);

return file.exists();

}

/**

* 将一个InputStream里面的数据写入到SD卡中

*

* @param path

* @param fileName

* @param input

* @return

*/

public File write2SDFromInput(String path, String fileName,

InputStream input) {

File file = null;

OutputStream output = null;

try {

createSDDir(path);

file = createSDFile(path + fileName);

output = new FileOutputStream(file);

byte[] buffer = new byte[FILESIZE];

int length;

while ((length = (input.read(buffer))) > 0) {

output.write(buffer, 0, length);

}

output.flush();

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

output.close();

} catch (IOException e) {

e.printStackTrace();

}

}

return file;

}

}

最后别忘了在manifest文件中添加相应的权限以及该activity

android:allowBackup="true"

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme" >

android:name="activity.AutoUpdateActivity"

android:label="@string/app_name" >

注意:Android不能在UI线程中进行比较耗时的操作,否则可能导致页面阻塞,甚至引发ANR错误(程序未响应),所以该示例中的下载操作放到一个异步任务中进行的,也可以采用工作线程的方式

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值