在Android开发中,经常用到的一个功能是版本的检测更新,有的是更新整个apk,而用户体验好的,省流量就是热更新和增量更新,这里我们不讲更新的方式,而是来说说我们怎么进行更新,更新的条件是什么?
一般的话,我们的apk里面新增加了内容,客户端会提示用户进行更新,那么我们就需要获取本地的apk的版本号和服务端的版本进行比较,获取服务端的版本号就是一个网络请求,这里就不说了,如果服务端的版本号大于本地的版本号,那就提示用户进行更新操作,这里有强制更新和一般更新,强制更新就是用户必须要进行更新才能正常使用apk,否则的话不让使用,有点流氓了,但是对于一些特殊情况,还是要使用的,记得12306就出现过。这里我要说的是一般的更新,也就是用户可选的。样式比较丑,可以自己修改样式。先看看效果:
详细代码如下:
import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; public class VersionUpdateActivity extends Activity implements OnClickListener{ // private static final String savePath = "/sdcard/updateAPK/"; // apk保存到SD卡的路径,这里是写死的,也可以采用下面这种方法,通用一点 private static final String savePath = Environment.getExternalStorageDirectory()+"/updateAPK/"; private static final String saveFileName = savePath + "eyeguard.apk"; // 完整路径名 private ProgressBar mProgress; // 下载进度条控件 private static final int DOWNLOADING = 1; // 表示正在下载 private static final int DOWNLOADED = 2; // 下载完毕 private static final int DOWNLOAD_FAILED = 3; // 下载失败 private int progress; // 下载进度 private String apkUrl;//apk下载地址 private Button btn_cancel; private Button btn_ok; // private RelativeLayout relative_update_dialog; private TextView txt_update; private TextView txt_update_name; final int REQUEST_CODE_CONTACT = 101; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //设置dialog不显示默认的标题文字 requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_version_update); // relative_update_dialog = (RelativeLayout) findViewById(R.id.relative_update_dialog); mProgress = (ProgressBar) findViewById(R.id.my_progress); btn_cancel = (Button) findViewById(R.id.btn_cancel); btn_ok = (Button) findViewById(R.id.btn_ok); txt_update = (TextView) findViewById(R.id.txt_update); txt_update_name = (TextView) findViewById(R.id.txt_update_name); btn_cancel.setOnClickListener(this); btn_ok.setOnClickListener(this); apkUrl="http://www.gamept.cn/d/file/game/qipai/20140627/HappyLordZZ_1.0.19_20140325_300002877528_2200139763.apk"; } /** 更新UI的handler */ private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub switch (msg.what) { case DOWNLOADING: mProgress.setProgress(progress); break; case DOWNLOADED: installAPK(); break; case DOWNLOAD_FAILED: Toast.makeText(getApplicationContext(), "下载失败,请稍后重试", Toast.LENGTH_LONG).show(); finish(); break; default: break; } } }; /** 下载apk的线程 */ public void downloadAPK() { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { Log.e("apk下载地址--->", apkUrl); URL url = new URL(apkUrl); HttpURLConnection conn = (HttpURLConnection) url .openConnection(); conn.connect(); int length = conn.getContentLength(); InputStream is = conn.getInputStream(); // //版本大于6.0的情况 // if (Build.VERSION.SDK_INT >= 23) { // // String[] permissions = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}; // //验证是否许可权限 // for (String str : permissions) { // if (VersionUpdateActivity.this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) { // //申请权限 // VersionUpdateActivity.this.requestPermissions(permissions, REQUEST_CODE_CONTACT); // return; // } // } // } File file = new File(savePath); if (!file.exists()) { file.mkdir(); } String apkFile = saveFileName; File ApkFile = new File(apkFile); FileOutputStream fos = new FileOutputStream(ApkFile); int count = 0; byte buf[] = new byte[1024]; while(true){ int numread = is.read(buf); count += numread; progress = (int) (((float) count / length) * 100); // 更新进度 mHandler.sendEmptyMessage(DOWNLOADING); if (numread <= 0) { // 下载完成通知安装 mHandler.sendEmptyMessage(DOWNLOADED); break; } fos.write(buf, 0, numread); } fos.close(); is.close(); } catch (Exception e) { mHandler.sendEmptyMessage(DOWNLOAD_FAILED); e.printStackTrace(); } } }).start(); } // //判断是否具有权限 // public void openPermission() { // //版本大于6.0的情况 // if (Build.VERSION.SDK_INT >= 23) { // // String[] permissions = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}; // //验证是否许可权限 // for (String str : permissions) { // if (VersionUpdateActivity.this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) { // //申请权限 // VersionUpdateActivity.this.requestPermissions(permissions, REQUEST_CODE_CONTACT); // // return; // }else { openPermission(); // } // } // }else { openPermission(); // } // } // // //重写权限的回调方法 // @Override // public void onRequestPermissionsResult(int requestCode, // String[] permissions, int[] grantResults) { // // TODO Auto-generated method stub // switch (requestCode) { // case REQUEST_CODE_CONTACT: // if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { // downloadAPK(); // // }else { // VersionUpdateActivity.this.finish(); // AppToastMgr.shortToast(VersionUpdateActivity.this, "没有权限,下载失败"); // } // break; // // default: // break; // } // super.onRequestPermissionsResult(requestCode, permissions, grantResults); // } /** 下载完成后自动安装apk */ public void installAPK() { File apkFile = new File(saveFileName); if (!apkFile.exists()) { return; } Intent intent = new Intent(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(Uri.parse("file://" + apkFile.toString()), "application/vnd.android.package-archive"); startActivity(intent); finish(); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { //确定按钮 case R.id.btn_ok: if (!AppNetworkMgr.isNetworkConnected(VersionUpdateActivity.this)) { Toast.makeText(VersionUpdateActivity.this, getString(R.string.sys_network_error),Toast.LENGTH_SHORT).show(); return; } mProgress.setVisibility(View.VISIBLE); txt_update.setVisibility(View.VISIBLE); btn_ok.setVisibility(View.GONE); btn_cancel.setVisibility(View.GONE); txt_update_name.setVisibility(View.GONE); downloadAPK(); break; //取消按钮 case R.id.btn_cancel: finish(); break; default: break; } } }
注释很详细了,自己看吧,这里顺便说一下,版本更新也可以使用第三方的。
下载链接: http://download.csdn.net/detail/u014727709/9702166
转载自
欢迎start,欢迎评论,欢迎指正