第三方安装库:
//工具库
implementation 'com.blankj:utilcode:1.25.9'
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.provider.Settings;
import android.widget.Toast;
import java.io.File;
/**
* 后台更新
*
*/
public class UpdateService {
private DownloadManager mDownloadManager;
private Context mContext;
private long downloadId;
private String apkName;
public UpdateService() {
}
public UpdateService(Context context) {
mContext = context;
}
public void download(String url, String name) {
final String packageName = "com.android.providers.downloads";
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 (ActivityNotFoundException 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 {
//正常下载流程
apkName = name;
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setAllowedOverRoaming(false);
//通知栏显示
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle(AppUtils.getAppName(mContext));
request.setDescription("正在下载中...");
request.setVisibleInDownloadsUi(true);
//设置下载的路径
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkName + ".apk");
//获取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:
break;
//下载延迟
case DownloadManager.STATUS_PENDING:
break;
//正在下载
case DownloadManager.STATUS_RUNNING:
break;
//下载完成
case DownloadManager.STATUS_SUCCESSFUL:
installAPK();
break;
//下载失败
case DownloadManager.STATUS_FAILED:
Toast.makeText(mContext, "下载失败", Toast.LENGTH_SHORT).show();
break;
}
}
cursor.close();
}
/**
* 安装
*/
private void installAPK() {
File apkFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), apkName + ".apk");
com.blankj.utilcode.util.AppUtils.installApp(apkFile);
}
}
使用:
now_update.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UpdateService updateService = new UpdateService(MaintActivity.this);
updateService.download(url , "");
}
});
AppUtils
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.Window;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class AppUtils {
Context context;
private static AlertDialog dialog;
/**
* 获取应用程序名称
*/
public static synchronized String getAppName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
int labelRes = packageInfo.applicationInfo.labelRes;
return context.getResources().getString(labelRes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取当前app version name
*/
public static String getAppVersionName(Context context) {
String appVersionName = "";
try {
PackageInfo packageInfo = context.getApplicationContext()
.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
appVersionName = packageInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
}
return appVersionName;
}
/**
* 获取图标 bitmap
* @param context
* @return
*/
public static synchronized String getBitmap(Context context) {
PackageManager packageManager = null;
ApplicationInfo applicationInfo = null;
try {
packageManager = context.getApplicationContext()
.getPackageManager();
applicationInfo = packageManager.getApplicationInfo(
context.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
applicationInfo = null;
}
Drawable d = packageManager.getApplicationIcon(applicationInfo); //xxx根据自己的情况获取drawable
BitmapDrawable bd = (BitmapDrawable) d;
Bitmap bm = bd.getBitmap();
return String.valueOf(bm);
}
/**
* 将图片保存到系统相册
*
* @param context
* @param bmp
*/
public static void saveImageToGallery(Context context, Bitmap bmp) {
// 首先保存图片
File appDir = new File(Environment.getExternalStorageDirectory(), "***");
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 其次把文件插入到系统图库
try {
MediaStore.Images.Media.insertImage(context.getContentResolver(),
file.getAbsolutePath(), fileName, null);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 最后通知图库更新
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(file.getPath()))));
// 弹出保存图片的对话框
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("保存成功\n\n1.打开微信扫描 相册二维码\n\n2.点击关注并绑定");
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialog.cancel();
}
});
dialog = builder.create();
Window window = dialog.getWindow();
window.setWindowAnimations(R.style.AlertAnimation);
dialog.show();
}
}
R.style.AlertAnimation // 从屏幕中间 由小到大的展开
<!-- AlertDialog 的动画效果 -->
<style name="AlertAnimation">
<item name="android:windowExitAnimation">@anim/alert_cancel</item>
<item name="android:windowEnterAnimation">@anim/alert_in</item>
</style>
alert_cancel.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="400"
>
<scale
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.0"
android:toYScale="0.0" />
</set>
alert_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="400"
>
<scale
android:fromXScale="0.0"
android:fromYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0"
/>
</set>