From de189c3fb0fc7bd6ef1e300e261fb3db31ee07a3 Mon Sep 17 00:00:00 2001 From: ZhanGSKen Date: Sat, 29 Nov 2025 16:17:12 +0800 Subject: [PATCH] =?UTF-8?q?20251129=5F161627=5F420=E6=95=B4=E4=BD=93?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E9=87=8D=E6=9E=84=E5=AE=8C=E6=88=90=EF=BC=8C?= =?UTF-8?q?=E5=BE=85=E8=B0=83=E8=AF=95=E3=80=82=E3=80=82=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- powerbell/build.properties | 4 +- powerbell/src/main/AndroidManifest.xml | 4 +- .../studio/powerbell/MainActivity.java | 8 +- ...y.java => BackgroundSettingsActivity.java} | 266 ++++++++------- .../activities/ClearRecordActivity.java | 2 +- .../activities/PixelPickerActivity.java | 14 +- .../powerbell/adapters/BatteryAdapter.java | 2 +- .../beans/BackgroundPictureBean.java | 99 ------ .../BackgroundPicturePreviewDialog.java | 8 +- .../dialogs/NetworkBackgroundDialog.java | 15 +- .../powerbell/fragments/MainViewFragment.java | 8 +- .../{beans => model}/AppConfigBean.java | 2 +- .../powerbell/model/BackgroundBean.java | 143 ++++++++ .../{beans => model}/BatteryData.java | 2 +- .../{beans => model}/BatteryInfoBean.java | 2 +- .../ControlCenterServiceBean.java | 2 +- .../{beans => model}/NotificationMessage.java | 2 +- .../ControlCenterServiceReceiver.java | 2 +- .../services/ControlCenterService.java | 4 +- .../studio/powerbell/utils/AppCacheUtils.java | 2 +- .../powerbell/utils/AppConfigUtils.java | 4 +- .../utils/BackgroundSourceUtils.java | 152 ++++++--- .../studio/powerbell/utils/FileUtils.java | 312 +++++++++++------- .../powerbell/utils/NotificationUtils2.java | 2 +- .../studio/powerbell/utils/StringUtils.java | 2 +- .../powerbell/views/BackgroundView.java | 261 ++++++++------- 26 files changed, 770 insertions(+), 554 deletions(-) rename powerbell/src/main/java/cc/winboll/studio/powerbell/activities/{BackgroundPictureActivity.java => BackgroundSettingsActivity.java} (73%) delete mode 100644 powerbell/src/main/java/cc/winboll/studio/powerbell/beans/BackgroundPictureBean.java rename powerbell/src/main/java/cc/winboll/studio/powerbell/{beans => model}/AppConfigBean.java (98%) create mode 100644 powerbell/src/main/java/cc/winboll/studio/powerbell/model/BackgroundBean.java rename powerbell/src/main/java/cc/winboll/studio/powerbell/{beans => model}/BatteryData.java (94%) rename powerbell/src/main/java/cc/winboll/studio/powerbell/{beans => model}/BatteryInfoBean.java (97%) rename powerbell/src/main/java/cc/winboll/studio/powerbell/{beans => model}/ControlCenterServiceBean.java (97%) rename powerbell/src/main/java/cc/winboll/studio/powerbell/{beans => model}/NotificationMessage.java (94%) diff --git a/powerbell/build.properties b/powerbell/build.properties index cb8978e7..b4ad7e58 100644 --- a/powerbell/build.properties +++ b/powerbell/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Sat Nov 29 02:59:10 GMT 2025 +#Sat Nov 29 08:15:05 GMT 2025 stageCount=11 libraryProject= baseVersion=15.11 publishVersion=15.11.10 -buildCount=32 +buildCount=35 baseBetaVersion=15.11.11 diff --git a/powerbell/src/main/AndroidManifest.xml b/powerbell/src/main/AndroidManifest.xml index cfd52eea..4da18dab 100644 --- a/powerbell/src/main/AndroidManifest.xml +++ b/powerbell/src/main/AndroidManifest.xml @@ -150,7 +150,7 @@ @@ -234,4 +234,4 @@ - \ No newline at end of file + diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java index 32cf4346..d20add3a 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/MainActivity.java @@ -17,12 +17,12 @@ import cc.winboll.studio.libaes.views.ADsBannerView; import cc.winboll.studio.libappbase.LogActivity; import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.powerbell.activities.AboutActivity; -import cc.winboll.studio.powerbell.activities.BackgroundPictureActivity; +import cc.winboll.studio.powerbell.activities.BackgroundSettingsActivity; import cc.winboll.studio.powerbell.activities.BatteryReportActivity; import cc.winboll.studio.powerbell.activities.ClearRecordActivity; import cc.winboll.studio.powerbell.activities.SettingsActivity; import cc.winboll.studio.powerbell.activities.WinBoLLActivity; -import cc.winboll.studio.powerbell.beans.BackgroundPictureBean; +import cc.winboll.studio.powerbell.model.BackgroundBean; import cc.winboll.studio.powerbell.fragments.MainViewFragment; import cc.winboll.studio.powerbell.unittest.MainUnitTestActivity; import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils; @@ -244,7 +244,7 @@ public class MainActivity extends WinBoLLActivity { } else if (menuItemId == R.id.action_clearrecord) { startActivity(new Intent(this, ClearRecordActivity.class)); } else if (menuItemId == R.id.action_changepicture) { - startActivity(new Intent(this, BackgroundPictureActivity.class)); + startActivity(new Intent(this, BackgroundSettingsActivity.class)); } else if (menuItemId == R.id.action_log) { LogActivity.startLogActivity(this); } else if (menuItemId == R.id.action_unittestactivity) { @@ -282,7 +282,7 @@ public class MainActivity extends WinBoLLActivity { return; } BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(this); - BackgroundPictureBean bean = utils.getBackgroundPictureBean(); + BackgroundBean bean = utils.getCurrentBackgroundBean(); int nPixelColor = bean.getPixelColor(); RelativeLayout mainLayout = findViewById(R.id.activitymainRelativeLayout1); if (mainLayout != null) { diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundPictureActivity.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java similarity index 73% rename from powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundPictureActivity.java rename to powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java index 37b8e63e..3cdb7d27 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundPictureActivity.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/BackgroundSettingsActivity.java @@ -22,7 +22,7 @@ import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.ToastUtils; import cc.winboll.studio.powerbell.App; import cc.winboll.studio.powerbell.R; -import cc.winboll.studio.powerbell.beans.BackgroundPictureBean; +import cc.winboll.studio.powerbell.model.BackgroundBean; import cc.winboll.studio.powerbell.dialogs.BackgroundPicturePreviewDialog; import cc.winboll.studio.powerbell.dialogs.NetworkBackgroundDialog; import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils; @@ -37,10 +37,10 @@ import java.io.IOException; import java.io.OutputStream; import androidx.core.util.Preconditions; -public class BackgroundPictureActivity extends WinBoLLActivity implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener { +public class BackgroundSettingsActivity extends WinBoLLActivity implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener { - public static final String TAG = "BackgroundPictureActivity"; - public BackgroundSourceUtils mBackgroundPictureUtils; + public static final String TAG = "BackgroundSettingsActivity"; + public BackgroundSourceUtils mBackgroundSourceUtils; // 图片选择请求码 public static final int REQUEST_SELECT_PICTURE = 0; @@ -52,8 +52,8 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr private File mfBackgroundDir; // 背景图片存储文件夹 private File mfPictureDir; // 拍照与剪裁临时文件夹 private File mfTakePhoto; // 拍照文件 - private File mfRecivedPicture; // 接收的图片文件 - + //private File mfRecivedPicture; // 接收的图片文件 + // 背景视图预览图片的文件名 private String preViewFilePath = ""; private String preViewFileUrl = ""; @@ -73,7 +73,7 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr private static String _mSourceCroppedFilePath; private static String _mszCommonFileType = "jpeg"; private int mnPictureCompress = 100; - private static String _RecivedBackgroundFileName; + //private static String _RecivedBackgroundFileName; @Override public Activity getActivity() { @@ -89,11 +89,13 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_backgroundpicture); - initEnv(); + bvPreviewBackground = (BackgroundView) findViewById(R.id.activitybackgroundpictureBackgroundView1); + + //initEnv(); // 初始化工具类和文件夹 - mBackgroundPictureUtils = BackgroundSourceUtils.getInstance(this); - mfBackgroundDir = new File(mBackgroundPictureUtils.getBackgroundDir()); + mBackgroundSourceUtils = BackgroundSourceUtils.getInstance(this); + mfBackgroundDir = new File(mBackgroundSourceUtils.getBackgroundSourceDirPath()); if (!mfBackgroundDir.exists()) { mfBackgroundDir.mkdirs(); } @@ -107,7 +109,7 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr mfTakePhoto = new File(mfPictureDir, "TakePhoto.jpg"); //mfTempCropPicture = new File(mfPictureDir, "TempCrop.jpg"); - mfRecivedPicture = getRecivedPictureFile(); + //mfRecivedPicture = getRecivedPictureFile(); _mSourceCropTempFile = new File(mfBackgroundDir, _mSourceCropTempFileName); _mSourceCroppedFile = new File(mfBackgroundDir, _mSourceCroppedFileName); _mSourceCroppedFilePath = _mSourceCroppedFile.getAbsolutePath().toString(); @@ -135,7 +137,9 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr findViewById(R.id.activitybackgroundpictureAButton7).setOnClickListener(onPixelPickerClickListener); findViewById(R.id.activitybackgroundpictureAButton8).setOnClickListener(onCleanPixelClickListener); - updatePreviewBackground(); + BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(BackgroundSettingsActivity.this); + utils.setCurrentSourceToPreview(); + bvPreviewBackground.reloadPreviewBackground(); // 处理分享的图片 Intent intent = getIntent(); @@ -148,10 +152,10 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr } } - private void initEnv() { - LogUtils.d(TAG, "initEnv()"); - _RecivedBackgroundFileName = "SourcePicture.data"; - } +// private void initEnv() { +// LogUtils.d(TAG, "initEnv()"); +// _RecivedBackgroundFileName = "SourcePicture.data"; +// } public static String getBackgroundFileName() { return _mSourceCroppedFileName; @@ -159,72 +163,74 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr @Override public void onAcceptRecivedPicture(String szPreRecivedPictureName) { - BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(this); - utils.getBackgroundPictureBean().setIsUseBackgroundFile(true); - utils.saveData(); - - File sourceFile = new File(utils.getBackgroundDir(), szPreRecivedPictureName); - if (FileUtils.copyFile(sourceFile, mfRecivedPicture)) { - startCropImageActivity(false); - } else { - ToastUtils.show("图片复制失败,请重试"); - } + ToastUtils.show("onAcceptRecivedPicture not yet."); +// BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(this); +// utils.getCurrentBackgroundBean().setIsUseBackgroundFile(true); +// utils.saveSettings(); +// +// File sourceFile = new File(utils.getBackgroundSourceDirPath(), szPreRecivedPictureName); +// if (FileUtils.copyFile(sourceFile, mfRecivedPicture)) { +// startCropImageActivity(false); +// } else { +// ToastUtils.show("图片复制失败,请重试"); +// } } /** - * 更新背景图片预览 + * 更新背景图片预览, + * 如果sourceFile参数为空,则加载旧的背景图片资源 */ - public void updatePreviewBackground() { + public void updateBackgroundView(File sourceFile, String sourceFileInfo) { LogUtils.d(TAG, "updatePreviewBackground"); - LogUtils.d(TAG, String.format("_mSourceCroppedFilePath : %s", _mSourceCroppedFilePath)); - //ImageView ivPreviewBackground = (ImageView) findViewById(R.id.activitybackgroundpictureImageView1); - bvPreviewBackground = (BackgroundView) findViewById(R.id.activitybackgroundpictureBackgroundView1); - BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(this); - utils.loadBackgroundPictureBean(); + BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(this); + if (sourceFile == null) { + bvPreviewBackground.reloadCurrentBackground(); + } else { + utils.saveFileToPreviewBean(sourceFile, sourceFileInfo); + bvPreviewBackground.reloadPreviewBackground(); + } - boolean isUseBackgroundFile = utils.getBackgroundPictureBean().isUseBackgroundFile(); - LogUtils.d(TAG, String.format("isUseBackgroundFile is %s, _mSourceCroppedFile.exists() is %s ", isUseBackgroundFile, _mSourceCroppedFile.exists())); - - //if (isUseBackgroundFile && _mSourceCroppedFile.exists()) { - if (_mSourceCroppedFile.exists()) { - //try { - //String filePath = utils.getBackgroundDir() + getBackgroundFileName(); - preViewFilePath = _mSourceCroppedFilePath; - LogUtils.d(TAG, String.format("preViewFilePathBackgroundView : %s", preViewFilePath)); - bvPreviewBackground.previewBackgroundImage(preViewFilePath); - /*Drawable drawable = FileUtils.getImageDrawable(filePath); - if (drawable != null) { - //drawable.setAlpha(120); - //bvPreviewBackground.setImageDrawable(drawable); - }*/ - //ToastUtils.show("背景图片已更新"); -// } catch (IOException e) { -// LogUtils.d(TAG, e, Thread.currentThread().getStackTrace()); -// ToastUtils.show("背景图片加载失败"); -// } - } else { - ToastUtils.show("未使用背景图片"); - preViewFilePath = ""; - bvPreviewBackground.previewBackgroundImage(preViewFilePath); -// Drawable drawable = getResources().getDrawable(R.drawable.blank10x10); -// if (drawable != null) { -// drawable.setAlpha(120); -// bvPreviewBackground.setImageDrawable(drawable); -// } - } +// boolean isUseBackgroundFile = utils.getCurrentBackgroundBean().isUseBackgroundFile(); +// LogUtils.d(TAG, String.format("isUseBackgroundFile is %s, _mSourceCroppedFile.exists() is %s ", isUseBackgroundFile, _mSourceCroppedFile.exists())); +// +// //if (isUseBackgroundFile && _mSourceCroppedFile.exists()) { +// if (_mSourceCroppedFile.exists()) { +// //try { +// //String filePath = utils.getBackgroundDir() + getBackgroundFileName(); +// preViewFilePath = _mSourceCroppedFilePath; +// LogUtils.d(TAG, String.format("preViewFilePathBackgroundView : %s", preViewFilePath)); +// bvPreviewBackground.previewBackgroundImage(preViewFilePath); +// /*Drawable drawable = FileUtils.getImageDrawable(filePath); +// if (drawable != null) { +// //drawable.setAlpha(120); +// //bvPreviewBackground.setImageDrawable(drawable); +// }*/ +// //ToastUtils.show("背景图片已更新"); +//// } catch (IOException e) { +//// LogUtils.d(TAG, e, Thread.currentThread().getStackTrace()); +//// ToastUtils.show("背景图片加载失败"); +//// } +// } else { +// ToastUtils.show("未使用背景图片"); +// preViewFilePath = ""; +// bvPreviewBackground.previewBackgroundImage(preViewFilePath); +//// Drawable drawable = getResources().getDrawable(R.drawable.blank10x10); +//// if (drawable != null) { +//// drawable.setAlpha(120); +//// bvPreviewBackground.setImageDrawable(drawable); +//// } +// } } // 点击事件监听器 private View.OnClickListener onOriginNullClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(BackgroundPictureActivity.this); - BackgroundPictureBean bean = utils.getBackgroundPictureBean(); + BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(BackgroundSettingsActivity.this); + BackgroundBean bean = utils.getCurrentBackgroundBean(); bean.setIsUseBackgroundFile(false); - utils.saveData(); - - preViewFilePath = ""; - bvPreviewBackground.previewBackgroundImage(preViewFilePath); + utils.saveSettings(); + bvPreviewBackground.reloadPreviewBackground(); } }; @@ -289,10 +295,11 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr private View.OnClickListener onReceivedPictureClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(BackgroundPictureActivity.this); - utils.getBackgroundPictureBean().setIsUseBackgroundFile(true); - utils.saveData(); - updatePreviewBackground(); + ToastUtils.show("onReceivedPictureClickListener not yet."); +// BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(BackgroundSettingsActivity.this); +// utils.getCurrentBackgroundBean().setIsUseBackgroundFile(true); +// utils.saveSettings(); +// updateBackgroundView(); } }; @@ -312,10 +319,10 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr private View.OnClickListener onCleanPixelClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(BackgroundPictureActivity.this); - BackgroundPictureBean bean = utils.getBackgroundPictureBean(); + BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(BackgroundSettingsActivity.this); + BackgroundBean bean = utils.getCurrentBackgroundBean(); bean.setPixelColor(0); - utils.saveData(); + utils.saveSettings(); setBackgroundColor(); } }; @@ -326,12 +333,13 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr void compressQualityToRecivedPicture(Bitmap bitmap) { OutputStream outStream = null; try { - mfRecivedPicture = getRecivedPictureFile(); - if (!mfRecivedPicture.exists()) { - mfRecivedPicture.createNewFile(); + BackgroundSourceUtils utils= BackgroundSourceUtils.getInstance(this); + File fRecivedPicture = new File(utils.getPreviewBackgroundScaledCompressFilePath()); + if (!fRecivedPicture.exists()) { + fRecivedPicture.createNewFile(); } - FileOutputStream fos = new FileOutputStream(mfRecivedPicture); + FileOutputStream fos = new FileOutputStream(fRecivedPicture); outStream = new BufferedOutputStream(fos); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream); outStream.flush(); @@ -358,15 +366,20 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr */ public void startCropImageActivity(boolean isCropFree) { LogUtils.d(TAG, "startCropImageActivity"); - BackgroundPictureBean bean = mBackgroundPictureUtils.loadBackgroundPictureBean(); - mfRecivedPicture = getRecivedPictureFile(); - Uri uri = UriUtil.getUriForFile(this, mfRecivedPicture); + BackgroundSourceUtils utils= BackgroundSourceUtils.getInstance(this); + BackgroundBean bean = utils.getPreviewBackgroundBean(); + bean.setIsUseScaledCompress(true); + utils.saveSettings(); + + File fRecivedPicture = new File(utils.getPreviewBackgroundFilePath()); + + Uri uri = UriUtil.getUriForFile(this, fRecivedPicture); LogUtils.d(TAG, "uri : " + uri.toString()); if (_mSourceCropTempFile.exists()) { _mSourceCropTempFile.delete(); } - + try { _mSourceCropTempFile.createNewFile(); } catch (IOException e) { @@ -393,6 +406,7 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr intent.putExtra("scale", true); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + startActivityForResult(intent, REQUEST_CROP_IMAGE); } @@ -420,7 +434,7 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr } // 优化:创建保存目录 - File backgroundDir = new File(mBackgroundPictureUtils.getBackgroundDir()); + File backgroundDir = new File(mBackgroundSourceUtils.getBackgroundSourceDirPath()); if (!backgroundDir.exists()) { if (!backgroundDir.mkdirs()) { ToastUtils.show("无法创建保存目录"); @@ -429,11 +443,12 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr } } - File saveFile = new File(backgroundDir, getBackgroundFileName()); + // 剪裁的图片的保存地址 + File fScaledCompressBitmapFile = new File(backgroundDir, BackgroundSourceUtils.getInstance(this).getPreviewBackgroundScaledCompressFilePath()); // 优化:检查文件是否可写 - if (saveFile.exists() && !saveFile.canWrite()) { - if (!saveFile.delete()) { + if (fScaledCompressBitmapFile.exists() && !fScaledCompressBitmapFile.canWrite()) { + if (!fScaledCompressBitmapFile.delete()) { ToastUtils.show("无法删除旧文件"); if (scaledBitmap != bitmap) scaledBitmap.recycle(); return; @@ -442,15 +457,20 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr FileOutputStream fos = null; try { - fos = new FileOutputStream(saveFile); + fos = new FileOutputStream(fScaledCompressBitmapFile); boolean success = scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos); fos.flush(); if (success) { - //ToastUtils.show("保存成功"); - updatePreviewBackground(); + ToastUtils.show("图片压缩保存成功"); + BackgroundSourceUtils.getInstance(this).getPreviewBackgroundBean().setIsUseScaledCompress(true); + BackgroundSourceUtils.getInstance(this).saveSettings(); + bvPreviewBackground.reloadPreviewBackground(); + } else { - LogUtils.e(TAG, "图片压缩保存失败"); ToastUtils.show("图片压缩保存失败"); + BackgroundSourceUtils.getInstance(this).getPreviewBackgroundBean().setIsUseScaledCompress(false); + BackgroundSourceUtils.getInstance(this).saveSettings(); + bvPreviewBackground.reloadPreviewBackground(); } } catch (FileNotFoundException e) { LogUtils.e(TAG, "文件未找到" + e); @@ -489,7 +509,9 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr * 分享图片 */ void sharePicture() { - Uri uri = UriUtil.getUriForFile(this, mfRecivedPicture); + BackgroundSourceUtils utils= BackgroundSourceUtils.getInstance(this); + File fRecivedPicture = new File(utils.getCurrentBackgroundFilePath()); + Uri uri = UriUtil.getUriForFile(this, fRecivedPicture); Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.putExtra(Intent.EXTRA_STREAM, uri); shareIntent.setType("image/" + _mszCommonFileType); @@ -497,19 +519,20 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr startActivity(Intent.createChooser(shareIntent, "Share Image")); } - public File getRecivedPictureFile() { - BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(this); - utils.loadBackgroundPictureBean(); - return new File(utils.getBackgroundDir(), _RecivedBackgroundFileName); - } +// public File getRecivedPictureFile() { +// BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(this); +// utils.loadSettings(); +// return new File(utils.getBackgroundSourceDirPath(), _RecivedBackgroundFileName); +// } - public void saveToRecivedBackground(String srcFilePath, String srcFillSourcePath) { - BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(this); - utils.loadBackgroundPictureBean(); - File dstFile = new File(utils.getBackgroundDir(), _RecivedBackgroundFileName); - compressQualityToRecivedPicture(srcFilePath); - FileUtils.copyFile(new File(srcFilePath), dstFile); - } +// public void saveToRecivedBackground(String srcFilePath, String srcFillSourcePath) { +// BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(this); +// utils.loadSettings(); +// File dstFile = new File(utils.getBackgroundSourceDirPath(), _RecivedBackgroundFileName); +// //compressQualityToRecivedPicture(srcFilePath); +// ToastUtils.show("compressQualityToRecivedPicture not yet."); +// FileUtils.copyFile(new File(srcFilePath), dstFile); +// } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { @@ -519,12 +542,17 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr Uri selectedImage = data.getData(); LogUtils.d(TAG, "Uri is : " + selectedImage.toString()); File fSrcImage = new File(UriUtil.getFilePathFromUri(this, selectedImage)); - mfRecivedPicture = getRecivedPictureFile(); - if (FileUtils.copyFile(fSrcImage, mfRecivedPicture)) { - startCropImageActivity(false); - } else { - ToastUtils.show("图片复制失败,请重试"); - } + BackgroundSourceUtils utils= BackgroundSourceUtils.getInstance(this); + utils.saveFileToPreviewBean(fSrcImage, selectedImage.toString()); + startCropImageActivity(false); + //mfRecivedPicture = getRecivedPictureFile(); +// BackgroundBean bean = utils.getPreviewBackgroundBean(); +// mfRecivedPicture = getRecivedPictureFile(); +// if (FileUtils.copyFile(fSrcImage, mfRecivedPicture)) { +// startCropImageActivity(false); +// } else { +// ToastUtils.show("图片复制失败,请重试"); +// } } catch (Exception e) { LogUtils.e(TAG, "选择图片异常" + e); ToastUtils.show("选择图片失败:" + e.getMessage()); @@ -618,8 +646,8 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr } void setBackgroundColor() { - BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(BackgroundPictureActivity.this); - BackgroundPictureBean bean = utils.getBackgroundPictureBean(); + BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(BackgroundSettingsActivity.this); + BackgroundBean bean = utils.getCurrentBackgroundBean(); int nPixelColor = bean.getPixelColor(); RelativeLayout mainLayout = findViewById(R.id.activitybackgroundpictureRelativeLayout1); mainLayout.setBackgroundColor(nPixelColor); @@ -665,7 +693,8 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr OnRecivedPictureListener onRecivedPictureListener = new OnRecivedPictureListener(){ @Override public void onRecivedPicture(String srcFilePath, String srcFileUrl) { - saveToRecivedBackground(srcFilePath, srcFileUrl); + BackgroundSourceUtils utils= BackgroundSourceUtils.getInstance(BackgroundSettingsActivity.this); + utils.saveFileToPreviewBean(new File(srcFilePath), srcFileUrl); startCropImageActivity(true); } }; @@ -681,16 +710,17 @@ public class BackgroundPictureActivity extends WinBoLLActivity implements Backgr @Override public void onNo() { isCommitSettings = true; - BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(BackgroundPictureActivity.this); - BackgroundPictureBean bean = utils.getBackgroundPictureBean(); + BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(BackgroundSettingsActivity.this); + BackgroundBean bean = utils.getCurrentBackgroundBean(); bean.setIsUseBackgroundFile(!preViewFilePath.equals("")); - utils.saveData(); + utils.saveSettings(); finish(); } @Override public void onYes() { - bvPreviewBackground.setImageViewSource(preViewFilePath); + BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(BackgroundSettingsActivity.this); + utils.commitPreviewSourceToCurrent(); isCommitSettings = true; finish(); } diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/ClearRecordActivity.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/ClearRecordActivity.java index 99e4d7f0..cbacbc71 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/ClearRecordActivity.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/ClearRecordActivity.java @@ -12,7 +12,7 @@ import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.ToastUtils; import cc.winboll.studio.powerbell.App; import cc.winboll.studio.powerbell.R; -import cc.winboll.studio.powerbell.beans.BatteryInfoBean; +import cc.winboll.studio.powerbell.model.BatteryInfoBean; import cc.winboll.studio.powerbell.receivers.ControlCenterServiceReceiver; import cc.winboll.studio.powerbell.utils.AppCacheUtils; import cc.winboll.studio.powerbell.utils.StringUtils; diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/PixelPickerActivity.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/PixelPickerActivity.java index c73b46a7..8ae5aef5 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/PixelPickerActivity.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/activities/PixelPickerActivity.java @@ -24,9 +24,9 @@ import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity; import cc.winboll.studio.libaes.views.AToolbar; import cc.winboll.studio.libappbase.GlobalApplication; import cc.winboll.studio.powerbell.R; -import cc.winboll.studio.powerbell.activities.BackgroundPictureActivity; +import cc.winboll.studio.powerbell.activities.BackgroundSettingsActivity; import cc.winboll.studio.powerbell.activities.PixelPickerActivity; -import cc.winboll.studio.powerbell.beans.BackgroundPictureBean; +import cc.winboll.studio.powerbell.model.BackgroundBean; import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils; import java.io.File; import java.io.FileInputStream; @@ -194,9 +194,9 @@ public class PixelPickerActivity extends WinBoLLActivity implements IWinBoLLActi dialog.dismiss(); // 可以在这里添加确定后的回调逻辑 BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(PixelPickerActivity.this); - BackgroundPictureBean bean = utils.getBackgroundPictureBean(); + BackgroundBean bean = utils.getCurrentBackgroundBean(); bean.setPixelColor(pixelColor); - utils.saveData(); + utils.saveSettings(); Toast.makeText(PixelPickerActivity.this, "已记录像素值", Toast.LENGTH_SHORT).show(); setBackgroundColor(); } @@ -218,7 +218,7 @@ public class PixelPickerActivity extends WinBoLLActivity implements IWinBoLLActi void setBackgroundColor() { BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(PixelPickerActivity.this); - BackgroundPictureBean bean = utils.getBackgroundPictureBean(); + BackgroundBean bean = utils.getCurrentBackgroundBean(); int nPixelColor = bean.getPixelColor(); RelativeLayout mainLayout = findViewById(R.id.activitypixelpickerRelativeLayout1); mainLayout.setBackgroundColor(nPixelColor); @@ -235,7 +235,7 @@ public class PixelPickerActivity extends WinBoLLActivity implements IWinBoLLActi public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { Intent intent = new Intent(); - intent.setClass(this, BackgroundPictureActivity.class); + intent.setClass(this, BackgroundSettingsActivity.class); startActivity(intent); //GlobalApplication.getWinBoLLActivityManager().startWinBoLLActivity(getApplicationContext(), ); return true; @@ -248,7 +248,7 @@ public class PixelPickerActivity extends WinBoLLActivity implements IWinBoLLActi public void onBackPressed() { super.onBackPressed(); Intent intent = new Intent(); - intent.setClass(this, BackgroundPictureActivity.class); + intent.setClass(this, BackgroundSettingsActivity.class); startActivity(intent); //GlobalApplication.getWinBoLLActivityManager().startWinBoLLActivity(getApplicationContext(), BackgroundPictureActivity.class); } diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/adapters/BatteryAdapter.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/adapters/BatteryAdapter.java index 93cc8fb8..9c8fe055 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/adapters/BatteryAdapter.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/adapters/BatteryAdapter.java @@ -12,7 +12,7 @@ import android.widget.TextView; import androidx.recyclerview.widget.RecyclerView; import cc.winboll.studio.powerbell.R; import cc.winboll.studio.powerbell.adapters.BatteryAdapter; -import cc.winboll.studio.powerbell.beans.BatteryData; +import cc.winboll.studio.powerbell.model.BatteryData; import java.util.ArrayList; import java.util.List; diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/BackgroundPictureBean.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/BackgroundPictureBean.java deleted file mode 100644 index d2aa9224..00000000 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/BackgroundPictureBean.java +++ /dev/null @@ -1,99 +0,0 @@ -package cc.winboll.studio.powerbell.beans; - -/** - * @Author ZhanGSKen - * @Date 2024/07/18 11:52:28 - * @Describe 应用背景图片数据类 - */ -import android.util.JsonReader; -import android.util.JsonWriter; -import cc.winboll.studio.libappbase.BaseBean; -import java.io.IOException; - -public class BackgroundPictureBean extends BaseBean { - - public static final String TAG = "BackgroundPictureBean"; - - int backgroundWidth = 100; - int backgroundHeight = 100; - boolean isUseBackgroundFile = false; - // 图片拾取像素颜色 - int pixelColor = 0; - - public BackgroundPictureBean() { - } - - public BackgroundPictureBean(String recivedFileName, boolean isUseBackgroundFile) { - this.isUseBackgroundFile = isUseBackgroundFile; - } - - public void setPixelColor(int pixelColor) { - this.pixelColor = pixelColor; - } - - public int getPixelColor() { - return pixelColor; - } - - public void setBackgroundWidth(int backgroundWidth) { - this.backgroundWidth = backgroundWidth; - } - - public int getBackgroundWidth() { - return backgroundWidth; - } - - public void setBackgroundHeight(int backgroundHeight) { - this.backgroundHeight = backgroundHeight; - } - - public int getBackgroundHeight() { - return backgroundHeight; - } - - public void setIsUseBackgroundFile(boolean isUseBackgroundFile) { - this.isUseBackgroundFile = isUseBackgroundFile; - } - - public boolean isUseBackgroundFile() { - return isUseBackgroundFile; - } - - @Override - public String getName() { - return BackgroundPictureBean.class.getName(); - } - - @Override - public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException { - super.writeThisToJsonWriter(jsonWriter); - BackgroundPictureBean bean = this; - jsonWriter.name("backgroundWidth").value(bean.getBackgroundWidth()); - jsonWriter.name("backgroundHeight").value(bean.getBackgroundHeight()); - jsonWriter.name("isUseBackgroundFile").value(bean.isUseBackgroundFile()); - jsonWriter.name("pixelColor").value(bean.getPixelColor()); - } - - @Override - public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException { - BackgroundPictureBean bean = new BackgroundPictureBean(); - jsonReader.beginObject(); - while (jsonReader.hasNext()) { - String name = jsonReader.nextName(); - if (name.equals("backgroundWidth")) { - bean.setBackgroundWidth(jsonReader.nextInt()); - } else if (name.equals("backgroundHeight")) { - bean.setBackgroundHeight(jsonReader.nextInt()); - } else if (name.equals("isUseBackgroundFile")) { - bean.setIsUseBackgroundFile(jsonReader.nextBoolean()); - } else if (name.equals("pixelColor")) { - bean.setPixelColor(jsonReader.nextInt()); - } else { - jsonReader.skipValue(); - } - } - // 结束 JSON 对象 - jsonReader.endObject(); - return bean; - } -} diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/dialogs/BackgroundPicturePreviewDialog.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/dialogs/BackgroundPicturePreviewDialog.java index 30be0778..23966d50 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/dialogs/BackgroundPicturePreviewDialog.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/dialogs/BackgroundPicturePreviewDialog.java @@ -12,7 +12,7 @@ import android.widget.Toast; import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.powerbell.MainActivity; import cc.winboll.studio.powerbell.R; -import cc.winboll.studio.powerbell.activities.BackgroundPictureActivity; +import cc.winboll.studio.powerbell.activities.BackgroundSettingsActivity; import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils; import cc.winboll.studio.powerbell.utils.FileUtils; import cc.winboll.studio.powerbell.utils.UriUtil; @@ -40,7 +40,7 @@ public class BackgroundPicturePreviewDialog extends Dialog { initEnv(); mContext = context; - mBackgroundPictureUtils = ((BackgroundPictureActivity)context).mBackgroundPictureUtils; + mBackgroundPictureUtils = ((BackgroundSettingsActivity)context).mBackgroundSourceUtils; ImageView imageView = findViewById(R.id.dialogbackgroundpicturepreviewImageView1); copyAndViewRecivePicture(imageView); @@ -78,7 +78,7 @@ public class BackgroundPicturePreviewDialog extends Dialog { void copyAndViewRecivePicture(ImageView imageView) { //AppConfigUtils appConfigUtils = AppConfigUtils.getInstance((GlobalApplication)mContext.getApplicationContext()); - BackgroundPictureActivity activity = ((BackgroundPictureActivity)mContext); + BackgroundSettingsActivity activity = ((BackgroundSettingsActivity)mContext); //取出文件uri Uri uri = activity.getIntent().getData(); @@ -95,7 +95,7 @@ public class BackgroundPicturePreviewDialog extends Dialog { File fSrcImage = new File(szSrcImage); //mszPreReceivedFileName = DateUtils.getDateNowString() + "-" + fSrcImage.getName(); - File mfPreReceivedPhoto = new File(activity.mBackgroundPictureUtils.getBackgroundDir(), mszPreReceivedFileName); + File mfPreReceivedPhoto = new File(activity.mBackgroundSourceUtils.getBackgroundSourceDirPath(), mszPreReceivedFileName); // 复制源图片到剪裁文件 try { FileUtils.copyFileUsingFileChannels(fSrcImage, mfPreReceivedPhoto); diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/dialogs/NetworkBackgroundDialog.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/dialogs/NetworkBackgroundDialog.java index 0be5eb2a..41bc00e9 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/dialogs/NetworkBackgroundDialog.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/dialogs/NetworkBackgroundDialog.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import cc.winboll.studio.powerbell.utils.ImageDownloader; +import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils; /** * @Author ZhanGSKen&豆包大模型 @@ -151,6 +152,9 @@ public class NetworkBackgroundDialog extends AlertDialog { @Override public void onClick(View v) { LogUtils.d("NetworkBackgroundDialog", "取消按钮点击"); + BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(mContext); + utils.setCurrentSourceToPreview(); + dismiss(); // 关闭对话框 if (listener != null) { listener.onCancel(); @@ -164,8 +168,9 @@ public class NetworkBackgroundDialog extends AlertDialog { public void onClick(View v) { LogUtils.d("NetworkBackgroundDialog", "确认按钮点击"); // 确定预览背景资源 - bvBackgroundPreview.previewBackgroundImage(previewFilePath); - + BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(mContext); + utils.saveFileToPreviewBean(new File(previewFilePath), previewFileUrl); + dismiss(); // 关闭对话框 if (listener != null) { listener.onConfirm(previewFilePath, previewFileUrl); @@ -198,7 +203,11 @@ public class NetworkBackgroundDialog extends AlertDialog { // 预览背景 previewFilePath = filePath; - bvBackgroundPreview.previewBackgroundImage(previewFilePath); + BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(mContext); + utils.saveFileToPreviewBean(new File(previewFilePath), previewFileUrl); + bvBackgroundPreview.reloadPreviewBackground(); + + //bvBackgroundPreview.previewBackgroundImage(previewFilePath); LogUtils.d(TAG, "图片预览成功:" + filePath); diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/fragments/MainViewFragment.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/fragments/MainViewFragment.java index 313f5a8b..17d5b916 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/fragments/MainViewFragment.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/fragments/MainViewFragment.java @@ -20,7 +20,7 @@ import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.powerbell.App; import cc.winboll.studio.powerbell.R; import cc.winboll.studio.powerbell.activities.PixelPickerActivity; -import cc.winboll.studio.powerbell.beans.BackgroundPictureBean; +import cc.winboll.studio.powerbell.model.BackgroundBean; import cc.winboll.studio.powerbell.services.ControlCenterService; import cc.winboll.studio.powerbell.utils.AppConfigUtils; import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils; @@ -84,7 +84,7 @@ public class MainViewFragment extends Fragment { bvPreviewBackground = mView.findViewById(R.id.fragmentmainviewBackgroundView1); BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(getActivity()); - BackgroundPictureBean bean = utils.getBackgroundPictureBean(); + BackgroundBean bean = utils.getCurrentBackgroundBean(); int nPixelColor = bean.getPixelColor(); bvPreviewBackground.setBackgroundColor(nPixelColor); /*final View mainImageView = mView.findViewById(R.id.fragmentmainviewImageView1); @@ -153,7 +153,7 @@ public class MainViewFragment extends Fragment { public void onResume() { super.onResume(); BackgroundSourceUtils utils = BackgroundSourceUtils.getInstance(getActivity()); - BackgroundPictureBean bean = utils.getBackgroundPictureBean(); + BackgroundBean bean = utils.getCurrentBackgroundBean(); int nPixelColor = bean.getPixelColor(); bvPreviewBackground.setBackgroundColor(nPixelColor); } @@ -320,7 +320,7 @@ public class MainViewFragment extends Fragment { } public void reloadBackground() { - bvPreviewBackground.reloadBackgroundImage(); + bvPreviewBackground.reloadCurrentBackground(); // BackgroundPictureBean bean = BackgroundPictureUtils.getInstance(getActivity()).getBackgroundPictureBean(); // ImageView imageView = mView.findViewById(R.id.fragmentmainviewImageView1); // String szBackgroundFilePath = BackgroundPictureUtils.getInstance(getActivity()).getBackgroundDir() + BackgroundPictureActivity.getBackgroundFileName(); diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/AppConfigBean.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/model/AppConfigBean.java similarity index 98% rename from powerbell/src/main/java/cc/winboll/studio/powerbell/beans/AppConfigBean.java rename to powerbell/src/main/java/cc/winboll/studio/powerbell/model/AppConfigBean.java index da4b8315..11764324 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/AppConfigBean.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/model/AppConfigBean.java @@ -1,4 +1,4 @@ -package cc.winboll.studio.powerbell.beans; +package cc.winboll.studio.powerbell.model; /** * @Author ZhanGSKen diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/model/BackgroundBean.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/model/BackgroundBean.java new file mode 100644 index 00000000..4f1f0025 --- /dev/null +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/model/BackgroundBean.java @@ -0,0 +1,143 @@ +package cc.winboll.studio.powerbell.model; + +/** + * @Author ZhanGSKen + * @Date 2024/07/18 11:52:28 + * @Describe 应用背景图片数据类 + */ +import android.util.JsonReader; +import android.util.JsonWriter; +import cc.winboll.studio.libappbase.BaseBean; +import java.io.IOException; + +public class BackgroundBean extends BaseBean { + + public static final String TAG = "BackgroundPictureBean"; + + String backgroundFileName = ""; + String backgroundFileInfo = ""; + boolean isUseBackgroundFile = false; + String backgroundScaledCompressFileName = ""; + boolean isUseScaledCompress = false; + int backgroundWidth = 100; + int backgroundHeight = 100; + // 图片拾取像素颜色 + int pixelColor = 0; + + public BackgroundBean() { + } + + public void setBackgroundScaledCompressFileName(String backgroundScaledCompressFileName) { + this.backgroundScaledCompressFileName = backgroundScaledCompressFileName; + } + + public String getBackgroundScaledCompressFileName() { + return backgroundScaledCompressFileName; + } + + public void setIsUseScaledCompress(boolean isUseScaledCompress) { + this.isUseScaledCompress = isUseScaledCompress; + } + + public boolean isUseScaledCompress() { + return isUseScaledCompress; + } + + public void setIsUseBackgroundFile(boolean isUseBackgroundFile) { + this.isUseBackgroundFile = isUseBackgroundFile; + } + + public boolean isUseBackgroundFile() { + return isUseBackgroundFile; + } + + public void setBackgroundFileInfo(String backgroundFileInfo) { + this.backgroundFileInfo = backgroundFileInfo; + } + + public String getBackgroundFileInfo() { + return backgroundFileInfo; + } + + public void setBackgroundFileName(String backgroundFileName) { + this.backgroundFileName = backgroundFileName; + } + + public String getBackgroundFileName() { + return backgroundFileName; + } + + public void setPixelColor(int pixelColor) { + this.pixelColor = pixelColor; + } + + public int getPixelColor() { + return pixelColor; + } + + public void setBackgroundWidth(int backgroundWidth) { + this.backgroundWidth = backgroundWidth; + } + + public int getBackgroundWidth() { + return backgroundWidth; + } + + public void setBackgroundHeight(int backgroundHeight) { + this.backgroundHeight = backgroundHeight; + } + + public int getBackgroundHeight() { + return backgroundHeight; + } + + @Override + public String getName() { + return BackgroundBean.class.getName(); + } + + @Override + public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException { + super.writeThisToJsonWriter(jsonWriter); + BackgroundBean bean = this; + jsonWriter.name("backgroundFileName").value(bean.getBackgroundFileName()); + jsonWriter.name("backgroundFileInfo").value(bean.getBackgroundFileInfo()); + jsonWriter.name("isUseBackgroundFile").value(bean.isUseBackgroundFile()); + jsonWriter.name("backgroundScaledCompressFileName").value(bean.getBackgroundScaledCompressFileName()); + jsonWriter.name("isUseScaledCompress").value(bean.isUseScaledCompress()); + jsonWriter.name("backgroundWidth").value(bean.getBackgroundWidth()); + jsonWriter.name("backgroundHeight").value(bean.getBackgroundHeight()); + jsonWriter.name("pixelColor").value(bean.getPixelColor()); + } + + @Override + public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException { + BackgroundBean bean = new BackgroundBean(); + jsonReader.beginObject(); + while (jsonReader.hasNext()) { + String name = jsonReader.nextName(); + if (name.equals("backgroundFileName")) { + bean.setBackgroundFileName(jsonReader.nextString()); + } else if (name.equals("backgroundFileInfo")) { + bean.setBackgroundFileInfo(jsonReader.nextString()); + } else if (name.equals("isUseBackgroundFile")) { + bean.setIsUseBackgroundFile(jsonReader.nextBoolean()); + } else if (name.equals("backgroundScaledCompressFileName")) { + bean.setBackgroundScaledCompressFileName(jsonReader.nextString()); + } else if (name.equals("isUseScaledCompress")) { + bean.setIsUseScaledCompress(jsonReader.nextBoolean()); + } else if (name.equals("backgroundWidth")) { + bean.setBackgroundWidth(jsonReader.nextInt()); + } else if (name.equals("backgroundHeight")) { + bean.setBackgroundHeight(jsonReader.nextInt()); + } else if (name.equals("pixelColor")) { + bean.setPixelColor(jsonReader.nextInt()); + } else { + jsonReader.skipValue(); + } + } + // 结束 JSON 对象 + jsonReader.endObject(); + return bean; + } +} diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/BatteryData.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/model/BatteryData.java similarity index 94% rename from powerbell/src/main/java/cc/winboll/studio/powerbell/beans/BatteryData.java rename to powerbell/src/main/java/cc/winboll/studio/powerbell/model/BatteryData.java index 269a4945..51b23dd3 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/BatteryData.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/model/BatteryData.java @@ -1,4 +1,4 @@ -package cc.winboll.studio.powerbell.beans; +package cc.winboll.studio.powerbell.model; /** * @Author ZhanGSKen diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/BatteryInfoBean.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/model/BatteryInfoBean.java similarity index 97% rename from powerbell/src/main/java/cc/winboll/studio/powerbell/beans/BatteryInfoBean.java rename to powerbell/src/main/java/cc/winboll/studio/powerbell/model/BatteryInfoBean.java index 3063c88d..e7f0fc03 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/BatteryInfoBean.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/model/BatteryInfoBean.java @@ -1,4 +1,4 @@ -package cc.winboll.studio.powerbell.beans; +package cc.winboll.studio.powerbell.model; import android.util.JsonReader; import android.util.JsonWriter; diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/ControlCenterServiceBean.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/model/ControlCenterServiceBean.java similarity index 97% rename from powerbell/src/main/java/cc/winboll/studio/powerbell/beans/ControlCenterServiceBean.java rename to powerbell/src/main/java/cc/winboll/studio/powerbell/model/ControlCenterServiceBean.java index 097cadef..5f13632d 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/ControlCenterServiceBean.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/model/ControlCenterServiceBean.java @@ -1,4 +1,4 @@ -package cc.winboll.studio.powerbell.beans; +package cc.winboll.studio.powerbell.model; /** * @Author ZhanGSKen diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/NotificationMessage.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/model/NotificationMessage.java similarity index 94% rename from powerbell/src/main/java/cc/winboll/studio/powerbell/beans/NotificationMessage.java rename to powerbell/src/main/java/cc/winboll/studio/powerbell/model/NotificationMessage.java index 25e195f8..b95b8f42 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/beans/NotificationMessage.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/model/NotificationMessage.java @@ -1,4 +1,4 @@ -package cc.winboll.studio.powerbell.beans; +package cc.winboll.studio.powerbell.model; // 应用消息结构 // diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/receivers/ControlCenterServiceReceiver.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/receivers/ControlCenterServiceReceiver.java index 53ae0526..7338e89e 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/receivers/ControlCenterServiceReceiver.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/receivers/ControlCenterServiceReceiver.java @@ -5,7 +5,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import cc.winboll.studio.libappbase.LogUtils; -import cc.winboll.studio.powerbell.beans.AppConfigBean; +import cc.winboll.studio.powerbell.model.AppConfigBean; import cc.winboll.studio.powerbell.services.ControlCenterService; import cc.winboll.studio.powerbell.utils.AppConfigUtils; import cc.winboll.studio.powerbell.utils.BatteryUtils; diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/services/ControlCenterService.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/services/ControlCenterService.java index 955d650b..95b2a7fb 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/services/ControlCenterService.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/services/ControlCenterService.java @@ -23,8 +23,8 @@ import cc.winboll.studio.libappbase.ToastUtils; import cc.winboll.studio.powerbell.App; import cc.winboll.studio.powerbell.MainActivity; import cc.winboll.studio.powerbell.R; -import cc.winboll.studio.powerbell.beans.AppConfigBean; -import cc.winboll.studio.powerbell.beans.NotificationMessage; +import cc.winboll.studio.powerbell.model.AppConfigBean; +import cc.winboll.studio.powerbell.model.NotificationMessage; import cc.winboll.studio.powerbell.handlers.ControlCenterServiceHandler; import cc.winboll.studio.powerbell.receivers.ControlCenterServiceReceiver; import cc.winboll.studio.powerbell.services.AssistantService; diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppCacheUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppCacheUtils.java index 6d21004e..9531159e 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppCacheUtils.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppCacheUtils.java @@ -2,7 +2,7 @@ package cc.winboll.studio.powerbell.utils; import android.content.Context; import cc.winboll.studio.libappbase.LogUtils; -import cc.winboll.studio.powerbell.beans.BatteryInfoBean; +import cc.winboll.studio.powerbell.model.BatteryInfoBean; import java.util.ArrayList; public class AppCacheUtils { diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppConfigUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppConfigUtils.java index a9e93d54..580d4776 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppConfigUtils.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/AppConfigUtils.java @@ -5,8 +5,8 @@ import android.content.Context; import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.powerbell.App; import cc.winboll.studio.powerbell.MainActivity; -import cc.winboll.studio.powerbell.beans.AppConfigBean; -import cc.winboll.studio.powerbell.beans.ControlCenterServiceBean; +import cc.winboll.studio.powerbell.model.AppConfigBean; +import cc.winboll.studio.powerbell.model.ControlCenterServiceBean; import cc.winboll.studio.powerbell.dialogs.YesNoAlertDialog; import cc.winboll.studio.powerbell.fragments.MainViewFragment; import cc.winboll.studio.powerbell.services.ControlCenterService; diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/BackgroundSourceUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/BackgroundSourceUtils.java index 3b18f00e..fdcee481 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/BackgroundSourceUtils.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/BackgroundSourceUtils.java @@ -1,64 +1,138 @@ package cc.winboll.studio.powerbell.utils; +import android.content.Context; +import cc.winboll.studio.powerbell.model.BackgroundBean; +import java.io.File; +import java.util.UUID; + /** * @Author ZhanGSKen * @Date 2024/07/18 12:07:20 - * @Describe 背景图片工具集 + * @Describe 背景图片工具集(修复单例模式,线程安全) */ -import android.content.Context; -import cc.winboll.studio.powerbell.beans.BackgroundPictureBean; -import java.io.File; - public class BackgroundSourceUtils { public static final String TAG = "BackgroundPictureUtils"; - static BackgroundSourceUtils _mBackgroundPictureUtils; - Context mContext; - BackgroundPictureBean mBackgroundPictureBean; + // 1. 静态实例加volatile,禁止指令重排,保证可见性 + private static volatile BackgroundSourceUtils sInstance; + private Context mContext; + private File currentBackgroundBeanFile; + private BackgroundBean currentBackgroundBean; + private File previewBackgroundBeanFile; + private BackgroundBean previewBackgroundBean; + // 应用外部存储文件夹路径 + private File fUtilsDir; + private File fModelDir; // 背景图片目录 - String mszBackgroundDir; + private File fBackgroundSourceDir; - BackgroundSourceUtils(Context context) { - mContext = context; - String szExternalFilesDir = mContext.getExternalFilesDir(TAG) + File.separator; - setBackgroundDir(szExternalFilesDir + "Background" + File.separator); - loadBackgroundPictureBean(); + // 2. 私有构造器(加防反射逻辑) + private BackgroundSourceUtils(Context context) { + // 防反射破坏:若已有实例,抛异常阻止创建 + if (sInstance != null) { + throw new RuntimeException("BackgroundSourceUtils 是单例类,禁止重复创建!"); + } + // 上下文建议用Application Context,避免内存泄漏 + this.mContext = context.getApplicationContext(); + fUtilsDir = this.mContext.getExternalFilesDir(TAG); + fModelDir = new File(fUtilsDir, "ModelDir"); + currentBackgroundBeanFile = new File(fModelDir, "currentBackgroundBean.json"); + previewBackgroundBeanFile = new File(fModelDir, "previewBackgroundBean.json"); + fBackgroundSourceDir = new File(fUtilsDir, "BackgroundSource"); + + // 加载配置 + loadSettings(); } + // 3. 双重校验锁单例(线程安全,高效) public static BackgroundSourceUtils getInstance(Context context) { - if (_mBackgroundPictureUtils == null) { - _mBackgroundPictureUtils = new BackgroundSourceUtils(context); + // 第一重校验:避免每次调用都加锁(提高效率) + if (sInstance == null) { + // 同步锁:保证同一时刻只有一个线程进入创建逻辑 + synchronized (BackgroundSourceUtils.class) { + // 第二重校验:防止多线程并发时重复创建(核心) + if (sInstance == null) { + sInstance = new BackgroundSourceUtils(context); + } + } } - return _mBackgroundPictureUtils; + return sInstance; } - // - // 加载应用背景图片配置数据 - // - public BackgroundPictureBean loadBackgroundPictureBean() { - mBackgroundPictureBean = BackgroundPictureBean.loadBean(mContext, BackgroundPictureBean.class); - if (mBackgroundPictureBean == null) { - mBackgroundPictureBean = new BackgroundPictureBean(); - BackgroundPictureBean.saveBean(mContext, mBackgroundPictureBean); + /* + * 加载背景图片配置数据 + */ + void loadSettings() { + currentBackgroundBean = BackgroundBean.loadBeanFromFile(currentBackgroundBeanFile.getAbsolutePath(), BackgroundBean.class); + if (currentBackgroundBean == null) { + currentBackgroundBean = new BackgroundBean(); + BackgroundBean.saveBeanToFile(currentBackgroundBeanFile.getAbsolutePath(), currentBackgroundBean); + } + previewBackgroundBean = BackgroundBean.loadBeanFromFile(previewBackgroundBeanFile.getAbsolutePath(), BackgroundBean.class); + if (previewBackgroundBean == null) { + previewBackgroundBean = new BackgroundBean(); + BackgroundBean.saveBeanToFile(previewBackgroundBeanFile.getAbsolutePath(), previewBackgroundBean); } - return mBackgroundPictureBean; } + + public BackgroundBean getCurrentBackgroundBean() { + return currentBackgroundBean; + } + + public BackgroundBean getPreviewBackgroundBean() { + return previewBackgroundBean; + } + public String getCurrentBackgroundFilePath() { + loadSettings(); + File file = new File(fBackgroundSourceDir, currentBackgroundBean.getBackgroundFileName()); + return file.getAbsolutePath(); + } - void setBackgroundDir(String mszBackgroundDir) { - this.mszBackgroundDir = mszBackgroundDir; + public String getPreviewBackgroundFilePath() { + loadSettings(); + File file = new File(fBackgroundSourceDir, previewBackgroundBean.getBackgroundFileName()); + return file.getAbsolutePath(); + } + + public String getPreviewBackgroundScaledCompressFilePath() { + loadSettings(); + File file = new File(fBackgroundSourceDir, previewBackgroundBean.getBackgroundScaledCompressFileName()); + return file.getAbsolutePath(); + } + + public void saveSettings() { + BackgroundBean.saveBeanToFile(currentBackgroundBeanFile.getAbsolutePath(), currentBackgroundBean); + BackgroundBean.saveBeanToFile(previewBackgroundBeanFile.getAbsolutePath(), previewBackgroundBean); } - - public String getBackgroundDir() { - return mszBackgroundDir; - } - - public BackgroundPictureBean getBackgroundPictureBean() { - return mBackgroundPictureBean; - } - - public void saveData() { - BackgroundPictureBean.saveBean(mContext, mBackgroundPictureBean); + + public String getBackgroundSourceDirPath() { + return fBackgroundSourceDir.getAbsolutePath(); } + + /* + * 保存图片到预览模型, 并返回预览模型数据 + */ + public BackgroundBean saveFileToPreviewBean(File sourceFile, String fileInfo) { + File previewBackgroundFile = new File(fBackgroundSourceDir, FileUtils.createUniqueFileName(sourceFile)); + FileUtils.copyFile(sourceFile, previewBackgroundFile); + previewBackgroundBean = new BackgroundBean(); + previewBackgroundBean.setBackgroundFileName(previewBackgroundFile.getName()); + previewBackgroundBean.setBackgroundScaledCompressFileName("ScaledCompress_"+previewBackgroundFile.getName()); + previewBackgroundBean.setBackgroundFileName(fileInfo); + saveSettings(); + return previewBackgroundBean; + } + + public void commitPreviewSourceToCurrent() { + currentBackgroundBean = previewBackgroundBean; + saveSettings(); + } + + public void setCurrentSourceToPreview() { + previewBackgroundBean = currentBackgroundBean; + saveSettings(); + } } + diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/FileUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/FileUtils.java index 59caa2cf..a2669b93 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/FileUtils.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/FileUtils.java @@ -1,176 +1,236 @@ package cc.winboll.studio.powerbell.utils; + import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import cc.winboll.studio.libappbase.LogUtils; -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; + +import java.io.*; import java.nio.channels.FileChannel; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.UUID; /** - * 文件读取工具类 + * 文件操作工具类 + * 功能:文件读写、复制、图片转换、文件名处理等常用文件操作 + * 适配:Java 7+,支持Android全版本 + * 注意:调用文件操作前需确保已获取存储权限(Android 6.0+ 需动态申请) */ - public class FileUtils { + /** 日志标签 */ public static final String TAG = "FileUtils"; + /** 读取文件默认缓冲区大小(10KB) */ + private static final int BUFFER_SIZE = 10240; + /** 最大读取文件大小(1GB),防止OOM */ + private static final long MAX_READ_FILE_SIZE = 1024 * 1024 * 1024; - // - // 读取文件内容,作为字符串返回 - // + // ====================================== 文件读取相关 ====================================== + + /** + * 读取文件内容并转为字符串 + * @param filePath 文件绝对路径(非空) + * @return 文件内容字符串 + * @throws IOException 异常:文件不存在、文件过大、读取失败等 + */ public static String readFileAsString(String filePath) throws IOException { + // 1. 校验文件合法性 File file = new File(filePath); if (!file.exists()) { - throw new FileNotFoundException(filePath); - } + throw new FileNotFoundException("文件不存在:" + filePath); + } + if (file.length() > MAX_READ_FILE_SIZE) { + throw new IOException("文件过大(超过1GB),禁止读取:" + filePath); + } - if (file.length() > 1024 * 1024 * 1024) { - throw new IOException("File is too large"); - } - - StringBuilder sb = new StringBuilder((int) (file.length())); - // 创建字节输入流 - FileInputStream fis = new FileInputStream(filePath); - // 创建一个长度为10240的Buffer - byte[] bbuf = new byte[10240]; - // 用于保存实际读取的字节数 - int hasRead = 0; - while ((hasRead = fis.read(bbuf)) > 0) { - sb.append(new String(bbuf, 0, hasRead)); - } - fis.close(); + // 2. 读取文件内容(使用StringBuilder高效拼接) + StringBuilder sb = new StringBuilder((int) file.length()); + try (FileInputStream fis = new FileInputStream(file)) { + byte[] buffer = new byte[BUFFER_SIZE]; + int readLen; + // 循环读取缓冲区,避免一次性读取大文件导致OOM + while ((readLen = fis.read(buffer)) > 0) { + sb.append(new String(buffer, 0, readLen)); + } + } return sb.toString(); } - // - // 根据文件路径读取byte[] 数组 - // + /** + * 读取文件内容并转为byte数组(适用于二进制文件:图片、音频等) + * @param filePath 文件绝对路径(非空) + * @return 文件内容byte数组 + * @throws IOException 异常:文件不存在、读取失败等 + */ public static byte[] readFileByBytes(String filePath) throws IOException { + // 1. 校验文件合法性 File file = new File(filePath); if (!file.exists()) { - throw new FileNotFoundException(filePath); - } else { - ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length()); - BufferedInputStream in = null; + throw new FileNotFoundException("文件不存在:" + filePath); + } - try { - in = new BufferedInputStream(new FileInputStream(file)); - short bufSize = 1024; - byte[] buffer = new byte[bufSize]; - int len1; - while (-1 != (len1 = in.read(buffer, 0, bufSize))) { - bos.write(buffer, 0, len1); - } + // 2. 缓冲流读取(高效,减少IO次数) + try (ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length()); + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) { - byte[] var7 = bos.toByteArray(); - return var7; - } finally { - try { - if (in != null) { - in.close(); - } - } catch (IOException var14) { - var14.printStackTrace(); - } - - bos.close(); + byte[] buffer = new byte[BUFFER_SIZE]; + int readLen; + while ((readLen = bis.read(buffer)) != -1) { + bos.write(buffer, 0, readLen); } + bos.flush(); + return bos.toByteArray(); } } - // - // 文件复制函数 - // + // ====================================== 文件复制相关 ====================================== + + /** + * 基于FileChannel复制文件(高效,适用于大文件复制) + * @param source 源文件(非空,必须存在) + * @param dest 目标文件(非空,父目录会自动创建) + * @throws IOException 异常:源文件不存在、复制失败等 + */ public static void copyFileUsingFileChannels(File source, File dest) throws IOException { - FileChannel inputChannel = null; - FileChannel outputChannel = null; - try { - inputChannel = new FileInputStream(source).getChannel(); - outputChannel = new FileOutputStream(dest).getChannel(); + // 1. 校验源文件合法性 + if (!source.exists() || !source.isFile()) { + throw new FileNotFoundException("源文件不存在或不是文件:" + source.getAbsolutePath()); + } + + // 2. 创建目标文件父目录 + if (!dest.getParentFile().exists()) { + dest.getParentFile().mkdirs(); + } + + // 3. 通道复制(try-with-resources 自动关闭通道,无需手动关闭) + try (FileChannel inputChannel = new FileInputStream(source).getChannel(); + FileChannel outputChannel = new FileOutputStream(dest).getChannel()) { + // 从输入通道复制到输出通道(高效,底层优化) outputChannel.transferFrom(inputChannel, 0, inputChannel.size()); - } finally { - inputChannel.close(); - outputChannel.close(); + LogUtils.d(TAG, "文件复制成功(FileChannel):" + source.getAbsolutePath() + " → " + dest.getAbsolutePath()); } } /** - * 将文件生成位图 - * @param path - * @return - * @throws IOException + * 简化版文件复制(基于NIO Files工具类,代码简洁,适用于中小文件) + * @param oldFile 源文件(非空,必须存在) + * @param newFile 目标文件(非空,父目录会自动创建) + * @return 复制结果:true-成功,false-失败 */ - public static BitmapDrawable getImageDrawable(String path) - throws IOException { - //打开文件 - File file = new File(path); - if (!file.exists()) { - return null; - } - - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - int BUFFER_SIZE = 1000; - byte[] bt = new byte[BUFFER_SIZE]; - - //得到文件的输入流 - InputStream in = new FileInputStream(file); - - //将文件读出到输出流中 - int readLength = in.read(bt); - while (readLength != -1) { - outStream.write(bt, 0, readLength); - readLength = in.read(bt); - } - - //转换成byte 后 再格式化成位图 - byte[] data = outStream.toByteArray(); - Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);// 生成位图 - BitmapDrawable bd = new BitmapDrawable(bitmap); - - return bd; - } - public static boolean copyFile(File oldFile, File newFile) { - //String oldPath = "path/to/original/file.txt"; - //String newPath = "path/to/new-location/for/file.txt"; + // 1. 校验源文件合法性 + if (oldFile == null || !oldFile.exists() || !oldFile.isFile()) { + LogUtils.e(TAG, "源文件无效:" + (oldFile != null ? oldFile.getAbsolutePath() : "null")); + return false; + } - //File oldFile = new java.io.File(oldPath); - //File newFile = new java.io.File(newPath); + // 2. 创建目标文件父目录 if (!newFile.getParentFile().exists()) { newFile.getParentFile().mkdirs(); } - if (!oldFile.exists()) { - //System.out.println("The original file does not exist."); - LogUtils.d(TAG, "The original file does not exist."); - } else { - try { - // 源文件路径 - Path sourcePath = Paths.get(oldFile.getPath()); - // 目标文件路径 - Path destPath = Paths.get(newFile.getPath()); - if(newFile.exists()) { - newFile.delete(); - } - Files.copy(sourcePath, destPath); - LogUtils.d(TAG, "File copy successfully."); - //System.out.println("File moved successfully."); - return true; - } catch (Exception e) { - LogUtils.d(TAG, e, Thread.currentThread().getStackTrace()); - //System.err.println("An error occurred while moving the file: " + e.getMessage()); + // 3. 复制文件(覆盖已有目标文件) + try { + Path sourcePath = Paths.get(oldFile.getPath()); + Path destPath = Paths.get(newFile.getPath()); + // 先删除已有目标文件(避免覆盖失败) + if (newFile.exists()) { + newFile.delete(); } + Files.copy(sourcePath, destPath); + LogUtils.d(TAG, "文件复制成功(Files):" + oldFile.getAbsolutePath() + " → " + newFile.getAbsolutePath()); + return true; + } catch (Exception e) { + LogUtils.e(TAG, "文件复制失败:" + e.getMessage(), e); + return false; } - return false; } + // ====================================== 图片文件相关 ====================================== + + /** + * 从文件路径获取BitmapDrawable(适用于Android图片显示) + * @param path 图片文件绝对路径(非空) + * @return BitmapDrawable 图片对象(文件不存在/读取失败返回null) + * @throws IOException 异常:文件读取IO错误 + */ + public static BitmapDrawable getImageDrawable(String path) throws IOException { + // 1. 校验文件合法性 + File file = new File(path); + if (!file.exists() || !file.isFile()) { + LogUtils.e(TAG, "图片文件不存在:" + path); + return null; + } + + // 2. 读取文件并转为BitmapDrawable(缓冲流读取,减少内存占用) + try (InputStream is = new FileInputStream(file); + ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + + byte[] buffer = new byte[BUFFER_SIZE]; + int readLen; + while ((readLen = is.read(buffer)) != -1) { + bos.write(buffer, 0, readLen); + } + + // 3. 生成Bitmap并包装为BitmapDrawable + byte[] imageBytes = bos.toByteArray(); + Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length); + return new BitmapDrawable(bitmap); + } + } + + // ====================================== 文件名处理相关 ====================================== + + /** + * 截取文件后缀名(兼容多 "." 场景,如"image.2025.png" → ".png") + * @param file 目标文件(可为null) + * @return 文件后缀名:带点(如".jpg"),无后缀/文件无效返回空字符串 + */ + public static String getFileSuffixWithMultiDot(File file) { + // 1. 校验文件合法性 + if (file == null || !file.isFile()) { + return ""; + } + + // 2. 提取文件名并查找最后一个 "." + String fileName = file.getName(); + int lastDotIndex = fileName.lastIndexOf("."); + + // 3. 校验后缀合法性(排除无后缀、以点结尾、后缀过长的异常文件) + if (lastDotIndex == -1 // 无 "." + || lastDotIndex == fileName.length() - 1 // 以 "." 结尾(如".gitignore") + || (fileName.length() - lastDotIndex) > 5) { // 后缀长度超过5(异常文件名) + return ""; + } + + // 4. 返回小写后缀(统一格式,避免大小写不一致问题) + return fileName.substring(lastDotIndex).toLowerCase(); + } + + /** + * 生成唯一文件名(优化版:唯一、合法、简洁) + * 生成规则:UUID(去掉"-") + "_" + 时间戳 + 原文件后缀 + * @param refFile 参考文件(用于提取后缀名,可为null) + * @return 唯一文件名(如"a1b2c3d4e5f6_1730000000000.jpg",无后缀则不带点) + */ + public static String createUniqueFileName(File refFile) { + // 1. 获取参考文件的后缀名(自动容错null/无效文件) + String suffix = getFileSuffixWithMultiDot(refFile); + + // 2. 生成唯一标识(UUID确保全局唯一,时间戳进一步降低重复概率) + String uniqueId = UUID.randomUUID().toString().replace("-", ""); // 去掉"-"简化文件名 + long timeStamp = System.currentTimeMillis(); + + // 3. 拼接文件名(分场景处理,避免多余点) + if (suffix.isEmpty()) { + // 无后缀:唯一ID + 时间戳 + return String.format("%s_%d", uniqueId, timeStamp); + } else { + // 有后缀:唯一ID + 时间戳 + 后缀(无多余点) + return String.format("%s_%d%s", uniqueId, timeStamp, suffix); + } + } } + diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/NotificationUtils2.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/NotificationUtils2.java index a2fe111d..63ed9ee8 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/NotificationUtils2.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/NotificationUtils2.java @@ -21,7 +21,7 @@ import android.widget.RemoteViews; import androidx.annotation.RequiresApi; import cc.winboll.studio.powerbell.MainActivity; import cc.winboll.studio.powerbell.R; -import cc.winboll.studio.powerbell.beans.NotificationMessage; +import cc.winboll.studio.powerbell.model.NotificationMessage; import cc.winboll.studio.powerbell.services.ControlCenterService; public class NotificationUtils2 { diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/StringUtils.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/StringUtils.java index 52895e29..967b9446 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/StringUtils.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/utils/StringUtils.java @@ -1,6 +1,6 @@ package cc.winboll.studio.powerbell.utils; -import cc.winboll.studio.powerbell.beans.BatteryInfoBean; +import cc.winboll.studio.powerbell.model.BatteryInfoBean; import java.util.ArrayList; public class StringUtils { diff --git a/powerbell/src/main/java/cc/winboll/studio/powerbell/views/BackgroundView.java b/powerbell/src/main/java/cc/winboll/studio/powerbell/views/BackgroundView.java index 30cdebc4..25f09330 100644 --- a/powerbell/src/main/java/cc/winboll/studio/powerbell/views/BackgroundView.java +++ b/powerbell/src/main/java/cc/winboll/studio/powerbell/views/BackgroundView.java @@ -14,6 +14,7 @@ import cc.winboll.studio.powerbell.R; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import cc.winboll.studio.powerbell.utils.BackgroundSourceUtils; /** * @Author ZhanGSKen&豆包大模型 @@ -67,7 +68,8 @@ public class BackgroundView extends RelativeLayout { setBackground(new ColorDrawable(0x00000000)); // 双重保障:同时设置Background为透明(兼容低版本) initBackgroundImageView(); // 初始化内部ImageView(全透明 + 不拉伸居中平铺) - initBackgroundImagePath(); + + backgroundSourceFilePath = BackgroundSourceUtils.getInstance(this.mContext).getCurrentBackgroundFilePath(); loadAndSetImageViewBackground(); } @@ -89,160 +91,157 @@ public class BackgroundView extends RelativeLayout { this.addView(ivBackground); } - private void initBackgroundImagePath() { - File externalFilesDir = mContext.getExternalFilesDir(null); - if (externalFilesDir == null) { - LogUtils.e(TAG, "外置存储不可用,无法初始化背景图片路径"); - return; - } - - File backgroundDir = new File(externalFilesDir, BACKGROUND_IMAGE_FOLDER); - if (!backgroundDir.exists()) { - backgroundDir.mkdirs(); - } - backgroundSourceFilePath = new File(backgroundDir, BACKGROUND_IMAGE_FILENAME).getAbsolutePath(); - } +// private void initBackgroundImagePath() { +// if (isPreviewMode) { +// backgroundSourceFilePath = BackgroundSourceUtils.getInstance(this.mContext).getPreviewBackgroundFilePath(); +// } else { +// backgroundSourceFilePath = BackgroundSourceUtils.getInstance(this.mContext).getCurrentBackgroundFilePath(); +// } +// } /** * 拷贝图片文件到背景资源目录(正式背景) */ - public void setImageViewSource(String srcBackgroundPath) { - initBackgroundImagePath(); - if (backgroundSourceFilePath == null) { - LogUtils.e(TAG, "目标路径初始化失败,无法保存背景图片"); - return; - } - - File srcFile = new File(srcBackgroundPath); - if (!srcFile.exists() || !srcFile.isFile()) { - LogUtils.e(TAG, String.format("源文件不存在或不是文件:%s", srcBackgroundPath)); - return; - } - - File destFile = new File(backgroundSourceFilePath); - File destDir = destFile.getParentFile(); - if (destDir != null && !destDir.exists()) { - boolean isDirCreated = destDir.mkdirs(); - if (!isDirCreated) { - LogUtils.e(TAG, "目标目录创建失败:" + destDir.getAbsolutePath()); - return; - } - } - - FileInputStream fis = null; - FileOutputStream fos = null; - try { - fis = new FileInputStream(srcFile); - fos = new FileOutputStream(destFile); - - byte[] buffer = new byte[4096]; - int len; - while ((len = fis.read(buffer)) != -1) { - fos.write(buffer, 0, len); - } - fos.flush(); - - LogUtils.d(TAG, String.format("文件拷贝成功:%s -> %s", srcBackgroundPath, backgroundSourceFilePath)); - // 拷贝成功后,若处于预览模式则退出预览,加载正式背景 - if (isPreviewMode) { - exitPreviewMode(); - } else { - loadAndSetImageViewBackground(); - } - - } catch (Exception e) { - LogUtils.e(TAG, String.format("文件拷贝失败:%s", e.getMessage()), e); - if (destFile.exists()) { - destFile.delete(); - LogUtils.d(TAG, "已删除损坏的目标文件"); - } - } finally { - if (fis != null) { - try { - fis.close(); - } catch (Exception e) { - LogUtils.e(TAG, "输入流关闭失败:" + e.getMessage()); - } - } - if (fos != null) { - try { - fos.close(); - } catch (Exception e) { - LogUtils.e(TAG, "输出流关闭失败:" + e.getMessage()); - } - } - } - } +// public void setImageViewSource(String srcBackgroundPath) { +// initBackgroundImagePath(); +// if (backgroundSourceFilePath == null) { +// LogUtils.e(TAG, "目标路径初始化失败,无法保存背景图片"); +// return; +// } +// +// File srcFile = new File(srcBackgroundPath); +// if (!srcFile.exists() || !srcFile.isFile()) { +// LogUtils.e(TAG, String.format("源文件不存在或不是文件:%s", srcBackgroundPath)); +// return; +// } +// +// File destFile = new File(backgroundSourceFilePath); +// File destDir = destFile.getParentFile(); +// if (destDir != null && !destDir.exists()) { +// boolean isDirCreated = destDir.mkdirs(); +// if (!isDirCreated) { +// LogUtils.e(TAG, "目标目录创建失败:" + destDir.getAbsolutePath()); +// return; +// } +// } +// +// FileInputStream fis = null; +// FileOutputStream fos = null; +// try { +// fis = new FileInputStream(srcFile); +// fos = new FileOutputStream(destFile); +// +// byte[] buffer = new byte[4096]; +// int len; +// while ((len = fis.read(buffer)) != -1) { +// fos.write(buffer, 0, len); +// } +// fos.flush(); +// +// LogUtils.d(TAG, String.format("文件拷贝成功:%s -> %s", srcBackgroundPath, backgroundSourceFilePath)); +// // 拷贝成功后,若处于预览模式则退出预览,加载正式背景 +// if (isPreviewMode) { +// exitPreviewMode(); +// } else { +// loadAndSetImageViewBackground(); +// } +// +// } catch (Exception e) { +// LogUtils.e(TAG, String.format("文件拷贝失败:%s", e.getMessage()), e); +// if (destFile.exists()) { +// destFile.delete(); +// LogUtils.d(TAG, "已删除损坏的目标文件"); +// } +// } finally { +// if (fis != null) { +// try { +// fis.close(); +// } catch (Exception e) { +// LogUtils.e(TAG, "输入流关闭失败:" + e.getMessage()); +// } +// } +// if (fos != null) { +// try { +// fos.close(); +// } catch (Exception e) { +// LogUtils.e(TAG, "输出流关闭失败:" + e.getMessage()); +// } +// } +// } +// } /** * 预览临时图片(全透明背景 + 不拉伸居中平铺) * @param previewImagePath 临时预览图片的路径 */ - public void previewBackgroundImage(String previewImagePath) { - if (previewImagePath == null || previewImagePath.isEmpty()) { - LogUtils.e(TAG, "预览图片路径为空"); - setDefaultImageViewBackground(); - return; - } + /*public void previewBackgroundImage(String previewImagePath) { + if (previewImagePath == null || previewImagePath.isEmpty()) { + LogUtils.e(TAG, "预览图片路径为空"); + setDefaultImageViewBackground(); + return; + } - File previewFile = new File(previewImagePath); - if (!previewFile.exists() || !previewFile.isFile()) { - LogUtils.e(TAG, "预览图片不存在或不是文件:" + previewImagePath); - setDefaultImageViewBackground(); - return; - } + File previewFile = new File(previewImagePath); + if (!previewFile.exists() || !previewFile.isFile()) { + LogUtils.e(TAG, "预览图片不存在或不是文件:" + previewImagePath); + setDefaultImageViewBackground(); + return; + } - // 计算图片原始宽高比 - if (!calculateImageAspectRatio(previewFile)) { - LogUtils.e(TAG, "预览图片尺寸无效,无法预览"); - setDefaultImageViewBackground(); - return; - } + // 计算图片原始宽高比 + if (!calculateImageAspectRatio(previewFile)) { + LogUtils.e(TAG, "预览图片尺寸无效,无法预览"); + setDefaultImageViewBackground(); + return; + } - // 压缩加载预览图片(保持比例) - Bitmap previewBitmap = decodeBitmapWithCompress(previewFile, 1080, 1920); - if (previewBitmap == null) { - LogUtils.e(TAG, "预览图片加载失败"); - setDefaultImageViewBackground(); - return; - } + // 压缩加载预览图片(保持比例) + Bitmap previewBitmap = decodeBitmapWithCompress(previewFile, 1080, 1920); + if (previewBitmap == null) { + LogUtils.e(TAG, "预览图片加载失败"); + setDefaultImageViewBackground(); + return; + } - // 设置预览图片(保持ImageView透明背景) - Drawable previewDrawable = new BitmapDrawable(mContext.getResources(), previewBitmap); - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { - ivBackground.setBackground(previewDrawable); - } else { - ivBackground.setBackgroundDrawable(previewDrawable); - } + // 设置预览图片(保持ImageView透明背景) + Drawable previewDrawable = new BitmapDrawable(mContext.getResources(), previewBitmap); + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { + ivBackground.setBackground(previewDrawable); + } else { + ivBackground.setBackgroundDrawable(previewDrawable); + } - // 调整ImageView尺寸(居中平铺,不拉伸) - adjustImageViewSize(); - isPreviewMode = true; - LogUtils.d(TAG, "进入预览模式,预览图片路径:" + previewImagePath + ",宽高比:" + imageAspectRatio); - } + // 调整ImageView尺寸(居中平铺,不拉伸) + adjustImageViewSize(); + isPreviewMode = true; + LogUtils.d(TAG, "进入预览模式,预览图片路径:" + previewImagePath + ",宽高比:" + imageAspectRatio); + } + */ /** * 退出预览模式,恢复显示正式背景图片 */ - public void exitPreviewMode() { - if (isPreviewMode) { - loadAndSetImageViewBackground(); - isPreviewMode = false; - LogUtils.d(TAG, "退出预览模式,恢复正式背景"); - } - } + /*public void exitPreviewMode() { + if (isPreviewMode) { + loadAndSetImageViewBackground(); + isPreviewMode = false; + LogUtils.d(TAG, "退出预览模式,恢复正式背景"); + } + }*/ /** * 公共函数:供外部类调用,重新加载正式背景图片(刷新显示) */ - public void reloadBackgroundImage() { + public void reloadCurrentBackground() { LogUtils.d(TAG, "外部调用重新加载背景图片"); - initBackgroundImagePath(); + backgroundSourceFilePath = BackgroundSourceUtils.getInstance(this.mContext).getCurrentBackgroundFilePath(); + loadAndSetImageViewBackground(); + } + + public void reloadPreviewBackground() { + LogUtils.d(TAG, "外部调用重新加载背景图片"); + backgroundSourceFilePath = BackgroundSourceUtils.getInstance(this.mContext).getPreviewBackgroundFilePath(); loadAndSetImageViewBackground(); - // 若处于预览模式,退出预览 - if (isPreviewMode) { - isPreviewMode = false; - } } /**