前言:
我们似乎在做什么apk,都需要去做更新这个功能,那怎么去做这个功能才好呢,那当然在做的时候当然回去百度一下(除非是大神)。想我这个种没做一个比较好玩的功能的时候,第一步就是去百度大家的做法,想法。怎么去实现、怎么完成。怎样比较好看,和健壮性比较好。
一直一来自己都是小白,所以很明白小白的心情,自己写博客也会写的非常详细,希望大神勿喷。也希望小白能从中得到学习。
好了不啰嗦,马上开始我们的代码体验.
为了不浪费大家的时间,我们先开看一下我们的实现效果先.如果这个效果是你想要的.就可以仔细阅读一下本篇文章啦.
正文:
这个自动检测升级Apk的功能,相信每个应用都会使用到。这里也提供给大家使用,直接copy过去就能使用了。
不需要做过多的调整。
其中使用Service、BroadcastReceiver、OkHttp下载、Gson解析json、NotificationManager、Notification 运用的知识也挺多的,也可以供大家参考、学习使用。
源码下载:点击打开链接
注意:博主使用的是Tomcat服务器,我们将这些数据下载下来放在Tomcat服务上就可以测试了
好了接下在直接进入代码主题:
1、第一步先添加入所需要的第三方依赖
2、模拟写好要去读取的json数据(这里可以是xml数据,根据自己喜欢)
update.json
{
//app名字
appname:"UpdateApk",
//服务器版本号
serverVersion:2,
//是否强制更新 true为强制升级,false为正常状态
whetherForce:false,
//apk下载地址
updateurl:"http://127.0.0.1:8080/UpdateApk.apk",
//版本的更新的描述
upgradeinfo:"有新功能哦!要不要尝试一下"
}
3、写好对应的Bean类
UpdateInfo.java
public class UpdateInfo {
//app名字
private String appname;
//服务器版本
private int serverVersion;
//强制升级
private boolean whetherForce;
//app最新版本地址
private String updateurl;
//升级信息
private String upgradeinfo;
/**
* 都生成对于的set and get 方法
* 这里我就不把set and get 方法贴出来了,读者注意去生成就好了
*/
}
4、单独创建一个java类来存储存放json数据的连接(方便管理)
HttpApi.java
/**
* 这里存放我们要去读取的json数据连接
*/
public class HttpApi {
public static String updateUrl = "http://127.0.0.1:8080/updateapk.json";
}
5、创建MyApplication.java 去继承 Application。需要一进去APP就去请求网络进行APP版本信息比配
/**
* 在程序进入的时候我们就去读取网络上APK的信息
* Created by WL-鬼 on 2017/5/13.
*/
public class MyApplication extends Application {
//先在这创建好上下文环境,可能会使用到,这里为个人习惯,需要使用的时候在创建也是可以的
private static Context mContext;
//读取到的bean对象
private static UpdateInfo mUpdateInfo;
public static final String UPDATE_ACTION = "UPDATE_INFO";
@Override
public void onCreate() {
super.onCreate();
mContext = this.getApplicationContext();
getServiceUpdateInfo(false);
}
/**
* 获取服务器上的更新信息
* @param isClick 参数一:是否为手动点击的检测更新
* @return 获取到的UpdateInfo对象
*/
public static UpdateInfo getServiceUpdateInfo(final boolean isClick){
mUpdateInfo = new UpdateInfo();
new Runnable() {
@Override
public void run() {
OkHttpClient mOkHttpClient = new OkHttpClient();
Request mRequest = new Request.Builder().url(HttpApi.updateUrl).build();
Call mCall = mOkHttpClient.newCall(mRequest);
Callback callback = new Callback() {
@Override
public void onFailure(Call call, IOException e) {
String r = e.toString();
Log.d("onFailure",r);
}
@Override
public void onResponse(Call call, Response response) {
Log.d("MyApplication--onResponse",response.code()+"");
try {
//只有服务器已成功处理了请求,才继续处理我们接下来想处理的事情
if (response.code() == 200){
String infoStr = response.body().string();
Log.d("onResponse",infoStr);
Gson mGson = new Gson();
mUpdateInfo = mGson.fromJson(infoStr,UpdateInfo.class);
//创建Intent
Intent intent = new Intent(UPDATE_ACTION);
if (isClick){
intent.putExtra("isclick",isClick);
}
//开启广播
mContext.sendBroadcast(intent);
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
mCall.enqueue(callback);
}
}.run();
return mUpdateInfo;
}
public static UpdateInfo getmUpdateInfo() {
return mUpdateInfo;
}
public static Context getContext() {
return mContext;
}
}
6、去创建 UpdateReceiver 继承 BroadcastReceiver 并且需要注册(这里可以使用动态注册和静态注册)(我这里实现了静态注册)
6.1、在UpdateReceiver中所需要使用到的布局文件
download_promp.xml
6.2,这里插入写的一个工具类
MyUtils.java
public class MyUtils {
//放在下载更新包的文件夹
public static String updateDownloadDir = "updateApk";
/**
* 获取本地APK的版本信息
*/
public static int getLocalCodeVersion(){
PackageManager mPackageManager = null;
PackageInfo mPackageInfo = null;
int localCodeEdition = 0;
try {
mPackageManager = getContext().getPackageManager();
mPackageInfo =mPackageManager.getPackageInfo(getContext().getPackageName(),0);
localCodeEdition = mPackageInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return localCodeEdition;
}
/**
* 删除更新包
*/
public static void clearUpateApk() {
File updateDir;
File updateFile;
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())) {
updateDir = new File(Environment.getExternalStorageDirectory(),
updateDownloadDir);
} else {
updateDir = getContext().getFilesDir();
}
updateFile = new File(updateDir.getPath(),getContext().getResources()
.getString(R.string.app_name) + ".apk");
if (updateFile.exists()) {
Log.d("update", "升级包存在,删除升级包");
updateFile.delete();
} else {
Log.d("update", "升级包不存在,不用删除升级包");
}
}
}
注:我这个服务里面。提供了两种提示更新的方式一个是使用Dialog ,一个是使用通知拦方式(NotificationManager)可根据自己喜欢调用对应的方法。
public class UpdateReceiver extends BroadcastReceiver {
//Dialog弹框
private static AlertDialog.Builder mDialog;
//这个是用来是否为手动点击获取更新信息的 默认为false
private static boolean isClick = false;
//刚刚在App中获取到的信息
private static UpdateInfo mUpdateInfo;
@Override
public void onReceive(Context context, Intent intent) {
//获取到网络上apk的信息
mUpdateInfo = MyApplication.getmUpdateInfo();
//获取是否为手动点击的信息 默认为false自动检测,true 为手动检测
isClick = intent.getBooleanExtra("isclick",false);
checkVersion(context);
}
/**
* 检查版本更新
*/
public void checkVersion(Context context) {
//如果服务上的版本大于本地的版本
if (mUpdateInfo.getServerVersion() > MyUtils.getLocalCodeVersion()){
Log.d("版本更新","需要更新");
//判断是否为强制更新
if (mUpdateInfo.isWhetherForce()){// true 为是强制升级
promptDiglog(context,2);
}else { //false 为正常升级
if (isClick){
promptDiglog(context,1);
}else {
promptUpdate(context);
}
}
}else{
if (isClick){
promptDiglog(context,0);
Log.d("版本更新","无需更新");
}
}
//判断是否存在升级包,存在就删除
MyUtils.clearUpateApk();
}
/**
* 通知栏提示更新
*/
private void promptUpdate(Context context){
NotificationManager motificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
Notification notification = new Notification();
notification.icon = R.mipmap.ic_launcher_round;
//添加声音提示
notification.defaults = Notification.DEFAULT_SOUND;
/* 或者使用以下几种方式
* notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3");
* notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");
* 如果想要让声音持续重复直到用户对通知做出反应,则可以在notification的flags字段增加"FLAG_INSISTENT"
* 如果notification的defaults字段包括了"DEFAULT_SOUND"属性,则这个属性将覆盖sound字段中定义的声音
*/
//audioStreamType的值必须AudioManager中的值,代表响铃模式
notification.audioStreamType = AudioManager.ADJUST_LOWER;
//添加LED灯提醒
notification.defaults |= Notification.DEFAULT_LIGHTS;
//或者可以自己的LED提醒模式:
/*notification.ledARGB = 0xff00ff00;
notification.ledOnMS = 300; //亮的时间
notification.ledOffMS = 1000; //灭的时间
notification.flags |= Notification.FLAG_SHOW_LIGHTS;*/
//添加震动
notification.defaults |= Notification.DEFAULT_VIBRATE;
//或者可以定义自己的振动模式:
/*long[] vibrate = {0,100,200,300}; //0毫秒后开始振动,振动100毫秒后停止,再过200毫秒后再次振动300毫秒
notification.vibrate = vibrate;*/
//状态栏提示信息
notification.tickerText = mUpdateInfo.getAppname()+" 发现新版本,点击下载";
//获取当前时间
notification.when = System.currentTimeMillis();
//加载自定义布局
notification.contentView = getRemoteViews(context,"发现新版本,点击下载");
//加载点击事件
notification.contentIntent = getPendingIntent(context);
// 点击清除按钮或点击通知后会自动消失
notification.flags |= Notification.FLAG_AUTO_CANCEL;
//取消Intent事件
//notification.contentIntent.cancel();
motificationManager.notify(0, notification);
}
//自定义notification布局
public static RemoteViews getRemoteViews(Context context,String info) {
RemoteViews remoteviews = new RemoteViews(context.getPackageName(),R.layout.download_promp);
remoteviews.setImageViewResource(R.id.download_promp_icon,R.mipmap.ic_launcher_round);
remoteviews.setTextViewText(R.id.download_title,mUpdateInfo.getAppname());
remoteviews.setTextViewText(R.id.download_promp_info,info);
//如果你需要对title中的哪一个小控件添加点击事件可以这样为控件添加点击事件(详情请下载代码进行观看)
//remoteviews.setOnClickPendingIntent(R.id.download_notification_root,getPendingIntent(context));
return remoteviews;
}
/**
* 给通知栏添加点击事件,实现具体操作
* @param context 上下文
* @return
*/
private PendingIntent getPendingIntent(Context context) {
Intent intent = new Intent(context,UpdateService.class);
intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("appname",mUpdateInfo.getAppname());
intent.putExtra("updateurl",mUpdateInfo.getUpdateurl());
PendingIntent pendingIntent = PendingIntent.getService(context,0,intent,0);
return pendingIntent;
}
/**
* Dialog提示升级,用户可以选择是否取消升级
*/
private void promptDiglog(final Context context, int i) {
mDialog = new AlertDialog.Builder(context);
mDialog.setTitle("版本更新");
switch (i){
case 0: //没有升级的版本
mDialog.setMessage("当前为最新版本");
mDialog.setNegativeButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
break;
case 1: //正常升级
mDialog.setMessage(mUpdateInfo.getUpgradeinfo());
mDialog.setPositiveButton("去升级", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent mIntent = new Intent(context, UpdateService.class);
mIntent.addFlags(FLAG_ACTIVITY_NEW_TASK);
mIntent.putExtra("appname",mUpdateInfo.getAppname());
mIntent.putExtra("updateurl",mUpdateInfo.getUpdateurl());
//传递数据
context.startService(mIntent);
}
}).setNegativeButton("下次吧", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
break;
case 2: //强制升级
mDialog.setMessage(mUpdateInfo.getUpgradeinfo());
mDialog.setPositiveButton("升级", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent mIntent = new Intent(context, UpdateService.class);
mIntent.addFlags(FLAG_ACTIVITY_NEW_TASK);
mIntent.putExtra("appname",mUpdateInfo.getAppname());
mIntent.putExtra("updateurl",mUpdateInfo.getUpdateurl());
//启动服务
context.startService(mIntent);
}
}).setNegativeButton("退出", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 直接退出应用
System.exit(0);
}
});
break;
}
AlertDialog alertDialog = mDialog.create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_TOAST);
alertDialog.show();
}
}
注:AndroidManifest.xml 中注册的广播代码
7、创建UpdateService 继承 Sercive 同样这个服务也需要注册。
download_notification.xml 在 Service 中使用到的布局
UpdateService.java
/**
* 状态栏通知服务
* Created by WL-鬼 on 2017/5/13.
*/
public class UpdateService extends Service{
private static final float SIZE_BT = 1024L; // BT字节参考量
private static final float SIZE_KB = SIZE_BT * 1024.0f; // KB字节参考量
private static final float SIZE_MB = SIZE_KB * 1024.0f;// MB字节参考量
private final static String DOWNLOAD_COMPLETE = "1";// 完成
private final static String DOWNLOAD_NOMEMORY = "-1";// 内存异常
private final static String DOWNLOAD_FAIL = "-2";// 失败
private String appName = null;// 应用名字
private String appUrl = null;// 应用升级地址
private File updateDir = null;// 文件目录
private File updateFile = null;// 升级文件
private NotificationManager updateNotificationManager = null; // 通知栏
private Notification updateNotification = null;
private PendingIntent updatePendingIntent = null;// 在下载的时候
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
appName = intent.getStringExtra("appname");
appUrl = intent.getStringExtra("updateurl");
Log.d("UpdateService---------updateInfo",appName + " " + appUrl);
updateNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
updateNotification = new Notification();
updateNotification.icon = R.mipmap.ic_launcher;//通知图标
updateNotification.tickerText = "正在下载"+appName;//通知信息描述
updateNotification.when = System.currentTimeMillis();
updateNotification.contentView = new RemoteViews(getPackageName(),
R.layout.download_notification);
updateNotification.contentView.setTextViewText(
R.id.download_notice_name_tv, appName + " 正在下载");
new UpdateThread().execute();
}
/**
* 这里使用一个内部类去继承AsyncTask
* 实现异步操作
*/
class UpdateThread extends AsyncTask{
@Override
protected Object doInBackground(Object[] params) {
return downloadUpdateFile(appUrl);
}
}
private long totalSize; //APK总大小
private long downloadSize; // 下载的大小
private int count = 0; //下载百分比
/**
* 下载更新程序文件
* @param appUrl 下载地址
* @return
*/
private String downloadUpdateFile(String appUrl) {
OkHttpClient mOkHttpClient = new OkHttpClient();
Request mRequest = new Request.Builder().url(appUrl).build();
Call mCall = mOkHttpClient.newCall(mRequest);
mCall.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
downloadResult(DOWNLOAD_FAIL);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.code() == 200){
InputStream is = null;
byte[] buf = new byte[4096];
int len = 0;
FileOutputStream fos = null;
try {
totalSize = response.body().contentLength();
downloadSize = 0;
if (MemoryAvailable(totalSize)){
is = response.body().byteStream();
fos = new FileOutputStream(updateFile,true);
while ((len = is.read(buf)) != -1) {
downloadSize += len;
fos.write(buf, 0, len);
if ((count == 0) || (int) (downloadSize * 100 / totalSize) >= count) {
count += 5;
//文本进度(百分比)
updateNotification.contentView
.setTextViewText(
R.id.download_notice_speed_tv,
getMsgSpeed(downloadSize,totalSize));
//进度条
updateNotification.contentView.setProgressBar(
R.id.pbProgress,
(int) totalSize,(int) downloadSize,false);
updateNotificationManager.notify(0,updateNotification);
}
}
fos.flush();
if (totalSize >= downloadSize) {
//进度条
updateNotification.contentView.setProgressBar(
R.id.pbProgress,
(int) totalSize,(int) totalSize,false);
downloadResult(DOWNLOAD_COMPLETE);
} else {
downloadResult(DOWNLOAD_FAIL);
}
}else {
downloadResult(DOWNLOAD_NOMEMORY);
}
} catch (IOException e) {
e.printStackTrace();
downloadResult(DOWNLOAD_FAIL);
} finally {
try {
if (is != null) {
is.close();
}
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}else {
downloadResult(DOWNLOAD_FAIL);
}
}
});
return null;
}
/**
* 下载结果
* @param integer
*/
private void downloadResult(String integer) {
switch (integer){
case DOWNLOAD_COMPLETE:
Log.d("update","下载成功");
String cmd = "chmod 777" + updateFile.getPath();
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
e.printStackTrace();
}
Uri uri = Uri.fromFile(updateFile);
//安装程序
Intent installIntent = new Intent(Intent.ACTION_VIEW);
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
installIntent.setDataAndType(uri,"application/vnd.android.package-archive");
updatePendingIntent = PendingIntent.getActivity(UpdateService.this, 0, installIntent, 0);
updateNotification.contentIntent = updatePendingIntent;
updateNotification.tickerText = appName + " 下载完成";//通知信息描述
/**
* 这里做为保留,是选择显示之前有进度条的下载完成提示还是选择另外的显示样式,可根据自己定义
*/
// updateNotification.contentView.setTextViewText(
// R.id.download_notice_name_tv, appName + " 下载完成");
// updateNotification.contentView.setTextViewText(
// R.id.download_notice_speed_tv,
// getString(R.string.update_notice_install));
updateNotification.contentView = UpdateReceiver.getRemoteViews(MyApplication.getContext(),"下载完成,点击安装");
updateNotification.when = System.currentTimeMillis();
updateNotification.defaults = Notification.DEFAULT_SOUND;
updateNotification.flags |= Notification.FLAG_AUTO_CANCEL;
updateNotificationManager.notify(0, updateNotification);
//启动安装程序
startActivity(installIntent);
stopSelf();
break;
case DOWNLOAD_NOMEMORY:
//如果内存有问题
updateNotification.tickerText = appName + "下载失败";
updateNotification.when = System.currentTimeMillis();
updateNotification.contentView.setTextViewText(
R.id.download_notice_speed_tv,
getString(R.string.update_notice_nomemory));
updateNotification.flags |= Notification.FLAG_AUTO_CANCEL;
updateNotification.defaults = Notification.DEFAULT_SOUND;
updateNotificationManager.notify(0, updateNotification);
stopSelf();
break;
case DOWNLOAD_FAIL:
//下载失败
updateNotification.tickerText = appName + "下载失败";
updateNotification.when = System.currentTimeMillis();
updateNotification.contentView.setTextViewText(
R.id.download_notice_speed_tv,
getString(R.string.update_notice_error));
updateNotification.flags |= Notification.FLAG_AUTO_CANCEL;
updateNotification.defaults = Notification.DEFAULT_SOUND;
updateNotificationManager.notify(0, updateNotification);
stopSelf();
break;
}
}
/**
* 可用内存大小
* @param fileSize
* @return
*/
private boolean MemoryAvailable(long fileSize) {
fileSize += (1024 << 10);
if (MemoryStatus.externalMemoryAvailable()) {
if ((MemoryStatus.getAvailableExternalMemorySize() <= fileSize)) {
if ((MemoryStatus.getAvailableInternalMemorySize() > fileSize)) {
createFile(false);
return true;
} else {
return false;
}
} else {
createFile(true);
return true;
}
} else {
if (MemoryStatus.getAvailableInternalMemorySize() <= fileSize) {
return false;
} else {
createFile(false);
return true;
}
}
}
/**
* 获取下载进度
* @param downSize
* @param allSize
* @return
*/
public static String getMsgSpeed(long downSize, long allSize) {
StringBuffer sBuf = new StringBuffer();
sBuf.append(getSize(downSize));
sBuf.append("/");
sBuf.append(getSize(allSize));
sBuf.append(" ");
sBuf.append(getPercentSize(downSize, allSize));
return sBuf.toString();
}
/**
* 获取大小
* @param size
* @return
*/
public static String getSize(long size) {
if (size >= 0 && size < SIZE_BT) {
return (double) (Math.round(size * 10) / 10.0) + "B";
} else if (size >= SIZE_BT && size < SIZE_KB) {
return (double) (Math.round((size / SIZE_BT) * 10) / 10.0) + "KB";
} else if (size >= SIZE_KB && size < SIZE_MB) {
return (double) (Math.round((size / SIZE_KB) * 10) / 10.0) + "MB";
}
return "";
}
/**
* 获取到当前的下载百分比
* @param downSize 下载大小
* @param allSize 总共大小
* @return
*/
public static String getPercentSize(long downSize, long allSize) {
String percent = (allSize == 0 ? "0.0" : new DecimalFormat("0.0")
.format((double) downSize / (double) allSize * 100));
return "(" + percent + "%)";
}
/**
* 创建file文件
* @param sd_available sdcard是否可用
*/
private void createFile(boolean sd_available) {
if (sd_available) {
updateDir = new File(Environment.getExternalStorageDirectory(),
MyUtils.updateDownloadDir);
} else {
updateDir = getFilesDir();
}
updateFile = new File(updateDir.getPath(), appName + ".apk");
if (!updateDir.exists()) {
updateDir.mkdirs();
}
if (!updateFile.exists()) {
try {
updateFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
} else {
updateFile.delete();
try {
updateFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
AndroidManifest.xml 中注册服务的代码
8、记得添加权限联网权限、sd卡读写权限...等等
9、在贴出我在开发用到的其它类和方法了。
MemoryStatus,java
/**
* 完成代码的健壮性,其实现在的Android手机的储存都的够用的。
* 一般不会没有空间,有这个类来判断就更健壮一些
*/
public class MemoryStatus {
private static final int ERROR = -1;
// 判断SD卡是否存在?
static public boolean externalMemoryAvailable() {
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
}
// 获取内部存储器有用空间大小?
static public long getAvailableInternalMemorySize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return availableBlocks * blockSize;
}
// 获取内部存储器空间的大小
static public long getTotalInternalMemorySize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
return totalBlocks * blockSize;
}
// 获取SD卡有用空间大小,错误返回-1
static public long getAvailableExternalMemorySize() {
if (externalMemoryAvailable()) {
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return availableBlocks * blockSize;
} else {
return ERROR;
}
}
// 获取SD卡的空间大小,错误返码1
static public long getTotalExternalMemorySize() {
if (externalMemoryAvailable()) {
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
return totalBlocks * blockSize;
} else {
return ERROR;
}
}
/**
* 根据给定的文件的路径来计算文件夹的大小
*
* @param dir 文件的路径
* @return 文件夹的大小
*/
static public long getFileSize(File dir) {
if (dir == null) {
return 0;
}
if (!dir.isDirectory()) {
return 0;
}
long dirSize=0;
File[] files=dir.listFiles();
for (File file : files) {
if(file.isFile())
{
dirSize+=file.length();
}else if (file.isDirectory()) {
dirSize+=getFileSize(file); //如果是目标那就进行递归 来计算文件的大小
}
}
return dirSize;
}
// 把文件大小转化字符串
static public String formatSize(long size) {
Log.d("WL-gui", "文件的大小为:"+size);
String suffix = null;
if(size==0)
{
return "";
}
if (size >= 1024) {
suffix = "KB";
size /= 1024;
if (size >= 1024) {
suffix = "MB";
size /= 1024;
if (size >= 1024) {
suffix = "G";
size /= 1024;
}
}
}
StringBuilder resultBuffer = new StringBuilder(Long.toString(size));
int commaOffset = resultBuffer.length() - 3;
while (commaOffset > 0) {
resultBuffer.insert(commaOffset, ',');
commaOffset -= 3;
}
if (suffix != null)
resultBuffer.append(suffix);
return resultBuffer.toString();
}
}
好了到这,后台知道检测提示更新的代码已经展示完了。接下载就展示一下手动检测的,只需要一行代码就可以了。
第一步:只需要布局文件中添加个按钮(做为演示使用)
activity_main.xml
第二步:在MainActivity.java中去调用就可以了。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void btn(View v){
MyApplication.getServiceUpdateInfo(true);//参数为true,为手动点击检测更新
}
}
结束语:
好了到这就完成这个功能了,希望这篇博客对大家有用,哪里有写的不好的地方,欠缺的地方。欢迎大家指出来。咱们共同进步。谢谢大家啦,如果这篇文章对你有用。
麻烦点个赞。如果博客中有什么问题欢迎大家留言指出问题。