2010.12.14——— android 应用的自动更新

参考:http://ming-fanglin.iteye.com/blog/795450
http://www.androidres.com/index.php/2009/04/13/add-liveupdate-to-android-applications/
http://www.cnblogs.com/qianxudetianxia/archive/2011/04/26/2010930.html

看了网上的一些东西 自己觉得 思路大致分三步:
  • 1、检查是否更新
  • 2、下载最新apk文件
  • 3、更新应用



代码如下:

UpdateProject.java


package com.huitu.project;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.List;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import android.app.Activity;import android.app.ActivityManager;import android.app.ActivityManager.RunningAppProcessInfo;import android.app.AlertDialog;import android.app.Dialog;import android.app.ProgressDialog;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.content.pm.PackageInfo;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.view.KeyEvent;import com.huitu.util.HttpUtil;public class UpdateProject extends Activity{private ProgressDialog pd;private Handler mProgressHandler = new Handler();private Intent intent;//private UninstallReceiver ur;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.updateproject);intent = new Intent(this,MainActivity.class);SharedPreferences sp = getSharedPreferences("version", Context.MODE_PRIVATE);long lastUpdateTime = sp.getLong("lastUpdateTime", System.currentTimeMillis());//更新间隔至少一天//if(lastUpdateTime + (24*60*60*1000)<System.currentTimeMillis()){lastUpdateTime = System.currentTimeMillis();Editor editor = sp.edit();editor.putLong("lastUpdateTime", lastUpdateTime);editor.commit();if(checkUpdate()){Dialog dialog = new AlertDialog.Builder(this).setTitle("系统更新").setMessage("已有新版本,是否更新?").setPositiveButton("确定",new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {pd = new ProgressDialog(UpdateProject.this);pd.setMessage("正在更新,请稍后...");pd.show();down(HttpUtil.BASE_URL+"android_file/cpjw.apk");}}).setNegativeButton("取消", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {startActivity(intent);}}).create();dialog.show();}else{startActivity(intent);}//}else{//startActivity(intent);//}}//判断是否需要更新private boolean checkUpdate(){String url = HttpUtil.BASE_URL+"android_checkUpdate.action";try {PackageInfo info = this.getPackageManager().getPackageInfo(this.getPackageName(), 0);int oldVersion = info.versionCode;System.out.println(oldVersion);String flat = HttpUtil.queryStringForPost(url);int newVersion = Integer.parseInt(flat);System.out.println(oldVersion+"============"+newVersion);if(newVersion > oldVersion){return true;}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return false;}private void down(final String url){ new Thread() {              public void run() {                  HttpClient client = new DefaultHttpClient();                  HttpGet get = new HttpGet(url);                  HttpResponse response;                  try {                      response = client.execute(get);                      HttpEntity entity = response.getEntity();                      long length = entity.getContentLength();                      InputStream is = entity.getContent();                      FileOutputStream fileOutputStream = null;                      if (is != null) {                            File file = new File(Environment                                  .getExternalStorageDirectory(), "cpjw.apk");                          fileOutputStream = new FileOutputStream(file);                                                    byte[] buf = new byte[1024];                          int ch = -1;                          while ((ch = is.read(buf)) != -1) {                              fileOutputStream.write(buf, 0, ch);                          }                        }                      fileOutputStream.flush();                      if (fileOutputStream != null) {                          fileOutputStream.close();                      }                      update();                                    } catch (ClientProtocolException e) {                      // TODO Auto-generated catch block                      e.printStackTrace();                  } catch (IOException e) {                      // TODO Auto-generated catch block                      e.printStackTrace();                  }              }            }.start(); }private void update() {    mProgressHandler.post(new Runnable() {                public void run() {                pd.cancel();            install();                finish();            }            });            }           private void install() {       Intent i = new Intent();   //i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);         i.setAction(Intent.ACTION_VIEW);            i.setDataAndType(Uri.fromFile(new File("/sdcard/cpjw.apk")),                    "application/vnd.android.package-archive");            startActivity(i);          //finish();    }       @Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {// 按下键盘上返回按钮if (keyCode == KeyEvent.KEYCODE_BACK) {new AlertDialog.Builder(this).setMessage("确定退出系统吗?").setNegativeButton("取消",new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog,int which) {}}).setPositiveButton("确定",new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog,int whichButton) {finish();}}).show();return true;} else {return super.onKeyDown(keyCode, event);}}@Overrideprotected void onDestroy() {super.onDestroy();// 或者下面这种方式//System.exit(0);//建议用这种android.os.Process.killProcess(android.os.Process.myPid());}}



首先 这个Activity 是在我们的应用启动时 就转到这个Activity里面 判断 更新 如果没有更新 就转到业务应用界面


1、判断是否需要更新

主要是根据版本号 来控制 在清单文件里面
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.huitu.project"      android:versionCode="1"      android:versionName="1.0">


我们在服务器建一张表 表里可以只有一条数据 这个数据就是最新的版本号

我们获得这个版本号 如果大于手机当前版本号 就提示更新

2、下载最新apk

我们在服务器 可以写一个文件上传的页面 把文件上传到一个固定的目录下面 上传成功后 还要更新数据库最新版本号


3、更新apk

i.setAction(Intent.ACTION_VIEW);            i.setDataAndType(Uri.fromFile(new File("/sdcard/cpjw.apk")),                    "application/vnd.android.package-archive");            startActivity(i);  


这样 就会开始安装apk


但是 这里有个问题 总是 提示“应用程序未安装

下载时成功了 但是就是安装不上

我在手机上 也是安装不上 只能把原来的应用卸载 然后安装才会成功


后来 我就想 是不是可以在程序里面先卸载 再安装啊 于是:

//   private void uninstall(){//   Intent intent = new Intent(Intent.ACTION_DELETE);    //   Uri data = Uri.parse("package:"+this.getPackageName());//   intent.setData(data);//   startActivity(intent);//   }//   //   private class UninstallReceiver extends BroadcastReceiver{////   @Override//   public void onReceive(Context context, Intent intent) {//   System.out.println("rrrrrrrrrrrrrrr");//   Toast.makeText(context, "1345435", 1).show();//   install();//   }//   //   }//   ////   @Override//   protected void onResume() {//   IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_DATA_CLEARED);  //       filter.addAction(Intent.ACTION_PACKAGE_REMOVED);  //       filter.addDataScheme("package");  //       ur = new UninstallReceiver();  //       registerReceiver(ur, filter);  //       super.onResume();  //   }@Overrideprotected void onDestroy() {super.onDestroy();// 或者下面这种方式//System.exit(0);//建议用这种//取消注册unregisterReceiver(ur);android.os.Process.killProcess(android.os.Process.myPid());}




但是 这个是不行的 应该只能监听别的应用卸载 监听不到自身吧

卸载后 应用就直接退出了 根本不会执行 下载和安装了

这个也是一个问题 希望有人能解决 。。。。










更多相关文章

  1. android studio 3.1 Android Device Monitor 新的启动方式
  2. Android不同层次开启硬件加速的方式
  3. Android 的 Button 按钮实现的两种方式
  4. Android中界面实现全屏显示的两种方式
  5. [Android Studio] Android Studio如何提示函数用法
  6. Android 的广播机制和两种注册方式
  7. Android的几种通讯方式
  8. android进行主题切换不重启整个应用(style方式)
  9. 用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)

随机推荐

  1. 确保网站性能的5个小贴士
  2. LeetCode 题解 | 1297.子串的最大出现次
  3. 像数据库一样设计你的 redux 数据结构
  4. 对比Excel学习SQL(5):分组和子查询
  5. 使用 React 实现页面过渡动画仅需四个步
  6. LeetCode 题解 | 1312. 让字符串成为回文
  7. 剑指Offer 图解 | 寻找旋转排序数组中的
  8. 我就想问一句,约么?
  9. 从 O(N) 优化到 O(logN),你的第一想法是什
  10. 神器 VS Code,超详细Python配置使用指南