源码整理
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#Created by .winboll/winboll_app_build.gradle
|
||||
#Wed Dec 03 08:28:19 GMT 2025
|
||||
#Wed Dec 03 09:19:24 GMT 2025
|
||||
stageCount=13
|
||||
libraryProject=
|
||||
baseVersion=15.11
|
||||
publishVersion=15.11.12
|
||||
buildCount=121
|
||||
buildCount=122
|
||||
baseBetaVersion=15.11.13
|
||||
|
||||
@@ -197,18 +197,6 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
LogUtils.d(TAG, "【分享接收】onAcceptRecivedPicture 触发,图片名:" + szPreRecivedPictureName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新背景预览(强制使用预览Bean,全程不操作正式Bean)
|
||||
*/
|
||||
// public void updateBackgroundView(File sourceFile, String sourceFileInfo) {
|
||||
// LogUtils.d(TAG, "【预览更新】updateBackgroundView 触发,sourceFile是否为空:" + (sourceFile == null));
|
||||
// if (sourceFile != null) {
|
||||
// mBgSourceUtils.saveFileToPreviewBean(sourceFile, sourceFileInfo); // 同步到预览Bean
|
||||
// }
|
||||
// mBackgroundView.loadBackground2(mBgSourceUtils.getPreviewBackgroundBean());
|
||||
// LogUtils.d(TAG, "【预览更新】预览背景更新完成(强制使用previewBackgroundBean)");
|
||||
// }
|
||||
|
||||
// ======================================== 按钮点击事件(仅UI交互) ========================================
|
||||
/**
|
||||
* 点击事件:取消背景(仅操作Bean,无文件逻辑)
|
||||
@@ -216,17 +204,11 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
private View.OnClickListener onOriginNullClickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
LogUtils.d(TAG, "【按钮点击】触发取消背景功能");
|
||||
LogUtils.d(TAG, "【按钮点击】触发取消背景图片功能");
|
||||
// 1. 修改正式Bean
|
||||
BackgroundBean currentBackgroundBean = mBgSourceUtils.getCurrentBackgroundBean();
|
||||
currentBackgroundBean.setIsUseBackgroundFile(false);
|
||||
currentBackgroundBean.resetBackgroundConfig();
|
||||
mBgSourceUtils.saveSettings();
|
||||
// 2. 同步预览Bean(关键优化:确保控件刷新后显示“取消背景”状态)
|
||||
mBgSourceUtils.setCurrentSourceToPreview();
|
||||
// 3. 控件刷新(仍依赖预览Bean)
|
||||
doubleRefreshPreview();
|
||||
ToastUtils.show("背景已取消");
|
||||
BackgroundBean previewBackgroundBean = mBgSourceUtils.getPreviewBackgroundBean();
|
||||
previewBackgroundBean.setIsUseBackgroundFile(false);
|
||||
doubleRefreshPreview();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -317,29 +299,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
LogUtils.d(TAG, "【按钮点击】触发固定比例裁剪功能");
|
||||
File targetFile = new File(mBgSourceUtils.getCurrentBackgroundFilePath());
|
||||
if (targetFile.exists()) {
|
||||
// 适配MIUI:弹出裁剪提示(建议选择系统相机)
|
||||
if (Build.MANUFACTURER.equalsIgnoreCase("Xiaomi")) {
|
||||
new AlertDialog.Builder(BackgroundSettingsActivity.this)
|
||||
.setTitle("裁剪提示")
|
||||
.setMessage("若裁剪失败,请选择「系统相机」作为裁剪工具")
|
||||
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
startCropImageActivity(false); // 启动固定比例裁剪
|
||||
}
|
||||
})
|
||||
.setNegativeButton("取消", null)
|
||||
.show();
|
||||
} else {
|
||||
startCropImageActivity(false); // 非MIUI机型直接启动裁剪
|
||||
}
|
||||
LogUtils.d(TAG, "【裁剪启动】固定比例裁剪已启动");
|
||||
} else {
|
||||
ToastUtils.show("无可用裁剪图片,请先选择/拍照");
|
||||
LogUtils.e(TAG, "【裁剪失败】无可用裁剪图片");
|
||||
}
|
||||
startCropImageActivity(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -350,29 +310,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
LogUtils.d(TAG, "【按钮点击】触发自由裁剪功能");
|
||||
File targetFile = new File(mBgSourceUtils.getCurrentBackgroundFilePath());
|
||||
if (targetFile.exists()) {
|
||||
// 适配MIUI:弹出裁剪提示(建议选择系统相机)
|
||||
if (Build.MANUFACTURER.equalsIgnoreCase("Xiaomi")) {
|
||||
new AlertDialog.Builder(BackgroundSettingsActivity.this)
|
||||
.setTitle("裁剪提示")
|
||||
.setMessage("若裁剪失败,请选择「系统相机」作为裁剪工具")
|
||||
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
startCropImageActivity(true); // 启动自由裁剪
|
||||
}
|
||||
})
|
||||
.setNegativeButton("取消", null)
|
||||
.show();
|
||||
} else {
|
||||
startCropImageActivity(true); // 非MIUI机型直接启动裁剪
|
||||
}
|
||||
LogUtils.d(TAG, "【裁剪启动】自由裁剪已启动");
|
||||
} else {
|
||||
ToastUtils.show("无可用裁剪图片,请先选择/拍照");
|
||||
LogUtils.e(TAG, "【裁剪失败】无可用裁剪图片");
|
||||
}
|
||||
startCropImageActivity(true);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -483,7 +421,6 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean();
|
||||
previewBean.setIsUseBackgroundScaledCompressFile(false);
|
||||
mBgSourceUtils.saveSettings();
|
||||
|
||||
doubleRefreshPreview();
|
||||
|
||||
File previewFile = new File(previewBean.getBackgroundFilePath()); // 裁剪缓存图片
|
||||
@@ -625,123 +562,6 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
return gcdResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存裁剪后的图片(修复:路径同步时序+压缩图路径强绑定)
|
||||
* 作用:裁剪后保存原图→生成压缩图→同步双路径到预览Bean→清理临时文件
|
||||
*/
|
||||
// private void saveCropBitmap(Bitmap bitmap) {
|
||||
// LogUtils.d(TAG, "【保存启动】开始保存裁剪图片(仅更新预览Bean,不影响正式Bean)");
|
||||
// if (bitmap == null || bitmap.isRecycled()) {
|
||||
// ToastUtils.show("裁剪图片为空");
|
||||
// //mBgSourceUtils.clearCropTempFiles();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // 内存优化:大图片自动缩放(保留原有逻辑,避免OOM)
|
||||
// Bitmap scaledBitmap = bitmap;
|
||||
// int originalSize = bitmap.getByteCount() / 1024 / 1024;
|
||||
// if (originalSize > 5) {
|
||||
// float scale = 1.0f;
|
||||
// while (scaledBitmap.getByteCount() / 1024 / 1024 > 2) {
|
||||
// scale -= 0.2f;
|
||||
// if (scale < 0.2f) break;
|
||||
// scaledBitmap = scaleBitmap(scaledBitmap, scale); // 复用原有缩放方法
|
||||
// }
|
||||
// LogUtils.d(TAG, "【内存优化】大图片自动缩放:原始大小=" + originalSize + "MB,缩放后大小=" + scaledBitmap.getByteCount() / 1024 / 1024 + "MB");
|
||||
// }
|
||||
//
|
||||
// File cropSaveFile = new File(mBgSourceUtils.getPreviewBackgroundFilePath());
|
||||
// FileOutputStream fos = null;
|
||||
// BufferedOutputStream bos = null;
|
||||
// try {
|
||||
// // 1. 清理旧的裁剪预览图(避免文件残留)
|
||||
//// if (cropSaveFile.exists()) {
|
||||
//// mBgSourceUtils.clearOldFileByExternal(cropSaveFile, "旧裁剪预览图");
|
||||
//// }
|
||||
// // 确保父目录存在(兼容Android 10+分区存储,多包名环境下目录适配)
|
||||
// File parentDir = cropSaveFile.getParentFile();
|
||||
// if (parentDir != null && !parentDir.exists()) {
|
||||
// parentDir.mkdirs();
|
||||
// mBgSourceUtils.copyFile(new File(""), parentDir); // 复用原有目录创建逻辑
|
||||
// }
|
||||
// if (parentDir == null) {
|
||||
// LogUtils.e(TAG, "【裁剪保存失败】目标文件父目录为空");
|
||||
// ToastUtils.show("裁剪图片保存失败");
|
||||
// return;
|
||||
// }
|
||||
// cropSaveFile.createNewFile();
|
||||
//
|
||||
// // 2. 写入裁剪原图到指定路径(覆盖旧文件)
|
||||
// fos = new FileOutputStream(cropSaveFile);
|
||||
// bos = new BufferedOutputStream(fos);
|
||||
// scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 85, bos);
|
||||
// bos.flush();
|
||||
// // 强制同步到磁盘(避免Android 10+异步写入导致文件读取不到)
|
||||
// if (fos != null) {
|
||||
// try {
|
||||
// fos.getFD().sync();
|
||||
// } catch (IOException e) {
|
||||
// LogUtils.w(TAG, "【裁剪保存】sync()调用失败,用flush()兜底:" + e.getMessage());
|
||||
// bos.flush();
|
||||
// }
|
||||
// }
|
||||
// LogUtils.d(TAG, "【裁剪保存】预览原图保存成功:" + cropSaveFile.getAbsolutePath() + ",大小=" + cropSaveFile.length() + "bytes");
|
||||
//
|
||||
// // 3. 生成新压缩图(关键:先获取/生成压缩路径,再压缩)
|
||||
// String newCompressPath = mBgSourceUtils.getPreviewBackgroundScaledCompressFilePath();
|
||||
// // 兜底:若压缩路径为空,生成新的唯一路径(避免空指针,兼容多包名路径隔离)
|
||||
// if (TextUtils.isEmpty(newCompressPath)) {
|
||||
// String sourceDir = mBgSourceUtils.getBackgroundSourceDirPath();
|
||||
// newCompressPath = new File(sourceDir, "ScaledCompress_" + System.currentTimeMillis() + ".jpg").getAbsolutePath();
|
||||
// }
|
||||
// // 调用重载方法压缩,传入指定压缩路径
|
||||
// mBgSourceUtils.compressQualityToRecivedPicture(scaledBitmap, newCompressPath);
|
||||
//
|
||||
// // 4. 同步更新预览Bean(核心修复:同时绑定原图路径+压缩图路径)
|
||||
// mBgSourceUtils.saveFileToPreviewBean(cropSaveFile, "裁剪后图片"); // 原有方法:更新原图路径
|
||||
// BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean();
|
||||
// if (previewBean != null) {
|
||||
// previewBean.setBackgroundScaledCompressFilePath(newCompressPath); // 新增:绑定压缩图路径
|
||||
// mBgSourceUtils.saveSettings(); // 持久化Bean配置,避免路径丢失(多包名环境下配置隔离)
|
||||
// LogUtils.d(TAG, "【路径同步】预览Bean双路径同步完成:");
|
||||
// LogUtils.d(TAG, "→ 原图路径:" + previewBean.getBackgroundFilePath());
|
||||
// LogUtils.d(TAG, "→ 压缩图路径:" + previewBean.getBackgroundScaledCompressFilePath());
|
||||
// } else {
|
||||
// LogUtils.e(TAG, "【路径同步失败】预览Bean为空");
|
||||
// }
|
||||
//
|
||||
// ToastUtils.show("裁剪图片保存成功");
|
||||
// } catch (IOException e) {
|
||||
// LogUtils.e(TAG, "【裁剪保存失败】IO异常:" + e.getMessage(), e);
|
||||
// ToastUtils.show("裁剪图片保存失败");
|
||||
// } finally {
|
||||
// // 资源回收(避免内存泄漏,兼容低版本Android)
|
||||
// if (bos != null) {
|
||||
// try {
|
||||
// bos.close();
|
||||
// } catch (IOException e) {
|
||||
// LogUtils.e(TAG, "【流关闭失败】BufferedOutputStream:" + e.getMessage());
|
||||
// }
|
||||
// }
|
||||
// if (fos != null) {
|
||||
// try {
|
||||
// fos.close();
|
||||
// } catch (IOException e) {
|
||||
// LogUtils.e(TAG, "【流关闭失败】FileOutputStream:" + e.getMessage());
|
||||
// }
|
||||
// }
|
||||
// // 回收缩放后的Bitmap(避免重复回收)
|
||||
// if (scaledBitmap != bitmap && scaledBitmap != null && !scaledBitmap.isRecycled()) {
|
||||
// scaledBitmap.recycle();
|
||||
// }
|
||||
// if (bitmap != null && !bitmap.isRecycled()) {
|
||||
// bitmap.recycle();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// LogUtils.d(TAG, "【裁剪保存】流程结束。");
|
||||
// }
|
||||
|
||||
/**
|
||||
* 图片缩放(核心用途:大图片自动缩小,降低内存占用,避免OOM崩溃)
|
||||
* 逻辑:按指定缩放比例(0~1之间)缩小Bitmap,保持宽高比不变,生成新的Bitmap并回收旧图
|
||||
@@ -916,7 +736,7 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
LogUtils.d(TAG, "【拍照Bitmap解析】开始解析拍照结果");
|
||||
|
||||
// 方案1:优先从拍照临时文件解析(推荐,获取清晰原图,避免缩略图模糊)
|
||||
if (mfTakePhoto != null && isFileActuallyReadable(mfTakePhoto)) {
|
||||
if (mfTakePhoto != null && mfTakePhoto.exists()) {
|
||||
LogUtils.d(TAG, "【拍照Bitmap解析】优先从临时文件解析:" + mfTakePhoto.getAbsolutePath());
|
||||
// 复用已定义的parseCropTempFileToBitmap函数(采样率加载,防OOM,无需重复写逻辑)
|
||||
Bitmap photoBitmap = parseCropTempFileToBitmap(mfTakePhoto);
|
||||
@@ -975,48 +795,6 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
// 其他失败场景
|
||||
handleOperationCancelOrFail();
|
||||
}
|
||||
// 打印校验日志
|
||||
// LogUtils.d(TAG, "【裁剪回调】校验:resultCode=" + resultCode + ",文件存在=" + isFileExist + ",大小=" + fileSize + "bytes,是否成功=" + isCropSuccess);
|
||||
//
|
||||
// // 处理MIUI裁剪取消(resultCode=0视为取消)
|
||||
// if (resultCode == 0 && !isCropSuccess) {
|
||||
// LogUtils.d(TAG, "【裁剪回调】MIUI 裁剪工具已取消");
|
||||
// ToastUtils.show("裁剪已取消");
|
||||
// //mBgSourceUtils.clearCropTempFiles();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // 处理裁剪文件为空(真正的裁剪失败)
|
||||
// if (isFileExist && fileSize == 0) {
|
||||
// LogUtils.e(TAG, "【裁剪失败】裁剪文件为空(MIUI适配问题)");
|
||||
// ToastUtils.show("裁剪失败,请尝试选择「系统相机」裁剪或更换图片");
|
||||
// //mBgSourceUtils.clearCropTempFiles();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // 裁剪成功:解析Bitmap并保存
|
||||
// if (isCropSuccess) {
|
||||
// BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean();
|
||||
// previewBean.setIsUseBackgroundScaledCompressFile(isCropSuccess);
|
||||
// mBgSourceUtils.saveSettings();
|
||||
//
|
||||
// doubleRefreshPreview();
|
||||
//
|
||||
// Bitmap cropBitmap = parseCropTempFileToBitmap(cropTempFile);
|
||||
// if (cropBitmap != null && !cropBitmap.isRecycled()) {
|
||||
// saveCropBitmap(cropBitmap); // 保存裁剪结果
|
||||
// // 更新预览数据集设置
|
||||
// BackgroundBean previewBean = mBgSourceUtils.getPreviewBackgroundBean();
|
||||
// previewBean.setIsUseBackgroundScaledCompressFile(isCropSuccess);
|
||||
// mBgSourceUtils.saveSettings();
|
||||
//
|
||||
// doubleRefreshPreview(); // 双重刷新预览(适配MIUI渲染延迟)
|
||||
// LogUtils.d(TAG, "【裁剪完成】裁剪回调处理结束");
|
||||
// } else {
|
||||
// ToastUtils.show("获取裁剪图片失败");
|
||||
// LogUtils.e(TAG, "【裁剪回调失败】Bitmap解析异常");
|
||||
// //mBgSourceUtils.clearCropTempFiles();
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1158,52 +936,6 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
LogUtils.d(TAG, "→ 压缩图路径 :" + targetCompressPath);
|
||||
|
||||
startCropImageActivity(false);
|
||||
|
||||
// 关键修复3:生成压缩图(指定BackgroundCrops目录下的路径,确保与预览Bean路径一致)
|
||||
//LogUtils.d(TAG, "【选图压缩】开始生成预览压缩图,目标路径:" + targetCompressPath);
|
||||
// Bitmap selectBitmap = null;
|
||||
// try {
|
||||
// // 优化:使用采样率加载Bitmap,避免OOM(原有直接decodeFile易导致大图片崩溃)
|
||||
// BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
// options.inJustDecodeBounds = true;
|
||||
// BitmapFactory.decodeFile(mBgSourceUtils.getPreviewBackgroundBean().getBackgroundFilePath(), options);
|
||||
// // 计算采样率(最大尺寸限制为2048px)
|
||||
// int maxSize = 2048;
|
||||
// int sampleSize = 1;
|
||||
// while (options.outWidth / sampleSize > maxSize || options.outHeight / sampleSize > maxSize) {
|
||||
// sampleSize *= 2;
|
||||
// }
|
||||
// options.inJustDecodeBounds = false;
|
||||
// options.inSampleSize = sampleSize;
|
||||
// options.inPreferredConfig = Bitmap.Config.RGB_565; // 节省内存
|
||||
// selectBitmap = BitmapFactory.decodeFile(mBgSourceUtils.getPreviewBackgroundBean().getBackgroundFilePath(), options);
|
||||
// LogUtils.d(TAG, "");
|
||||
// } catch (Exception e) {
|
||||
// LogUtils.e(TAG, "【选图压缩】Bitmap加载失败:" + e.getMessage(), e);
|
||||
// }
|
||||
|
||||
// 关键修复4:校验压缩图是否生成成功(避免压缩失败但仍启动裁剪)
|
||||
// File compressFile = new File(targetCompressPath);
|
||||
// if (!compressFile.exists() || compressFile.length() <= 0) {
|
||||
// ToastUtils.show("压缩图生成失败,请重新选择图片");
|
||||
// LogUtils.e(TAG, "【选图压缩失败】压缩图文件无效:" + targetCompressPath);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// 刷新预览并启动裁剪(无需重复同步预览Bean,已提前绑定)
|
||||
/*doubleRefreshPreview();
|
||||
|
||||
// 新增:延迟50ms启动裁剪(适配部分机型选图后文件写入延迟)
|
||||
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!isFinishing()) {
|
||||
startCropImageActivity(false);
|
||||
LogUtils.d(TAG, "【选图完成】选图回调处理结束,已启动裁剪(正式图+压缩图均已生成)");
|
||||
}
|
||||
}
|
||||
}, 50);
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1211,8 +943,6 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
*/
|
||||
private void handleOperationCancelOrFail() {
|
||||
initBackgroundViewByPreviewBean();
|
||||
doubleRefreshPreview();
|
||||
|
||||
LogUtils.d(TAG, "【操作回调】操作取消或失败");
|
||||
ToastUtils.show("操作已取消");
|
||||
}
|
||||
@@ -1239,66 +969,4 @@ public class BackgroundSettingsActivity extends WinBoLLActivity implements Backg
|
||||
LogUtils.d(TAG, "【选图权限】已添加持久化读取权限");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 精准校验文件是否实际可读取(核心用途:解决Android14+ 中 File.canRead() 假阳性问题,避免“文件存在但无法读取”)
|
||||
* 逻辑:不依赖canRead(),而是通过实际打开文件流读取1字节,验证是否真的有读取权限(最可靠的校验方式)
|
||||
* @param file 待校验的文件(如选图临时文件、裁剪文件)
|
||||
* @return true=文件实际可读取,false=文件不可读(不存在/无权限/不是文件)
|
||||
*/
|
||||
private boolean isFileActuallyReadable(File file) {
|
||||
// 第一重:基础校验(快速过滤明显无效的文件)
|
||||
if (file == null) {
|
||||
LogUtils.w(TAG, "【文件可读性校验】文件对象为空,直接返回false");
|
||||
return false;
|
||||
}
|
||||
if (!file.exists()) {
|
||||
LogUtils.w(TAG, "【文件可读性校验】文件不存在,路径:" + file.getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
if (!file.isFile()) {
|
||||
LogUtils.w(TAG, "【文件可读性校验】路径不是合法文件(可能是目录),路径:" + file.getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
if (file.length() <= 0) {
|
||||
LogUtils.w(TAG, "【文件可读性校验】文件为空(大小=0字节),路径:" + file.getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 第二重:实际流读取校验(核心,规避canRead()假阳性)- Java7 手动流操作
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
// 尝试打开文件输入流(若无权限,会直接抛出异常)
|
||||
fis = new FileInputStream(file);
|
||||
// 读取1字节(无需读取完整文件,仅验证“能否读取”)
|
||||
fis.read(new byte[1]); // 读取1字节,验证流是否可用
|
||||
LogUtils.d(TAG, "【文件可读性校验】文件实际可读取,路径:" + file.getAbsolutePath());
|
||||
return true;
|
||||
|
||||
} catch (SecurityException e) {
|
||||
// 捕获权限异常(最常见:有文件但无读取权限)
|
||||
LogUtils.e(TAG, "【文件可读性校验】无读取权限,路径:" + file.getAbsolutePath() + ",异常:" + e.getMessage());
|
||||
return false;
|
||||
|
||||
} catch (IOException e) {
|
||||
// 捕获IO异常(文件破损/被占用/无法打开)
|
||||
LogUtils.e(TAG, "【文件可读性校验】文件无法读取(可能破损/被占用),路径:" + file.getAbsolutePath() + ",异常:" + e.getMessage());
|
||||
return false;
|
||||
|
||||
} catch (Exception e) {
|
||||
// 捕获其他异常(如文件路径非法等)
|
||||
LogUtils.e(TAG, "【文件可读性校验】未知异常,路径:" + file.getAbsolutePath() + ",异常:" + e.getMessage());
|
||||
return false;
|
||||
|
||||
} finally {
|
||||
// 手动关闭流(Java7 标准写法,避免内存泄漏)
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
LogUtils.e(TAG, "【文件可读性校验】输入流关闭失败,路径:" + file.getAbsolutePath() + ",异常:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user