整理两种下载方法,顺便结合了上一篇博客
android 10或者targetSdkVersion=26情况下,升级apk有问题
一、弹窗下载apk,图解大概是下面四张图,下载完成后,点击立即体验才进行安装
弹窗的进度条,引用地址:https://github.com/zhangke3016/SpecialProgressBar
/**
* <p>标题: 升级弹窗</p>
* <p>描述:</p>
*/
public class UpdateDialog extends Dialog {
View view;
TextView tvVersionCode;
TextView tvUpdateInfo;
ScrollView scrollVersionInfo;
RelativeLayout rlyProgress;
SignSeekBar seekBar;
Button btnUpdate;
Button btnCancel;
Button btnNowExperience;
TextView tvDownloading;
TextView tvDowloadSize;
TextView tvAllSize;
private Activity mActivity;
private float versionSize = 0;
private boolean openPermission = false;
private String APK_NAME = "shurufa.apk";
// 地址改成自己apk存放位置
String downloadUrl = "apk存放的服务器地址" + APK_NAME;
DownloadAPK downloadAPK = new DownloadAPK();
private int mProgress = 0; // 进度
private File apkFile;
private String getVersionSize = "8.5M";
public UpdateDialog(Activity mActivity) {
super(mActivity);
this.mActivity = mActivity;
onCreate();
}
protected void onCreate() {
requestWindowFeature(Window.FEATURE_NO_TITLE);
view = View.inflate(mActivity, R.layout.dialog_update, null);
Window window = this.getWindow();
window.setContentView(view);
window.setDimAmount(0f); //去掉遮罩层
window.setBackgroundDrawableResource(android.R.color.transparent); // 背景透明
setCanceledOnTouchOutside(false);
openPermission = PermissionGrantedUtils.isStoragePermissionGranted(mActivity);
initView();
initData();
}
private void initView() {
tvVersionCode = (TextView) view.findViewById(R.id.tv_version_code);
tvUpdateInfo = (TextView) view.findViewById(R.id.tv_update_info);
scrollVersionInfo = (ScrollView) view.findViewById(R.id.scroll_version_info);
rlyProgress = (RelativeLayout) view.findViewById(R.id.rly_progress);
seekBar = (SignSeekBar) view.findViewById(R.id.seek_bar);
tvDownloading = (TextView) view.findViewById(R.id.tv_downloading);
tvDowloadSize = (TextView) view.findViewById(R.id.tv_dowload_size);
tvAllSize = (TextView) view.findViewById(R.id.tv_all_size);
btnUpdate = (Button) view.findViewById(R.id.btn_update);
btnCancel = (Button) view.findViewById(R.id.btn_cancel);
btnNowExperience = (Button) view.findViewById(R.id.btn_now_experience);
// 立即更新
btnUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//增加权限判断,防止权限被关掉,无法升级
openPermission = PermissionGrantedUtils.isStoragePermissionGranted(mActivity);
if (openPermission) {
btnUpdate.setVisibility(View.GONE);
btnCancel.setVisibility(View.VISIBLE);
btnNowExperience.setVisibility(View.GONE);
scrollVersionInfo.setVisibility(View.GONE);
rlyProgress.setVisibility(View.VISIBLE);
downloadAPK.execute(downloadUrl);
} else {
Toast.makeText(mActivity, "请先增加访问SD卡权限!", Toast.LENGTH_LONG).show();
}
}
});
// 取消
btnCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if ("取消".equals(btnCancel.getText().toString())) {
Toast.makeText(mActivity, "已取消下载!", Toast.LENGTH_LONG).show();
downloadAPK.cancel(true);
btnCancel.setText("重新下载");
} else {
downloadAPK = new DownloadAPK();
downloadAPK.execute(downloadUrl);
mProgress = 0;
btnCancel.setText("取消");
}
}
});
//立即体验
btnNowExperience.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
installAPK(apkFile); //打开安装apk文件操作
}
});
}
private void initData() {
String description = "1、开发版本。";
String[] split = description.split("。");
StringBuffer sb = new StringBuffer();
if (split.length >= 1) {
for (int i = 0; i < split.length; i++) {
sb.append(split[i]);
if (i != split.length - 1) {
sb.append(";");
} else {
sb.append("。");
}
}
}
tvUpdateInfo.setText(sb.toString());
tvVersionCode.setText("v1.0.1");
tvDowloadSize.setText("0M");
tvAllSize.setText("/" + getVersionSize);
versionSize = Float.parseFloat(getVersionSize.split("M")[0]);
// seekbar禁止滑动
seekBar.setClickable(false);
seekBar.setEnabled(false);
seekBar.setSelected(false);
seekBar.setFocusable(false);
// 提示牌
seekBar.setValueFormatListener(new SignSeekBar.OnValueFormatListener() {
@Override
public String format(float progress) {
return (int) progress + "%";
}
});
}
public class DownloadAPK extends AsyncTask<String, Integer, String> {
File file;
@Override
protected String doInBackground(String... params) {
URL url;
HttpURLConnection conn;
BufferedInputStream bis = null;
FileOutputStream fos = null;
try {
url = new URL(params[0]);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
int fileLength = conn.getContentLength();
bis = new BufferedInputStream(conn.getInputStream());
file = new File(getExternalStoragePath(), APK_NAME);
if (!file.exists()) {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
file.createNewFile();
}
fos = new FileOutputStream(file);
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = bis.read(data)) != -1) {
total += count;
mProgress = (int) (total * 100 / fileLength);
mUpdateProgressHandler.sendEmptyMessage(1);
fos.write(data, 0, count);
fos.flush();
}
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bis != null) {
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
mProgress = 100;
apkFile = file;
tvDowloadSize.setText(getVersionSize);
tvDownloading.setText("更新完成");
btnUpdate.setVisibility(View.GONE);
btnCancel.setVisibility(View.GONE);
btnNowExperience.setVisibility(View.VISIBLE);
}
}
/**
* 接收消息
*/
@SuppressLint("HandlerLeak")
private Handler mUpdateProgressHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
// 设置进度条
seekBar.setProgress(mProgress);
tvDowloadSize.setText(keep2DecimalPoint2(versionSize * mProgress / 100) + "MB");
break;
}
}
;
};
/**
* 安装Apk
*/
private void installAPK(File file) {
File apkFile = file;
if (!apkFile.exists()) {
return;
}
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri apkUri = FileProvider.getUriForFile(mActivity,
mActivity.getPackageName() + ".fileprovider", apkFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.parse("file://" + apkFile.toString()), "application/vnd.android.package-archive");
}
mActivity.startActivity(intent);
dismiss();
}
/**
* 获取SD下的应用目录,包名文件夹里面
*/
private String getExternalStoragePath() {
StringBuilder sb = new StringBuilder();
sb.append(Environment.getExternalStorageDirectory().getAbsolutePath());
sb.append(File.separator);
sb.append(mActivity.getPackageName());
sb.append(File.separator);
return sb.toString();
}
/**
* 保留两位小数点
*/
public static String keep2DecimalPoint2(double number) {
String formatStr = String.format("%.2f", number);
return formatStr;
}
@Override
public void show() {
super.show();
}
@Override
public void dismiss() {
mActivity.finish();
super.dismiss();
}
}
二、通知栏下载apk,通知栏下载完成后,自动跳转到安装界面
/**
* <p>标题: /p>
* <p>描述:</p>
*/
public class MyAsyncTask extends AsyncTask<String, Integer, Integer> {
private Context context;
private NotificationManager notificationManager;
private NotificationCompat.Builder builder;
// 地址改成自己apk存放位置
private String apkName = "shurufa.apk";
private String savePath = Environment.getExternalStorageDirectory().getPath() + "/mh/";
private String saveFileName = savePath + apkName;
public MyAsyncTask(Context context) {
this.context = context;
notificationManager = (NotificationManager) context.getSystemService(Activity.NOTIFICATION_SERVICE);
builder = new NotificationCompat.Builder(context);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
builder.setSmallIcon(R.mipmap.ic_launcher)
.setVisibility(Notification.VISIBILITY_PUBLIC) // 设置通知
.setContentInfo("下载中...")
.setContentTitle(apkName);
}
@Override
protected Integer doInBackground(String... params) {
File file = new File(saveFileName);
if (!file.exists()) {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
}
Log.e("url", "doInBackground: " + params[0]);
InputStream is = null;
OutputStream os = null;
HttpURLConnection connection = null;
int total_length = 0;
try {
URL url1 = new URL(params[0]);
connection = (HttpURLConnection) url1.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(50000);
connection.connect();
if (connection.getResponseCode() == 200) {
is = connection.getInputStream();
os = new FileOutputStream(saveFileName);
byte[] buf = new byte[1024];
int len;
int pro1 = 0;
int pro2 = 0;
// 获取文件流大小,用于更新进度
long file_length = connection.getContentLength();
while ((len = is.read(buf)) != -1) {
total_length += len;
if (file_length > 0) {
pro1 = (int) ((total_length / (float) file_length) * 100);//传递进度(注意顺序)
}
if (pro1 != pro2) {
// 调用update函数,更新进度
publishProgress(pro2 = pro1);
}
os.write(buf, 0, len);
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (connection != null) {
connection.disconnect();
}
}
return total_length;
}
@Override
protected void onCancelled(Integer integer) {
super.onCancelled(integer);
}
@Override
protected void onCancelled() {
super.onCancelled();
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
builder.setProgress(100, values[0], false);
notificationManager.notify(0x3, builder.build());
//下载进度提示
builder.setContentText("下载" + values[0] + "%");
if (values[0] == 100) { //下载完成后点击安装
Intent it = new Intent(Intent.ACTION_VIEW);
it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
it.setDataAndType(Uri.parse(saveFileName), "application/vnd.android.package-archive");
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, it, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentTitle("下载完成")
.setContentText("点击安装")
.setContentInfo("下载完成")
.setContentIntent(pendingIntent);
notificationManager.notify(0x3, builder.build());
File file = new File(saveFileName);
if (file.exists()) {
openFile(file);
if (notificationManager != null) {
notificationManager.cancel(0x3);//下载完毕 移除通知栏
}
} else {
Toast.makeText(context, "服务端没配置,请联系管理员!", Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
if (integer == 100) {
}
}
//打开APK程序代码
private void openFile(File file) {
// TODO Auto-generated method stub
Log.e("OpenFile", file.getName());
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= 24) {
Uri apkUri = FileProvider.getUriForFile(context, "com.zoesoft.zymobilenurse.fileprovider", file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
}
context.startActivity(intent);
}
}
两个下载方式原理一样,有需要的可以自己整合。
可以参考图解,看是否是自己需要的,然后进行下载代码,有不足之处欢迎之处,谢谢!
源码地址:https://download.csdn.net/download/qq_30543115/12598359