内容简介:1、查询线上版本号,然后拿本地版本号与之对比。2、若线上版本号比本地版本号大,则下载线上版本号。3、把下载好的版本号安装,并替换当前旧版本根据上面的需求我们可以知道,需要用到的权限应该有网络权限、本地文件写入权限,本地文件读取权限。使用网络权限去获取线上的版本号,然后下载保存到本地,安装的时候再去本地取来。另外8.0上google把未知应用的安装权限的管理放到了每个app上,每个app都有允许安装未知应用的设置开关,所以这里也需要权限1.先判断8.0以上的需要检测是否有权限,有的直接去检测版本更新,没有去申
一、需求分析
1、查询线上版本号,然后拿本地版本号与之对比。2、若线上版本号比本地版本号大,则下载线上版本号。3、把下载好的版本号安装,并替换当前旧版本
二、权限
根据上面的需求我们可以知道,需要用到的权限应该有网络权限、本地文件写入权限,本地文件读取权限。使用网络权限去获取线上的版本号,然后下载保存到本地,安装的时候再去本地取来。另外8.0上google把未知应用的安装权限的管理放到了每个app上,每个app都有允许安装未知应用的设置开关,所以这里也需要权限
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>---8.0安装权限 复制代码
三、步骤
1.先判断8.0以上的需要检测是否有权限,有的直接去检测版本更新,没有去申请
if (!checkInstall()){ if (conn) { this.checkUpdate(splashView); } else { Toast.makeText(this, "请检查网络~", Toast.LENGTH_LONG).show(); } } /** * 如果想让应用自动安装下载的新版本apk,那么必须打开应用的这个权限,不然是不会自动安装的 */ public boolean checkInstall() { boolean haveInstallPermission; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //先获取是否有安装未知来源应用的权限 haveInstallPermission = getPackageManager().canRequestPackageInstalls(); if (!haveInstallPermission) {//没有权限 android.support.v7.app.AlertDialog alertDialog = new android.support.v7.app.AlertDialog.Builder(this) .setTitle("请开启未知来源权限") .setMessage("应用需要打开安装未知来源应用权限,请去设置中开启权限") .setCancelable(false) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); Toast.makeText(WelcomeActivity.this, "您拒绝了权限,应用无法正常使用!", Toast.LENGTH_SHORT).show(); finish(); } }) .setPositiveButton("去设置", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); toInStallPermissionSettingActivity(); } }).create(); alertDialog.show(); return true; } } return false; } @RequiresApi(api = Build.VERSION_CODES.O) private void toInStallPermissionSettingActivity() { Uri packageURI = Uri.parse("package:" + getPackageName()); //注意这个是8.0新API Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI); startActivityForResult(intent, REQUEST_CODE_INSTALL_PERMISSION); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode==RESULT_OK&&requestCode==REQUEST_CODE_INSTALL_PERMISSION){ if (conn) { this.checkUpdate(splashView); } else { Toast.makeText(this, "请检查网络~", Toast.LENGTH_LONG).show(); } }else { finish(); Toast.makeText(WelcomeActivity.this, " 您拒绝了权限,应用无法正常使用!", Toast.LENGTH_SHORT).show(); } } 复制代码
2网络请求检测更新
/** * 检测软件更新 */ public void checkUpdate(final View splashView) { // 创建okHttpClient对象 OkHttpClient mOkHttpClient = new OkHttpClient(); Request request = new Request.Builder().url(Urls.UPDATEXML).build();//http://ushevapp-10060464.cos.myqcloud.com/version.xml mOkHttpClient.newCall(request).enqueue( new okhttp3.Callback() { @Override public void onFailure(okhttp3.Call call, IOException e) { Message msg = new Message(); msg.what = 0; mmHandler.sendMessage(msg); Log.d("h_bl", "失败"); } @Override public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException { InputStream is = null; byte[] buf = new byte[2048]; int len = 0; String SDPath = Environment.getExternalStorageDirectory().getAbsolutePath(); try { is = response.body().byteStream(); ParseXmlService pxs = new ParseXmlService(); stringStringHashMap = pxs.parseXml(is); Message msg = new Message(); msg.what = 1; mmHandler.sendMessage(msg); Log.d("h_bl", "检测软件更新文件下载成功"); } catch (Exception e) { Message msg = new Message(); msg.what = 0; mmHandler.sendMessage(msg); Log.d("h_bl", "文检测软件更新件下载失败"); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { } } } } ); 复制代码
3、去开启服务下载apk,然后安装
/** * 下载文件:Okhttp */ private void loadFileByOkhttp() { initNotification(); OkHttpClient mOkHttpClient = new OkHttpClient(); Request request = new Request.Builder() .url(url) // .addHeader("Accept-Encoding", "identity") .build(); mOkHttpClient.newCall(request).enqueue( new Callback() { @Override public void onFailure(okhttp3.Call call, IOException e) { cancelNotification(); Log.d("h_bl", "新版本下载失败"); } @Override public void onResponse(okhttp3.Call call, Response response) throws IOException { InputStream is = null; byte[] buf = new byte[2048]; int len = 0; FileOutputStream fos = null; try { is = response.body().byteStream(); long total = response.body().contentLength(); File file = new File(destFileDir, destFileName); fos = new FileOutputStream(file); long sum = 0; int progress = 0; while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); sum += len; progress = (int) (sum * 1.0f / total * 100); updateNotification(progress); } if (progress == 100) { cancelNotification(); installApk(file); } fos.flush(); Log.d("h_bl", "apk文件下载成功"); } catch (Exception e) { e.printStackTrace(); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (fos != null) { fos.close(); } } catch (IOException e) { e.printStackTrace(); } } } } ); } 复制代码
另外这里也有8·0的坑,就是不做特殊处理下载没有通知显示,那么看代码
/** * 初始化Notification通知 */ public void initNotification() { destFileDir = getTempDirectoryPath(); notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { builder = new NotificationCompat.Builder(mContext, PUSH_CHANNEL_ID); NotificationChannel channel = new NotificationChannel(PUSH_CHANNEL_ID, PUSH_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH); channel.enableVibration(false); channel.setVibrationPattern(new long[]{0}); channel.setSound(null, null); if (notificationManager != null) { notificationManager.createNotificationChannel(channel); } builder.setSmallIcon(R.mipmap.logo) .setContentText("0%") .setContentTitle("住保服务更新") .setChannelId(PUSH_CHANNEL_ID); } else { builder = new NotificationCompat.Builder(mContext) .setSmallIcon(R.mipmap.logo) .setContentText("0%") .setContentTitle("住保服务更新"); } notificationManager.notify(NOTIFY_ID, builder.build()); } 复制代码
最后安装apk,注意一些细节,更新的包需要和旧包有相同的签名文件否则会安装失败,还有就是8.0的坑了,前面以后给出权限解决
/** * 安装软件 * * @param file */ private void installApk(File file) { Uri uri = Uri.fromFile(file); Intent install = new Intent(Intent.ACTION_VIEW); install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); install.setDataAndType(uri, "application/vnd.android.package-archive"); // 执行意图进行安装 mContext.startActivity(install); } 复制代码
欧了,现在应该自动更新没问题可以解决了,如有问题欢迎指正,互相学习
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- oscnews 1.3.0 更新,更新趋势榜功能
- VLOOK V9.23 更新!表格自动排版大更新
- oscnews 1.0.0 更新,软件更新资讯 Chrome 插件
- .NET Framework 4.8 的 Microsoft 更新目录更新
- 网游丨一月一更新,一更更一月,如何实现热更新?
- CCleaner v5.74.8184 发布:重要更新版本、可自动更新
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First jQuery
Ryan Benedetti , Ronan Cranley / O'Reilly Media / 2011-9 / USD 39.99
Want to add more interactivity and polish to your websites? Discover how jQuery can help you build complex scripting functionality in just a few lines of code. With Head First jQuery, you'll quickly g......一起来看看 《Head First jQuery》 这本书的介绍吧!