[android studio]Android 程序更新模块与自动更新模块实例

更新时间:2018-09-13    来源:今天更新    手机版     字体:

【www.bbyears.com--今天更新】

这里介绍了实现原理,为了使用方便,简单封装了一个类Updater。用法很简单。好吧,为了支持多语言,其实还是有些繁琐。

用法:

strings.xml 中用到的字符定义
其他语言的自己添加,下面的实例程序中,中英文都有

 代码如下

check for update
Help?
I am helper,muhaha~~~
Found a new version
need update?
Software Update
Update
Not now
Downloading update
Please wait a moment

在AndroidManifest.xml添加更新需要用到的权限

 代码如下



检查更新,如发现有新版本会弹出提示

 

 代码如下  private boolean checkUpdate() {
 Updater updater = new Updater("http://127.0.0.1/", this);
 if (updater.needUpdate())//found update
  updater.showNewVersionUpdate();
 else {
 
 }
 
 return true;
}

自动更新


之前帮别人定制的一个android应用需要加个自动更新的功能。在 Market 里的应用是无需操心此事的,但像我这种定制的程序就需要自己实现。

原理相当简单,检查更新的时候,通过指定的URL获取服务器端版本信息。比较版本,如果更新,访问服务器端返回的apk的URL地址,下载,安装。各种 Makert 也是通过类似的机制实现的。原理搞清楚了,代码就相当简单了。

获取apk的VesionName,即AndroidManifest.xml中定义的android:versionName

 代码如下

public String getVesionName(Context context) {
 String versionName = null;
 try {
  versionName = context.getPackageManager().getPackageInfo("net.vpntunnel", 0).versionName;
 } catch (NameNotFoundException e) {
  Log.e(TAG, e.getMessage());
 }
 
 return versionName;
}

更新以及安装程序需要的权限,在AndroidManifest.xml中添加

 代码如下



获取apk的versionCode,即AndroidManifest.xml中定义的android:versionCode

 代码如下

public int getVersionCode(Context context) {
 int versionCode = 0;
 try {
  versionCode = context.getPackageManager().getPackageInfo("net.vpntunnel", 0).versionCode;
 } catch (NameNotFoundException e) {
  Log.e(TAG, e.getMessage());
 }
 
 return versionCode;
}

服务器端version.JSON,包含apk路径以及版本信息

 代码如下

{
    "ApkName":"NAME",
    "ApkFullName":"NAME_1.0.5.apk",
    "VersionName":"1.0.5",
    "VersionCode":3
}

获取远程服务器的版本信息

 代码如下

private void getRemoteJSON(string host) throws ClientProtocolException, IOException, JSONException {
 String url = String.format("http://%s/%s", host, VER_JSON);
 StringBuilder sb = new StringBuilder();
 HttpClient client = new DefaultHttpClient();
 HttpParams httpParams = client.getParams();
 HttpConnectionParams.setConnectionTimeout(httpParams, 3000);
 HttpConnectionParams.setSoTimeout(httpParams, 5000);
 HttpResponse response = client.execute(new HttpGet(url));
 HttpEntity entity = response.getEntity();
 if (entity != null) {
  BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"), 8192);
 
  String line = null;
  while ((line = reader.readLine()) != null) {
   sb.append(line + "n");
  }
  reader.close();
 }
 
 JSONObject object = (JSONObject) new JSONTokener(sb.toString()).nextValue();
 this.apkFullName = object.getString("ApkFullName");
 this.versionName = object.getString("VersionName");
 this.versionCode = Integer.valueOf(object.getInt("VersionCode"));
}

发现更新的提醒窗口,通过AlertDialog实现

 代码如下

private void shoVersionUpdate(String newVersion, final String updateURL) {
 String message = String.format("%s: %s, %s", mContext.getString(R.string.found_newversion), newVersion, mContext.getString(R.string.need_update));
 AlertDialog dialog = new AlertDialog.Builder(mContext).setTitle(mContext.getString(R.string.alertdialog_title)).setMessage(message)
 // update
   .setPositiveButton(mContext.getString(R.string.alertdialog_update_button), new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
     pBar = new ProgressDialog(mContext);
     pBar.setTitle(mContext.getString(R.string.progressdialog_title));
     pBar.setMessage(mContext.getString(R.string.progressdialog_message));
     pBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
     dialog.dismiss();
     downFile(updateURL);
    }
    // cancel
   }).setNegativeButton(mContext.getString(R.string.alertdialog_cancel_button), new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
     dialog.dismiss();
    }
   }).create();
 dialog.show();
}

下载新版的apk文件,存放地址可以放到SD卡中。通过Environment.getExternalStorageDirectory()获取SD卡中的路径

 代码如下

private void downFile(final String url) {
 pBar.show();
 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 f = new File(UPDATE_DIR);
     if (!f.exists()) {
      f.mkdirs();
     }
     fileOutputStream = new FileOutputStream(new File(UPDATE_DIR, updateFileName));
 
     byte[] buf = new byte[1024];
     int ch = -1;
     int count = 0;
     while ((ch = is.read(buf)) != -1) {
      fileOutputStream.write(buf, 0, ch);
      count += ch;
      Log.d(TAG, String.valueOf(count));
      if (length > 0) {
      }
     }
    }
    fileOutputStream.flush();
    if (fileOutputStream != null) {
     fileOutputStream.close();
    }
 
    handler.post(new Runnable() {
     public void run() {
      pBar.cancel();
      installUpdate();
     }
    });
   } catch (Exception e) {
    pBar.cancel();
    Log.e(TAG, e.getMessage());
   }
  }
 
 }.start();
}

安装更新

 代码如下 private void installUpdate() {
 Intent intent = new Intent(Intent.ACTION_VIEW);
 intent.setDataAndType(Uri.fromFile(new File(UPDATE_DIR, updateFileName)), "application/vnd.android.package-archive");
 mContext.startActivity(intent);
}

至此更新需要函数就完成了,根据自己的业务逻辑组合一下,更新功能就搞定了。也可以稍微封装下,写成一个通用类,下次就可以直接用了。

本文来源:http://www.bbyears.com/jintiangengxin/44315.html

热门标签

更多>>

本类排行