android版本更新java工具类:
public class UpdateApk {
private static long downloadId;
private static String mUrl;
private static final String loadDocument = "/" + MyApp.mApp.getPackageName() + "/public/";
private static final String loadApkName = "pos.apk";
private static final String appPath = Environment.getExternalStorageDirectory().getAbsolutePath() + loadDocument + loadApkName;
private static final String installType = "application/vnd.android.package-archive";
private static ScheduledExecutorService service;
private static ProgressDialog progressDialog;
public static void loadApp(Activity context, String url) {
mUrl = url;
int installCode = UpdateApk.getInstallAppVersionCode(context);
int uninstallCode = UpdateApk.getUninstallAppVersonCode(appPath);
LogUtil.e("installCode", installCode + "uninstallCode" + uninstallCode);
File file = new File(appPath);
if (UpdateApk.hasMyApp(file)) {
if (uninstallCode == -1) {
notLoadSuccess(context, file);
} else if (installCode < uninstallCode) {
LoadSuccess(context, file);
} else {
oldApp(context, file);
}
} else {
firstLoad(context);
}
}
//还没下载完
private static void notLoadSuccess(Activity context, File file) {
downloadId = SharedData.getInstance().getLong(Constant.SHARE_APP_DOWNLOADID, 0);
deletApk(file);
startLoad(context);
}
//已经下载完成未安装
private static void LoadSuccess(Activity context, File file) {
UpdateApk.installApk(context, file);
}
//上一个版本的app
private static void oldApp(Activity context, File file) {
UpdateApk.deletApk(file);
startLoad(context);
}
//第一次下载
private static void firstLoad(Activity context) {
startLoad(context);
}
private static void startLoad(final Activity context) {
if (canDownloadState(context)) {
try {
final DownloadManager downloadManager = (DownloadManager) context.getSystemService(context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(mUrl));
// // 设置允许使用的网络类型,这里是移动网络和wifi都可以
request.setAllowedNetworkTypes(request.NETWORK_WIFI | request.NETWORK_MOBILE);
request.setDestinationInExternalPublicDir(loadDocument, loadApkName);
// //设置文件类型
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(mUrl));
request.setMimeType(mimeString);
// //在通知栏中显示
request.setNotificationVisibility(request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle(MyApp.mApp.getResources().getString(R.string.app_name));
request.setVisibleInDownloadsUi(true);
// //sdcard目录下的download文件夹
downloadId = downloadManager.enqueue(request);
SharedData.getInstance().put(Constant.SHARE_APP_DOWNLOADID, downloadId).commit();
registerBroad(context);
showDownloadDialog(context);
Runnable thread = new Runnable() {
@Override
public void run() {
query(downloadManager, context);
}
};
service = Executors.newScheduledThreadPool(1);
service.scheduleAtFixedRate(thread, 100, 100, TimeUnit.MILLISECONDS);
} catch (Exception e) {
LogUtil.e("exception", e.getMessage());
viewDownload(context);
}
}
}
private static void viewDownload(Context context) {
Intent it = new Intent(Intent.ACTION_VIEW);
it.setData(Uri.parse(mUrl)); //这里面是需要调转的rul
it = Intent.createChooser(it, null);
context.startActivity(it);
}
private static void registerBroad(Activity context) {
//注册下载完成的广播
IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
context.registerReceiver(downloadReceiver, filter);
}
private static BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long completeDownloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (completeDownloadId == downloadId) {
// if download successful
if (service != null && !service.isShutdown()) {
service.shutdown();
}
if (progressDialog != null) {
progressDialog.dismiss();
}
File file = new File(appPath);
installApk(context, file);
}
}
};
//安装apk
private static void installApk(Context context, File file) {
LogUtil.e("installApk->", file.getAbsolutePath());
Intent intent = new Intent();
//执行动作
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//执行的数据类型
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
LogUtil.e("installApkaa->", file.getAbsolutePath());
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(context, MyApp.mApp.getPackageName() + ".fileprovider"
, file);
intent.setDataAndType(contentUri, installType);
} else {
LogUtil.e("installApkbb->", file.getAbsolutePath());
intent.setDataAndType(Uri.fromFile(file), installType);
}
context.startActivity(intent);
context.unregisterReceiver(downloadReceiver);
((Activity) context).finish();
}
//获取当前应用的versionCode
private static int getInstallAppVersionCode(Context context) {
try {
return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return 0;
}
}
//获取未安装应用的versionCode
private static int getUninstallAppVersonCode(String apkPath) {
PackageManager pm = MyApp.mApp.getPackageManager();
PackageInfo info = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
int appCode = 0;
if (info != null) {
appCode = info.versionCode;
} else {
appCode = -1;
}
return appCode;
}
//删除自己的apk
private static void deletApk(File file) {
file.delete();
}
//查看是否有自己的apk
private static boolean hasMyApp(File file) {
if (file.exists()) {
return true;
}
return false;
}
private static boolean isNetError = false;
private static Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case DISMISS:
progressDialog.dismiss();
ToastUtil.ToastMessage("网络异常,请连接网络继续加载", ToastUtil.WARN);
break;
case SHOW:
progressDialog.show();
break;
case PROGRESS:
LogUtil.e("PROGRESS", "PROGRESS");
int progress = msg.getData().getInt("progress");
int total = msg.getData().getInt("total");
progressDialog.setProgress(progress);
progressDialog.setMax(total);
break;
}
}
};
private static final int DISMISS = 1;
private static final int SHOW = 2;
private static final int PROGRESS = 3;
private static void query(DownloadManager downloadManager, Context context) {
LogUtil.e("query->", "downloadManager->");
if (!NetUtil.isConnected(context)) {
if (!isNetError) {
isNetError = true;
handler.sendEmptyMessage(DISMISS);
}
} else {
if (isNetError) {
isNetError = false;
handler.sendEmptyMessage(SHOW);
}
}
DownloadManager.Query downloadQuery = new DownloadManager.Query();
downloadQuery.setFilterById(downloadId);
Cursor cursor = downloadManager.query(downloadQuery);
if (cursor != null && cursor.moveToFirst()) {
int totalSizeBytesIndex = cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
int bytesDownloadSoFarIndex = cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
// 下载的文件总大小
int totalSizeBytes = cursor.getInt(totalSizeBytesIndex);
// 截止目前已经下载的文件总大小
int bytesDownloadSoFar = cursor.getInt(bytesDownloadSoFarIndex);
int total = 100;
int progress = bytesDownloadSoFar * 100 / totalSizeBytes;
Message message = new Message();
message.what = PROGRESS;
Bundle bundle = new Bundle();
bundle.putInt("progress", progress);
bundle.putInt("total", total);
message.setData(bundle);
handler.sendMessage(message);
cursor.close();
}
}
private static boolean canDownloadState(Context ctx) {
try {
int state = ctx.getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads");
if (state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|| state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
|| state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
try {
openDownload(ctx);
// EventBus.getDefault().post(new DownloadEvent());
} catch (ActivityNotFoundException e) {
// Open the generic Apps page:
viewDownload(ctx);
}
return false;
}
} catch (Exception e) {
e.printStackTrace();
viewDownload(ctx);
return false;
}
return true;
}
public static void openDownload(Context context) {
String packageName = "com.android.providers.downloads";
// Open the specific App Info page:
Intent intent = new Intent(
android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + packageName));
context.startActivity(intent);
}
private static void showDownloadDialog(Activity context) {
progressDialog = new ProgressDialog(context);
progressDialog.setTitle("正在下载...");
progressDialog.setCancelable(false);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.show();
}
}
manifest中需要配置:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
filepaths中的配置:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path
name="external"
path="" />
<files-path
name="files"
path="" />
<cache-path
name="cache"
path="" />
</paths>
</resources>
注意:如果是androidx版本的sdk则需要修改下保存的路径,还有provider
androidx的java代码:
public class UpdateApk {
private static long downloadId;
private static String mUrl;
private static final String loadDocument = String.valueOf(MyApp.mApp.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS));
private static final String loadApkName = "pos.apk";
private static final String appPath = loadDocument + "/"+ loadApkName;
private static final String installType = "application/vnd.android.package-archive";
private static ScheduledExecutorService service;
private static ProgressDialog progressDialog;
public static void loadApp(Activity context, String url) {
mUrl = url;
int installCode = UpdateApk.getInstallAppVersionCode(context);
int uninstallCode = UpdateApk.getUninstallAppVersonCode(appPath);
LogUtil.e("installCode", installCode + "uninstallCode" + uninstallCode + appPath);
File file = new File(appPath);
if (UpdateApk.hasMyApp(file)) {
if (uninstallCode == -1) {
notLoadSuccess(context, file);
} else if (installCode < uninstallCode) {
LoadSuccess(context, file);
} else {
oldApp(context, file);
}
} else {
firstLoad(context);
}
}
//还没下载完
private static void notLoadSuccess(Activity context, File file) {
downloadId = SharedData.getInstance().getLong(Constant.SHARE_APP_DOWNLOADID, 0);
deletApk(file);
startLoad(context);
}
//已经下载完成未安装
private static void LoadSuccess(Activity context, File file) {
UpdateApk.installApk(context, file);
}
//上一个版本的app
private static void oldApp(Activity context, File file) {
UpdateApk.deletApk(file);
startLoad(context);
}
//第一次下载
private static void firstLoad(Activity context) {
startLoad(context);
}
private static void startLoad(final Activity context) {
if (canDownloadState(context)) {
try {
final DownloadManager downloadManager = (DownloadManager) context.getSystemService(context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(mUrl));
// // 设置允许使用的网络类型,这里是移动网络和wifi都可以
request.setAllowedNetworkTypes(request.NETWORK_WIFI | request.NETWORK_MOBILE);
// request.setDestinationInExternalPublicDir(loadDocument, loadApkName);
request.setDestinationInExternalFilesDir(MyApp.mApp, Environment.DIRECTORY_DOWNLOADS, loadApkName);
// //设置文件类型
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(mUrl));
request.setMimeType(mimeString);
// //在通知栏中显示
request.setNotificationVisibility(request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle(MyApp.mApp.getResources().getString(R.string.app_name));
request.setVisibleInDownloadsUi(true);
// //sdcard目录下的download文件夹
downloadId = downloadManager.enqueue(request);
SharedData.getInstance().put(Constant.SHARE_APP_DOWNLOADID, downloadId).commit();
registerBroad(context);
showDownloadDialog(context);
Runnable thread = new Runnable() {
@Override
public void run() {
query(downloadManager, context);
}
};
service = Executors.newScheduledThreadPool(1);
service.scheduleAtFixedRate(thread, 100, 100, TimeUnit.MILLISECONDS);
} catch (Exception e) {
LogUtil.e("exception", e.getMessage());
viewDownload(context);
}
}
}
private static void viewDownload(Context context) {
Intent it = new Intent(Intent.ACTION_VIEW);
it.setData(Uri.parse(mUrl)); //这里面是需要调转的rul
it = Intent.createChooser(it, null);
context.startActivity(it);
}
private static void registerBroad(Activity context) {
//注册下载完成的广播
IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
context.registerReceiver(downloadReceiver, filter);
}
private static BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long completeDownloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (completeDownloadId == downloadId) {
// if download successful
if (service != null && !service.isShutdown()) {
service.shutdown();
}
if (progressDialog != null) {
progressDialog.dismiss();
}
File file = new File(appPath);
installApk(context, file);
}
}
};
//安装apk
private static void installApk(Context context, File file) {
LogUtil.e("installApk->", file.getAbsolutePath());
Intent intent = new Intent();
//执行动作
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//执行的数据类型
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
LogUtil.e("installApkaa->", file.getAbsolutePath());
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(context, MyApp.mApp.getPackageName() + ".fileprovider"
, file);
intent.setDataAndType(contentUri, installType);
} else {
LogUtil.e("installApkbb->", file.getAbsolutePath());
intent.setDataAndType(Uri.fromFile(file), installType);
}
context.startActivity(intent);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
((Activity) context).finish();
}
//获取当前应用的versionCode
private static int getInstallAppVersionCode(Context context) {
try {
return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return 0;
}
}
//获取未安装应用的versionCode
private static int getUninstallAppVersonCode(String apkPath) {
PackageManager pm = MyApp.mApp.getPackageManager();
PackageInfo info = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
int appCode = 0;
if (info != null) {
appCode = info.versionCode;
} else {
appCode = -1;
}
return appCode;
}
//删除自己的apk
private static void deletApk(File file) {
file.delete();
}
//查看是否有自己的apk
private static boolean hasMyApp(File file) {
if (file.exists()) {
return true;
}
return false;
}
private static boolean isNetError = false;
private static Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case DISMISS:
progressDialog.dismiss();
ToastUtil.ToastMessage("网络异常,请连接网络继续加载", ToastUtil.WARN);
break;
case SHOW:
progressDialog.show();
break;
case PROGRESS:
LogUtil.e("PROGRESS", "PROGRESS");
int progress = msg.getData().getInt("progress");
int total = msg.getData().getInt("total");
progressDialog.setProgress(progress);
progressDialog.setMax(total);
break;
}
}
};
private static final int DISMISS = 1;
private static final int SHOW = 2;
private static final int PROGRESS = 3;
private static void query(DownloadManager downloadManager, Context context) {
LogUtil.e("query->", "downloadManager->");
if (!NetUtil.isConnected(context)) {
if (!isNetError) {
isNetError = true;
handler.sendEmptyMessage(DISMISS);
}
} else {
if (isNetError) {
isNetError = false;
handler.sendEmptyMessage(SHOW);
}
}
DownloadManager.Query downloadQuery = new DownloadManager.Query();
downloadQuery.setFilterById(downloadId);
Cursor cursor = downloadManager.query(downloadQuery);
if (cursor != null && cursor.moveToFirst()) {
int totalSizeBytesIndex = cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
int bytesDownloadSoFarIndex = cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
// 下载的文件总大小
long totalSizeBytes = cursor.getLong(totalSizeBytesIndex);
// 截止目前已经下载的文件总大小
long bytesDownloadSoFar = cursor.getLong(bytesDownloadSoFarIndex);
int total = 100;
int progress = (int) (bytesDownloadSoFar * 100 / totalSizeBytes);
Message message = new Message();
message.what = PROGRESS;
Bundle bundle = new Bundle();
bundle.putInt("progress", progress);
bundle.putInt("total", total);
message.setData(bundle);
handler.sendMessage(message);
cursor.close();
}
}
private static boolean canDownloadState(Context ctx) {
try {
int state = ctx.getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads");
if (state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|| state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
|| state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
try {
openDownload(ctx);
// EventBus.getDefault().post(new DownloadEvent());
} catch (ActivityNotFoundException e) {
// Open the generic Apps page:
viewDownload(ctx);
}
return false;
}
} catch (Exception e) {
e.printStackTrace();
viewDownload(ctx);
return false;
}
return true;
}
public static void openDownload(Context context) {
String packageName = "com.android.providers.downloads";
// Open the specific App Info page:
Intent intent = new Intent(
android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + packageName));
context.startActivity(intent);
}
private static void showDownloadDialog(Activity context) {
progressDialog = new ProgressDialog(context);
progressDialog.setTitle("正在下载...");
progressDialog.setCancelable(false);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.show();
}
}
manifest中需要配置:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
filepaths代码:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path
name="external"
path="" />
<external-files-path path="/download" name="download"/>
<files-path
name="files"
path="" />
<cache-path
name="cache"
path="" />
</paths>
</resources>