解耦类型功能

This commit is contained in:
2025-12-04 06:59:54 +08:00
parent 4434221827
commit 7f3c91fb1d
3 changed files with 349 additions and 1082 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Wed Dec 03 22:37:16 GMT 2025
#Wed Dec 03 22:57:30 GMT 2025
stageCount=13
libraryProject=
baseVersion=15.11
publishVersion=15.11.12
buildCount=191
buildCount=195
baseBetaVersion=15.11.13

View File

@@ -0,0 +1,148 @@
package cc.winboll.studio.powerbell.utils;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
import androidx.core.content.FileProvider;
import java.io.File;
import java.util.List;
import cc.winboll.studio.powerbell.App;
/**
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
* @Date 2025/12/04 06:45
* @Describe 图片裁剪工具类(仅调用系统裁剪,传入比例/自由裁剪参数)
*/
public class ImageCropUtils {
private static final String TAG = "ImageCropUtils";
// FileProvider授权与清单文件一致
/**
* 启动系统裁剪工具
* @param activity 上下文
* @param srcFile 裁剪原图
* @param aspectX 裁剪宽比例自由裁剪传0
* @param aspectY 裁剪高比例自由裁剪传0
* @param isFreeCrop 是否自由裁剪
* @param requestCode 裁剪请求码
*/
public static void startSystemCrop(Activity activity, File srcFile, int aspectX, int aspectY, boolean isFreeCrop, int requestCode) {
Log.d(TAG, "startSystemCrop: 启动系统裁剪,自由裁剪:" + isFreeCrop);
// 校验原图
if (srcFile == null || !srcFile.exists() || srcFile.length() <= 100) {
Toast.makeText(activity, "无有效图片可裁剪", Toast.LENGTH_SHORT).show();
Log.e(TAG, "startSystemCrop: 原图无效");
return;
}
// 生成输入Uri
Uri inputUri = getFileProviderUri(activity, srcFile);
if (inputUri == null) {
Toast.makeText(activity, "获取图片Uri失败", Toast.LENGTH_SHORT).show();
Log.e(TAG, "startSystemCrop: 输入Uri生成失败");
return;
}
// 生成输出文件使用BackgroundSourceUtils的压缩路径
BackgroundSourceUtils bgSourceUtils = BackgroundSourceUtils.getInstance(activity);
File outputFile = new File(bgSourceUtils.getPreviewBackgroundBean().getBackgroundScaledCompressFilePath());
if (outputFile == null) {
Toast.makeText(activity, "裁剪输出路径无效", Toast.LENGTH_SHORT).show();
Log.e(TAG, "startSystemCrop: 输出文件为空");
return;
}
Uri outputUri = getFileProviderUri(activity, outputFile);
// 构建裁剪意图
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(inputUri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("noFaceDetection", true);
// 设置裁剪比例(自由裁剪则不设置)
if (!isFreeCrop && aspectX > 0 && aspectY > 0) {
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY", aspectY);
Log.d(TAG, "startSystemCrop: 裁剪比例:" + aspectX + ":" + aspectY);
}
// 输出配置
intent.putExtra("outputX", 2048);
intent.putExtra("outputY", 2048);
intent.putExtra("scale", true);
intent.putExtra("scaleUpIfNeeded", true);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("quality", 100);
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
// 权限设置
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
}
// 适配系统裁剪工具
try {
List<ResolveInfo> resolveInfos = activity.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (!resolveInfos.isEmpty()) {
ResolveInfo resolveInfo = resolveInfos.get(0);
String cropPackageName = resolveInfo.activityInfo.packageName;
String cropActivityName = resolveInfo.activityInfo.name;
// 授予MIUI裁剪权限
if (cropPackageName.equals("com.miui.gallery")) {
activity.grantUriPermission(cropPackageName, inputUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
activity.grantUriPermission(cropPackageName, outputUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
// 显式启动裁剪
Intent cropIntent = new Intent(intent);
cropIntent.setComponent(new ComponentName(cropPackageName, cropActivityName));
activity.startActivityForResult(cropIntent, requestCode);
Log.d(TAG, "startSystemCrop: 启动裁剪成功,输出路径:" + outputFile.getAbsolutePath());
} else {
// 兜底启动
Intent chooser = Intent.createChooser(intent, "选择裁剪工具");
chooser.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
if (chooser.resolveActivity(activity.getPackageManager()) != null) {
activity.startActivityForResult(chooser, requestCode);
} else {
Toast.makeText(activity, "无可用裁剪工具", Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
Log.e(TAG, "startSystemCrop: 启动裁剪失败:" + e.getMessage());
Toast.makeText(activity, "裁剪工具启动失败", Toast.LENGTH_SHORT).show();
}
}
/**
* 获取FileProvider Uri复用方法避免重复代码
*/
public static Uri getFileProviderUri(Activity activity, File file) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
String FILE_PROVIDER_AUTHORITY = activity.getPackageName() + ".fileprovider";
return FileProvider.getUriForFile(activity, FILE_PROVIDER_AUTHORITY, file);
} else {
return Uri.fromFile(file);
}
} catch (Exception e) {
Log.e(TAG, "getFileProviderUri: 生成Uri失败" + e.getMessage());
return null;
}
}
}