基于OkHttpUtils自己实现一个检查升级软件功能
2016-12-29 16:52
549 查看
一、思路
先请求后台接口,得到服务器的最新软件版本,然后和软件本身的版本进行对比,如果有最新的版本,则提示用户点击按钮进行下载,否则提示该版本为最新版本!逻辑是不是很简单哈~。我们现在主要的实现是在有最新版本时去下载更新!我们使用的网络框架是基于OkHttpUtils:https://github.com/hongyangAndroid/okhttputils
二、上代码
下载apk文件肯定是耗时的,并且我们要在通知栏显示进度,因些我们需要开启一个Service来下载和更新进度!
三、使用
Intent intent = new Intent(MoreActivity.this, UpdateService.class);
intent.putExtra("apkUrl", getResources().getString(R.string.http_url) + updateApp.getUrl());
startService(intent);
先请求后台接口,得到服务器的最新软件版本,然后和软件本身的版本进行对比,如果有最新的版本,则提示用户点击按钮进行下载,否则提示该版本为最新版本!逻辑是不是很简单哈~。我们现在主要的实现是在有最新版本时去下载更新!我们使用的网络框架是基于OkHttpUtils:https://github.com/hongyangAndroid/okhttputils
二、上代码
下载apk文件肯定是耗时的,并且我们要在通知栏显示进度,因些我们需要开启一个Service来下载和更新进度!
public class UpdateService extends Service { private String apkURL; private NotificationManager notificationManager; private NotificationCompat.Builder builder; private int mProceess = -1; private SdcardUtils sdcardUtils; @Override public void onDestroy() { super.onDestroy(); OkHttpUtils.getInstance().cancelTag(this); } @Override public void onCreate() { notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); sdcardUtils = new SdcardUtils(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent == null) { notifyUser("下载失败", 0); stopSelf();//取消 } else { apkURL = intent.getStringExtra("apkUrl"); initNotify(); initFileDir(); notifyUser("下载开始", 0); startDownload();//启动下载 } return super.onStartCommand(intent, flags, startId); } /** * 创建文件夹 */ private void initFileDir() { if (SdcardUtils.existSdcard()) { if (!sdcardUtils.isFileExist(Constants.FILE_DIR_NAME)) {//不存在就重新创建文件 sdcardUtils.creatSDDir(Constants.FILE_DIR_NAME); } } else { ToastUtils.getInstance().show("sd卡不存在!"); } } private void initNotify() { builder = new NotificationCompat.Builder(this); builder.setContentTitle(Constants.APP_NAME); builder.setSmallIcon(R.mipmap.ic_launcher) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)); builder.setAutoCancel(true); builder.setWhen(System.currentTimeMillis()); builder.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT)); } private void startDownload() { OkHttpUtils// .get()// .tag(this) .url(apkURL)// .build()// .execute(new FileCallBack(sdcardUtils.getSDPATH() + "/" + Constants.FILE_DIR_NAME, Constants.APP_NAME)// { int fProgress; @Override public void inProgress(float progress, long total, int id) {//下载进度 super.inProgress(progress, total, id); fProgress = (int) (100 * progress); if (fProgress != mProceess) {//避免刷新太快,会卡死 mProceess = fProgress; notifyUser("正在下载", fProgress); } } @Override public void onError(Call call, Exception e, int id) {//下载失败 notifyUser("下载失败", 0); stopSelf(); } @Override public void onResponse(File response, int id) {//下载完成 notifyUser("下载完成", 100); stopSelf(); //下载完成则安装 File apkFile = new File(sdcardUtils.getSDPATH() + "/" + Constants.FILE_DIR_NAME + "/" + Constants.APP_NAME); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(Uri.parse("file://" + apkFile.getAbsolutePath()), "application/vnd.android.package-archive"); startActivity(intent); if (notificationManager != null) { notificationManager.cancelAll(); } } }); } private void notifyUser(String result, int process) { if (builder == null) { return; } if (process > 0 && process < 100) { builder.setProgress(100, process, false); } else { builder.setProgress(0, 0, false); } if (process >= 100) { builder.setContentIntent(getContentIntent()); } builder.setContentInfo(process+"%"); builder.setContentText(result); notificationManager.notify(0,builder.build()); } private PendingIntent getContentIntent() { File apkFile = new File(sdcardUtils.getSDPATH() + "/" + Constants.FILE_DIR_NAME + "/" + Constants.APP_NAME); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(Uri.parse("file://" + apkFile.getAbsolutePath()), "application/vnd.android.package-archive"); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); return pendingIntent; } @Nullable @Override public IBinder onBind(Intent intent) { return null; } }对SD卡进行扣件的工具类
public class SdcardUtils { private String SDPATH; public String getSDPATH() { return SDPATH; } public SdcardUtils() { //得到当前外部存储设备的目录 // /SDCARD SDPATH = Environment.getExternalStorageDirectory() + "/"; } /** * 判断sdk是否存在 * * @return */ public static boolean existSdcard() { return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); //判断sd卡是否存在 } /** * 在SD卡上创建文件 * * @throws IOException */ public File creatSDFile(String fileName) throws IOException { File file = new File(SDPATH + fileName); file.createNewFile(); return file; } /** * 在SD卡上创建目录 * * @param dirName */ public File creatSDDir(String dirName) { File dir = new File(SDPATH + dirName); dir.mkdir(); return dir; } /** * 在原来的路径上创建文件夹 * @param base * @param name * @return */ public File creatFileDir(String base, String name) { File dir = new File(base + "/" + name); if (dir.exists()) { } else { dir.mkdir(); } return dir; } /** * 判断绝对路径下文件夹是否存在 * @param path * @return */ public boolean fileExit(String path) { File file = new File(path); return file.exists(); } /** * 判断SD卡上的文件夹是否存在 */ public boolean isFileExist(String fileName) { File file = new File(SDPATH + fileName); return file.exists(); } /** * 将一个InputStream里面的数据写入到SD卡中 */ public File write2SDFromInput(String path, String fileName, InputStream input) { File file = null; OutputStream output = null; try { creatSDDir(path); file = creatSDFile(path + fileName); output = new FileOutputStream(file); byte buffer[] = new byte[4 * 1024]; while ((input.read(buffer)) != -1) { output.write(buffer); } output.flush(); } catch (Exception e) { e.printStackTrace(); } finally { try { output.close(); } catch (Exception e) { e.printStackTrace(); } } return file; } /** * 删除单个文件 * * @param filePath 被删除文件的文件名 * @return 文件删除成功返回true,否则返回false */ public static boolean deleteFile(String filePath) { File file = new File(filePath); if (file.isFile() && file.exists()) { return file.delete(); } return false; } /** * 删除文件夹以及目录下的文件 * * @param filePath 被删除目录的文件路径 * @return 目录删除成功返回true,否则返回false */ public static boolean deleteDirectory(String filePath) { boolean flag = false; //如果filePath不以文件分隔符结尾,自动添加文件分隔符 if (!filePath.endsWith(File.separator)) { filePath = filePath + File.separator; } File dirFile = new File(filePath); if (!dirFile.exists() || !dirFile.isDirectory()) { return false; } flag = true; File[] files = dirFile.listFiles(); //遍历删除文件夹下的所有文件(包括子目录) for (int i = 0; i < files.length; i++) { if (files[i].isFile()) { //删除子文件 flag = deleteFile(files[i].getAbsolutePath()); if (!flag) break; } else { //删除子目录 flag = deleteDirectory(files[i].getAbsolutePath()); if (!flag) break; } } if (!flag) return false; //删除当前空目录 return dirFile.delete(); } /** * 根据路径删除指定的目录或文件,无论存在与否 * * @param filePath 要删除的目录或文件 * @return 删除成功返回 true,否则返回 false。 */ public static boolean deleteFolder(String filePath) { File file = new File(filePath); if (!file.exists()) { return false; } else { if (file.isFile()) { // 为文件时调用删除文件方法 return deleteFile(filePath); } else { // 为目录时调用删除目录方法 return deleteDirectory(filePath); } } } }
三、使用
Intent intent = new Intent(MoreActivity.this, UpdateService.class);
intent.putExtra("apkUrl", getResources().getString(R.string.http_url) + updateApp.getUrl());
startService(intent);
相关文章推荐
- 基于Nginx实现一个自己的HTTP模块
- 毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选
- 毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选
- 基于Nginx实现一个自己的HTTP模块--发送磁盘中的文件
- 正在准备写一个Java实现的HTTP的负载均衡软件
- Android中xml解析--实现软件升级功能
- 自己写的一个基于数组实现的栈,欢迎大家批评指正,共同进步
- 自己编写的一个Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加载对象
- Android 一个相对完整的自动升级功能实现代码
- 一点一点地实现每个功能,最后才能汇聚成一个庞大的软件
- DrGraph软件升级:实现最近使用文档功能
- Objective-C如何自己实现一个基于数组下标的属性访问模式
- WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序)
- 实现"通过串口升级嵌入式目标板软件"功能的一些心得体会
- Android照相功能驱动层中HAL的实现(基于OK6410开发板+OV9650摄像头)
- 自己写了一个上传类,实现了常用的功能
- 使用C#的WebService实现客户端软件的在线升级功能
- 自己编写的一个Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加载对象
- [Visaul C#] 自己实现的一个HttpContextHelper有多处方法,可实现强大的HTTP请求处理
- 利用socket自己实现基于HTTP协议的Web服务器