APK静默安装与更新
来源:互联网 发布:ims数据 编辑:程序博客网 时间:2024/06/16 04:29
在平时开发中,很常见的功能就是一个版本发布了,在进入主页面之前会对本地版本和服务器版本对比,发现新版本就会直接弹出对话框然用户选择是否要更新,实现逻辑代码如下,建立一个splash.xml,这个页面主要是作用是检测版本异同
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ll_main" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical|center_horizontal" android:orientation="vertical" > <TextView android:id="@+id/tv_splash_version" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="280dip" android:text="版本号" android:textColor="#FF01b6f8" android:textSize="20sp" /> <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="50dip" /></LinearLayout>
建立一个SplashActivity,这个类的主要作用是检测版本更新,请求服务器并解析返回结果,把版本抽取成一个对象
public class Info {
<span style="white-space:pre"></span>//省去set/get和构造private String version;private String desc;private String apkurl;}
public class SplashActivity extends Activity {private LinearLayout ll_main;private TextView tv_splash_version;private ProgressDialog pd;private String versiontext;private Info info;private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {if (isNeedUpdate(versiontext)) {showUpdataDialog();}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.splash);ll_main = (LinearLayout) findViewById(R.id.ll_main);tv_splash_version = (TextView) findViewById(R.id.tv_splash_version);pd = new ProgressDialog(this);pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);pd.setMessage("正在下载...");versiontext = getVersion();new Thread() {public void run() {//延迟2秒SystemClock.sleep(2000);//发送消息给handlerhandler.sendEmptyMessage(0);};}.start();tv_splash_version.setText(versiontext);AlphaAnimation aa = new AlphaAnimation(0.0f, 1.0f);aa.setDuration(2000);ll_main.startAnimation(aa);// 全屏显示getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);}// 更新提示框private void showUpdataDialog() {AlertDialog.Builder builder = new Builder(this);builder.setTitle("升级提示");builder.setMessage(info.getDesc());builder.setCancelable(false);builder.setPositiveButton("下载", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// 判断SD卡是否可用if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {DownloadFileThreadTask task = new DownloadFileThreadTask(info.getApkurl(), Environment.getExternalStorageDirectory() + "/new.apk");pd.show();//开启下载APK线程new Thread(task).start();} else {Toast.makeText(getApplicationContext(), "sd卡不可用", 1).show();loadMainUI();}}});builder.setNegativeButton("取消", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {//点击取消,也进入主页面loadMainUI();}});builder.create().show();}// 下载文件private class DownloadFileThreadTask implements Runnable {private String path;private String filePath;public DownloadFileThreadTask(String path, String filePath) {this.path = path;this.filePath = filePath;}@Overridepublic void run() {try {//获取路径和文件和dialogFile file = DownloadFileTask.getFile(path, filePath, pd);pd.dismiss();//下载完成就安装installAPK(file);} catch (Exception e) {pd.dismiss();e.printStackTrace();Toast.makeText(getApplicationContext(), "文件下载失败", 0).show();loadMainUI();}}}// 检测本地版本和服务器是否一致private boolean isNeedUpdate(String textversion) {HttpTools httpTools = new HttpTools(this);// 从服务器获取最新版本信息try {info = httpTools.getServerVersion(R.string.apkupdateurl);String version = info.getVersion();if (textversion.equals(version)) {loadMainUI();return false;} else {return true;}} catch (Exception e) {e.printStackTrace();Toast.makeText(this, "获取版本异常", 0).show();loadMainUI();return false;}};// 加载主页面private void loadMainUI() {startActivity(new Intent(SplashActivity.this, MainActivity.class));finish();}// 静默安装public void installAPK(File file) {Intent intent = new Intent();intent.setAction(Intent.ACTION_VIEW);intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");finish();startActivity(intent);}// 获取版本号public String getVersion() {PackageManager packageManager = getPackageManager();try {PackageInfo info = packageManager.getPackageInfo(getPackageName(),0);return info.versionName;} catch (NameNotFoundException e) {e.printStackTrace();}return "版本异常";}}在SplashActivity中,使用到了请求服务器数据并解析数据的HttpTools这个类,其中使用到了android内部提供的httpClient来解析服务器返回的json数据
public class HttpTools {private Context context;public HttpTools(Context context) {this.context = context;}// 根据配置文件中的url获取json地址public Info getServerVersion(int uid) {Info info = null;
<span style="white-space:pre"></span>//使用外部配置文件中的地址String path = context.getResources().getString(uid);HttpClient httpClient = new DefaultHttpClient();HttpGet httpGet = new HttpGet(path);HttpResponse httpResponse;JSONObject jsonObject;try {httpResponse = httpClient.execute(httpGet);if (httpResponse.getStatusLine().getStatusCode() == 200) {// {version:'2.0',desc:'fuck',apkurl:'http://xxx'}String json = EntityUtils.toString(httpResponse.getEntity(),"UTF-8");try {jsonObject = new JSONObject(json);for (int i = 0; i < jsonObject.length(); i++) {String version = jsonObject.getString("version");String apkurl = jsonObject.getString("apkurl");String desc = jsonObject.getString("desc");info = new Info(version, desc, apkurl);}} catch (JSONException e) {e.printStackTrace();}}} catch (ClientProtocolException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} return info;}}好了,基于上面的代码,大体功能已经完成一半了;继续ing....。完成上面代码之后,在SplashActivity中使用到了一个DownloadFileTask这个类,这个类主要是负责下载文件和更新进度条,写完代码之后才发现,冗余的代码很多,想用AsyncHtttpClient这个开源项目简化一下
public class DownloadFileTask {public static File getFile(String path, String filePath, ProgressDialog pd)throws Exception {URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(5000);if (conn.getResponseCode() == 200) {int total = conn.getContentLength();pd.setMax(total);InputStream is = conn.getInputStream();File file = new File(filePath);FileOutputStream fos = new FileOutputStream(file);byte[] buffer = new byte[1024];int len = 0;int process = 0;while ((len = is.read(buffer)) != -1) {fos.write(buffer, 0, len);process += len;pd.setProgress(process);Thread.sleep(50);}fos.flush();fos.close();is.close();return file;}return null;}}到了这里,客户端的代码完成差不多了,最后别忘了一点,在values下见了一个config.xml文件,在这个文件里面动态的添加访问服务器的路径
<resources> <string name="apkupdateurl">http://192.168.4.112:8080/Server/Server</string></resources>=====================我是分割线==============================
编写服务端的代码,在服务端用一个servlet来编写代码如下:
@WebServlet("/Server")public class ServerServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");response.setCharacterEncoding("UTF-8");Info info = new Info();info.setVersion("2.0");info.setDesc("发现新版本,请更新哦(*^__^*) ");info.setApkurl("http://192.168.4.112:8080/Demo.apk");String json = JSONObject.toJSONString(info);response.getWriter().write(json);}}
把需要添加的权限加入:
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
最后,记得把最新的版本放到服务器上,并且确保本地客户端的清单文件中的版本和服务器上的版本不同,才能弹出更新对话框和更新并且安装。
0 0
- APK静默安装与更新
- Android 静默更新apk
- 代码中执行apk安装、卸载、更新以及静默安装
- 代码中执行apk安装、卸载、更新以及静默安装
- 静默安装apk,静默卸载apk
- 静默安装APK
- android 静默安装apk
- android 静默安装Apk
- Android静默安装apk
- android静默安装apk
- android apk静默安装
- Android静默安装apk
- 静默安装apk
- android APK静默安装
- apk 静默安装
- 关于静默安装apk
- 静默安装apk
- Android 静默安装apk
- hdu 3879 最大权闭合图(裸题)
- 如何将 Vim 打造成一个成熟的 IDE
- 计算机系学长的大学四年
- 第十一周项目六 回文素数(1)
- 汇编基础学习
- APK静默安装与更新
- MVC4 Model验证注意点
- 第11周上机实践项目3——程序的多文件组织
- 写sql出错
- Reveal使用步骤
- Linux open
- 第十一周 项目五: 当年第几天
- 纳豆就像国人喜欢吃的臭豆腐一样
- 第十一周项目 4 特殊的三位数