您的位置:首页 > 理论基础 > 计算机网络

基于OkHttpUtils自己实现一个检查升级软件功能

2016-12-29 16:52 549 查看
一、思路

先请求后台接口,得到服务器的最新软件版本,然后和软件本身的版本进行对比,如果有最新的版本,则提示用户点击按钮进行下载,否则提示该版本为最新版本!逻辑是不是很简单哈~。我们现在主要的实现是在有最新版本时去下载更新!我们使用的网络框架是基于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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐