技术标签: APP更新相关 技术总结 工具类 utils 下载
/**
* 下载的工具类
* Created by zhuzi on 2019/12/04.
*/
public class DownloadUtils {
private static final String TAG = "DownloadUtils";
private DownloadManager mDownloadManager;
private static Context mContext;
private long downloadId;
private File apkFile;
private Notification mNotification;
private NotificationManager mNotificationManager;
public static final String UPDATE = "UPDATE";
public DownloadUtils(Context context) {
mContext = context;
}
public void download(String url, String name, String file_size) {
try {
apkFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), name);
Log_Ma.e(TAG, "download: 下载的工具类/" + apkFile.toString() + "/" + GetFileSize(apkFile) + "/" + file_size);
if (apkFile.exists()) {
boolean upda = (boolean) SPUtils.get(mContext, UPDATE, false);
if (upda) {
installAPK(apkFile);
} else {
ToastUtils.showToast("正在下载中");
}
} else {
downAPK(url, name);
}
} catch (Exception e) {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
mContext.startActivity(intent);
Log_Ma.e("更新", e.getMessage());
}
}
private String getSDPath() {
File sdDir = null;
boolean sdCardExist = Environment.getExternalStorageState()
.equals(Environment.MEDIA_MOUNTED);
//判断sd卡是否存在
if (sdCardExist) {
//获取跟目录
sdDir = Environment.getExternalStorageDirectory();
}
return sdDir.toString();
}
private void downAPK(String url, String name) {
final String packageName = "com.anrongtec.zcpt";
int state = mContext.getPackageManager().getApplicationEnabledSetting(packageName);
//检测下载管理器是否被禁用
if (state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|| state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
|| state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext).setTitle("温馨提示").setMessage
("系统下载管理器被禁止,需手动打开").setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
try {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + packageName));
mContext.startActivity(intent);
} catch (Exception e) {
Intent intent = new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
mContext.startActivity(intent);
}
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
} else {
//正常下载流程
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setAllowedOverRoaming(false);
//通知栏显示
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle("新版本安装");
request.setDescription("正在下载中...");
request.setVisibleInDownloadsUi(true);
//设置下载的路径
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, name);
//获取DownloadManager
mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
downloadId = mDownloadManager.enqueue(request);
mContext.registerReceiver(mReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
checkStatus();
}
};
/**
* 检查下载状态
*/
private void checkStatus() {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadId);
Cursor cursor = mDownloadManager.query(query);
if (cursor.moveToFirst()) {
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch (status) {
case DownloadManager.STATUS_PAUSED:
//下载暂停
SPUtils.put(mContext, UPDATE, false);
break;
case DownloadManager.STATUS_PENDING:
//当下载等待开始时。
SPUtils.put(mContext, UPDATE, false);
break;
case DownloadManager.STATUS_RUNNING:
//正在下载
SPUtils.put(mContext, UPDATE, false);
break;
case DownloadManager.STATUS_SUCCESSFUL:
//下载完成
SPUtils.put(mContext, UPDATE, true);
installAPK(apkFile);
break;
case DownloadManager.STATUS_FAILED:
//下载失败
ToastUtils.showToast("下载失败");
break;
}
}
cursor.close();
}
/**
* 7.0兼容
*/
public static void installAPK(File apkFile) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//7.0以上权限问题
Uri apkUri = FileProvider.getUriForFile(BaseApplication.getContext(), "com.jiada.selection.fileprovider", apkFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
}
BaseApplication.getContext().startActivity(intent);
}
public String GetFileSize(File file) {
String size = "";
if (file.isFile()) {
long fileS = file.length();
DecimalFormat df = new DecimalFormat("#.00");
if (fileS < 1024) {
size = df.format((double) fileS);
} else if (fileS < 1048576) {
size = df.format((double) fileS / 1024);
} else if (fileS < 1073741824) {
size = df.format((double) fileS / 1048576);
} else {
size = df.format((double) fileS / 1073741824);
}
} else if (file.exists() && file.isDirectory()) {
size = "";
} else {
size = "";
}
Log_Ma.e(TAG, "GetFileSize: 下载的工具类/" + size);
return size;
}
/**
* 安装apk文件
*
* @return
*/
private PendingIntent getInstallIntent() {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//7.0以上权限问题
Uri apkUri = FileProvider.getUriForFile(mContext, "com.anrongtec.zcpt.fileprovider", apkFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
}
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
private void notifyMsg(String title, String content, int progress) {
mNotificationManager = (NotificationManager) mContext.getSystemService(Service.NOTIFICATION_SERVICE);
//为了向下兼容,这里采用了v7包下的NotificationCompat来构造
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
builder.setSmallIcon(R.mipmap.app_logo).setContentTitle(title);
if (progress > 0 && progress < 100) {
//下载进行中
builder.setProgress(100, progress, false);
} else {
builder.setProgress(0, 0, false);
}
builder.setAutoCancel(true);
builder.setWhen(System.currentTimeMillis());
builder.setContentText(content);
if (progress >= 100) {
//下载完成
builder.setContentIntent(getInstallIntent());
}
mNotification = builder.build();
mNotificationManager.notify(0, mNotification);
}
public static void update(final Bean_Update update, final String token, final Context context, final OnUpdate onUpdate) {
new XPopup.Builder(context)
.dismissOnTouchOutside(false)
.asCustom(new CenterPopupView(context) {
@Override
protected int getImplLayoutId() {
return R.layout.dialog_update;
}
@Override
protected void onCreate() {
super.onCreate();
final String down_URL = update.getData().getExpFileId();
Log_Ma.e(TAG, "onCreate: " + down_URL);
ImageView down_Imag = findViewById(R.id.umeng_wifi_indicator1);
TextView update_content = findViewById(R.id.update_content);
TextView btn_update_id_cancel = findViewById(R.id.btn_update_id_cancel);
if (update.getData().force) {
btn_update_id_cancel.setVisibility(GONE);
} else {
btn_update_id_cancel.setVisibility(VISIBLE);
}
final TextView btn_update_id_ok = findViewById(R.id.btn_update_id_ok);
final NumberProgressView numberProgressBar = findViewById(R.id.numberProgressBar);
update_content.setText(update.data.getVersionDesc());
btn_update_id_ok.setText("立即更新");
down_Imag.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse(down_URL);
Intent viewIntent = new Intent(Intent.ACTION_VIEW, uri);
context.startActivity(viewIntent);
}
});
btn_update_id_cancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onUpdate.btnUpdateIdCancel(token);
}
});
btn_update_id_ok.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
numberProgressBar.setVisibility(VISIBLE);
btn_update_id_ok.setText("正在下载");
OkGo.<File>get(down_URL)
.tag(this)
.execute(new FileCallback(FileUtils.path, FileUtils.StoreName) {
@Override
public void onSuccess(Response<File> response) {
btn_update_id_ok.setText("正在安装");
numberProgressBar.setVisibility(GONE);
installAPK(response.body());
numberProgressBar.setProgress(0);
}
@Override
public void downloadProgress(Progress progress) {
try {
int dou = (int) ((float) progress.currentSize / Long.parseLong(update.getData().getExpSize()) * 100);
Log_Ma.e(TAG, "downloadProgress: " + "/" + dou + "/" + progress.currentSize + "/" + update.getData().getExpSize());
numberProgressBar.setProgress(dou);
} catch (Exception e) {
numberProgressBar.setVisibility(GONE);
}
}
});
onUpdate.btnUpdateIdOk(token);
}
});
}
}).show();
}
public interface OnUpdate {
void btnUpdateIdCancel(String token);
void btnUpdateIdOk(String string);
}
}
Make 就是针对上面问题所设计的工具:它首先允许开发者编写一种平台无关的 CMakeList.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。从而做到“Write once, run everywhere”。
秒懂HC-SR501红外感测器Arduino UNO实作HC-SR501是怎么运作的? 这个模块的核心实际上是由一个 热电感测器 组成,当这个感测器 暴露在热量下 的时候会 生成能量 ,并转化成电讯号。那么,也就是说,当一个人走进他的感测范围之后,他的移动将被HC-SR501感测到,因为 人体 会不断地 以红外线的形式散发...
1、BGA最外边的两圈pin最好直接走线走出来,不要在BGA封装FPGA器件周围比较近的地方打孔换层走线,因为会阻挡BGA里面的引脚走线出来。2、及时删除掉没用的Fanout出来的过孔,不要让没用的过孔影响你的走线。3、当6层板时候,有4层可以进行走线,优先走TOP层和BOTTOM层,我的顺序是TOP层走BGA外边圈1、2层的走线,BOTTOM走3、4层的走线,一般来说SIG3可以负责更深入层的走...
AfghanistanAland IslandsAlbaniaAlgeriaAmerican SamoaAndorraAngolaAnguillaAntarcticaAntigua and BarbudaArgentinaArmeniaArubaAustraliaAustriaAzerbaijanBahamasBahrainBangladeshBarbadosBelarusBelgiumBeliz...
数组作业:def main(args: Array[String]) { var flag : Boolean = true def isNegative(n : Int) : Boolean = { if(flag) if(n flag = false return true
准备步骤:1.下载vscode:Visual Studio Code - Code Editing. Redefined2.vscode下载PlatformIO插件3.下载STM32CubeMX:STM32CubeMX - STM32Cube initialization code generator - STMicroelectronics1.新建空白项目文件夹,例platformIO_demo2.使用vscode打开此文件夹,打开PlatformIO插件主页3.新建项目:Op
python在Windows环境下文件路径:之前在用python打开一些文件的时候一直出错,后来发现是文件的路径有问题。win下路径使用单斜杠 \python下\为转义,所有要用双斜杠\\来隔开路径,或者可以采用r“(路径地址)”的写法。相对路径相关写法:../ 表示当前文件所在的目录的上一级目录./ 表示当前文件所在的目录(可以省略)/ 表示当前站点的根目录(域名映射的硬盘目录)...
在python中,模拟http客户端发送get和post请求,主要用httplib模块的功能。1、python发送GET请求我在本地建立一个测试环境,test.php的内容就是输出一句话:echo 'Old friends and old wines are best.';python发送get请求代码:#!/usr/bin/env python#coding=utf8import httplib...
来人呀,给这位道友赐座!????我以创建一台云主机的整体思路来贯彻每个组件的增、删、改、查。因此,创建一台虚拟机需要有flavor、image、neutron、secgroup、service、keypair、floatingip。1.flavor:$ nova flavor-list #列出所有云主机类型$ nova flavor-show 00fc2b8e-d5d7-4629-a9fb-04709193b979(flavorID) #某一个云主机类型的详情$ nova fla
maven编译总是卡在这里好久才能过去,每次编译都要等好久,浪费时间解决办法,设置maven的setting.xml,修改mirrors,加入阿里云配置因为本地仓库找不到,默认不配置镜像,会自动去repo.maven.apache.org这个地址去下载,所以这里配置mirror为阿里云的镜像<mirrors> <mirror> <id>aliyun-central</id> <mirrorOf>central.
主要记录一下element-plus组件的一些实用技巧和注意事项,同时会提供对应的代码示例。
【matlab】eps 意义及用法MATLAB中eps是一个函数,可以返回某一个数N的最小浮点数精度,形式例如eps(N)。一般直接用eps即可。eps = eps(1) = 2.2204e-161 == 1 + eps: false1 == 1 + eps * 0.51: false1 == 1 + eps * 0.5: true (<=0.5 时为true)用法: 一般用在分...