Compare commits

...

7 Commits

13 changed files with 141 additions and 44 deletions

View File

@@ -77,7 +77,7 @@ dependencies {
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
//api 'androidx.fragment:fragment:1.1.0'
implementation 'cc.winboll.studio:libaes:15.11.6'
implementation 'cc.winboll.studio:libaes:15.11.7'
implementation 'cc.winboll.studio:libappbase:15.11.0'
//api fileTree(dir: 'libs', include: ['*.aar'])

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Wed Nov 26 16:27:33 HKT 2025
stageCount=9
#Thu Nov 27 14:46:03 HKT 2025
stageCount=10
libraryProject=
baseVersion=15.11
publishVersion=15.11.8
publishVersion=15.11.9
buildCount=0
baseBetaVersion=15.11.9
baseBetaVersion=15.11.10

View File

@@ -230,6 +230,8 @@
<activity android:name="cc.winboll.studio.powerbell.activities.ShortcutActionActivity"/>
<activity android:name="cc.winboll.studio.powerbell.activities.SettingsActivity"/>
</application>
</manifest>

View File

@@ -12,7 +12,7 @@ import java.io.File;
public class App extends GlobalApplication {
public static final String TAG = "GlobalApplication";
public static final String TAG = "App";
public static final String COMPONENT_EN1 = "cc.winboll.studio.powerbell.MainActivityEN1";
public static final String COMPONENT_CN1 = "cc.winboll.studio.powerbell.MainActivityCN1";

View File

@@ -20,6 +20,7 @@ import cc.winboll.studio.powerbell.activities.AboutActivity;
import cc.winboll.studio.powerbell.activities.BackgroundPictureActivity;
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.fragments.MainViewFragment;
@@ -198,7 +199,7 @@ public class MainActivity extends WinBoLLActivity {
reloadBackground();
setBackgroundColor();
if (mADsBannerView != null) {
mADsBannerView.resumeADs();
mADsBannerView.resumeADs(MainActivity.this);
}
// // 修复:优化广告请求逻辑(添加生命周期判断 + 主线程执行)
@@ -234,7 +235,9 @@ public class MainActivity extends WinBoLLActivity {
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
int menuItemId = item.getItemId();
if (menuItemId == R.id.action_about) {
if (menuItemId == R.id.action_settings) {
startActivity(new Intent(this, SettingsActivity.class));
} else if (menuItemId == R.id.action_about) {
startActivity(new Intent(this, AboutActivity.class));
} else if (menuItemId == R.id.action_battery_report) {
startActivity(new Intent(this, BatteryReportActivity.class));

View File

@@ -0,0 +1,21 @@
package cc.winboll.studio.powerbell.activities;
import android.app.Activity;
import android.os.Bundle;
import cc.winboll.studio.powerbell.R;
/**
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
* @Date 2025/11/27 14:26
* @Describe 应用设置窗口
*/
public class SettingsActivity extends Activity {
public static final String TAG = "SettingsActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
}
}

View File

@@ -19,8 +19,11 @@ import android.widget.TextView;
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.services.ControlCenterService;
import cc.winboll.studio.powerbell.utils.AppConfigUtils;
import cc.winboll.studio.powerbell.utils.BackgroundPictureUtils;
import cc.winboll.studio.powerbell.utils.ServiceUtils;
import cc.winboll.studio.powerbell.views.BackgroundView;
import cc.winboll.studio.powerbell.views.BatteryDrawable;
@@ -79,6 +82,11 @@ public class MainViewFragment extends Fragment {
// 获取指定ID的View实例
bvPreviewBackground = mView.findViewById(R.id.fragmentmainviewBackgroundView1);
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(getActivity());
BackgroundPictureBean bean = utils.getBackgroundPictureBean();
int nPixelColor = bean.getPixelColor();
bvPreviewBackground.setBackgroundColor(nPixelColor);
/*final View mainImageView = mView.findViewById(R.id.fragmentmainviewImageView1);
// 注册OnGlobalLayoutListener
@@ -141,6 +149,17 @@ public class MainViewFragment extends Fragment {
return mView;
}
@Override
public void onResume() {
super.onResume();
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(getActivity());
BackgroundPictureBean bean = utils.getBackgroundPictureBean();
int nPixelColor = bean.getPixelColor();
bvPreviewBackground.setBackgroundColor(nPixelColor);
}
void setViewData() {
int nChargeReminderValue = mAppConfigUtils.getChargeReminderValue();
int nUsegeReminderValue = mAppConfigUtils.getUsegeReminderValue();

View File

@@ -4,6 +4,7 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
@@ -17,7 +18,7 @@ import java.io.FileOutputStream;
/**
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
* @Date 2025/11/19 18:01
* @Describe 背景图片视图控件(支持预览临时图片 + 外部刷新
* @Describe 背景图片视图控件(全透明背景 + 不拉伸居中平铺 + 完全填充父视图
*/
public class BackgroundView extends RelativeLayout {
@@ -30,8 +31,8 @@ public class BackgroundView extends RelativeLayout {
private static String BACKGROUND_IMAGE_FILENAME = "current.data";
private static String BACKGROUND_IMAGE_PREVIEW_FILENAME = "current_preview.data";
private static String backgroundSourceFilePath;
private float imageAspectRatio = 1.0f; // 默认 1:1
// 标记当前是否处于预览状态
private float imageAspectRatio = 1.0f; // 图片原始宽高比(控制不拉伸)
// 标记当前是否处于预览模式
private boolean isPreviewMode = false;
public BackgroundView(Context context) {
@@ -59,18 +60,32 @@ public class BackgroundView extends RelativeLayout {
}
void initView() {
initBackgroundImageView();
// 1. 控件本身:完全填充父视图 + 全透明背景 + 无内边距
setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
setPadding(0, 0, 0, 0); // 取消自身内边距
setBackgroundColor(0x00000000); // 全透明背景(#00000000
setBackground(new ColorDrawable(0x00000000)); // 双重保障同时设置Background为透明兼容低版本
initBackgroundImageView(); // 初始化内部ImageView全透明 + 不拉伸居中平铺)
initBackgroundImagePath();
loadAndSetImageViewBackground();
}
private void initBackgroundImageView() {
ivBackground = new ImageView(mContext);
// 2. ImageView初始宽高WRAP_CONTENT + 居中 + 无内边距 + 全透明背景
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); // 居中显示
layoutParams.setMargins(0, 0, 0, 0); // 取消边距
ivBackground.setLayoutParams(layoutParams);
// 3. 缩放模式FIT_CENTER不拉伸按比例显示
ivBackground.setScaleType(ImageView.ScaleType.FIT_CENTER);
ivBackground.setPadding(0, 0, 0, 0); // 取消内部padding
ivBackground.setBackgroundColor(0x00000000); // ImageView背景全透明
ivBackground.setBackground(new ColorDrawable(0x00000000)); // 双重保障(兼容低版本)
this.addView(ivBackground);
}
@@ -160,35 +175,39 @@ public class BackgroundView extends RelativeLayout {
}
/**
* 【新增公共函数】预览临时图片(不修改正式背景文件
* 预览临时图片(全透明背景 + 不拉伸居中平铺
* @param previewImagePath 临时预览图片的路径
*/
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;
}
// 计算预览图片宽高比
// 计算图片原始宽高比
if (!calculateImageAspectRatio(previewFile)) {
LogUtils.e(TAG, "预览图片尺寸无效,无法预览");
setDefaultImageViewBackground();
return;
}
// 压缩加载预览图片
// 压缩加载预览图片(保持比例)
Bitmap previewBitmap = decodeBitmapWithCompress(previewFile, 1080, 1920);
if (previewBitmap == null) {
LogUtils.e(TAG, "预览图片加载失败");
setDefaultImageViewBackground();
return;
}
// 设置预览图片ImageView
// 设置预览图片(保持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);
@@ -196,14 +215,14 @@ public class BackgroundView extends RelativeLayout {
ivBackground.setBackgroundDrawable(previewDrawable);
}
// 调整 ImageView 尺寸以匹配预览图片宽高比
// 调整ImageView尺寸(居中平铺,不拉伸)
adjustImageViewSize();
isPreviewMode = true;
LogUtils.d(TAG, "进入预览模式,预览图片路径:" + previewImagePath);
LogUtils.d(TAG, "进入预览模式,预览图片路径:" + previewImagePath + ",宽高比:" + imageAspectRatio);
}
/**
* 【新增公共函数】退出预览模式,恢复显示正式背景图片
* 退出预览模式,恢复显示正式背景图片
*/
public void exitPreviewMode() {
if (isPreviewMode) {
@@ -227,7 +246,7 @@ public class BackgroundView extends RelativeLayout {
}
/**
* 加载正式背景图片并设置到 ImageView
* 加载正式背景图片并设置到 ImageView(全透明背景 + 不拉伸居中平铺)
*/
private void loadAndSetImageViewBackground() {
if (backgroundSourceFilePath == null) {
@@ -242,11 +261,13 @@ public class BackgroundView extends RelativeLayout {
return;
}
// 计算图片原始宽高比
if (!calculateImageAspectRatio(backgroundFile)) {
setDefaultImageViewBackground();
return;
}
// 压缩加载 Bitmap保持比例
Bitmap bitmap = decodeBitmapWithCompress(backgroundFile, 1080, 1920);
if (bitmap == null) {
LogUtils.e(TAG, "图片加载失败,无法解析为 Bitmap");
@@ -254,6 +275,7 @@ public class BackgroundView extends RelativeLayout {
return;
}
// 设置图片保持ImageView透明背景
Drawable backgroundDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
ivBackground.setBackground(backgroundDrawable);
@@ -261,12 +283,13 @@ public class BackgroundView extends RelativeLayout {
ivBackground.setBackgroundDrawable(backgroundDrawable);
}
// 调整ImageView尺寸居中平铺不拉伸
adjustImageViewSize();
LogUtils.d(TAG, "ImageView 背景加载成功,宽高比:" + imageAspectRatio);
LogUtils.d(TAG, "ImageView 背景加载成功(全透明+不拉伸),宽高比:" + imageAspectRatio);
}
/**
* 计算图片宽高比(宽/高)
* 计算图片原始宽高比(宽/高)
*/
private boolean calculateImageAspectRatio(File file) {
try {
@@ -291,11 +314,11 @@ public class BackgroundView extends RelativeLayout {
}
/**
* 动态调整 ImageView 尺寸以匹配图片宽高比
* 调整ImageView尺寸(不拉伸,居中平铺)
*/
private void adjustImageViewSize() {
int parentWidth = getWidth();
int parentHeight = getHeight();
int parentWidth = getWidth(); // 控件宽度(已填充父视图)
int parentHeight = getHeight(); // 控件高度(已填充父视图)
if (parentWidth == 0 || parentHeight == 0) {
post(new Runnable() {
@@ -316,14 +339,17 @@ public class BackgroundView extends RelativeLayout {
imageViewWidth = (int) (imageViewHeight * imageAspectRatio);
}
// 应用尺寸
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) ivBackground.getLayoutParams();
layoutParams.width = imageViewWidth;
layoutParams.height = imageViewHeight;
ivBackground.setLayoutParams(layoutParams);
LogUtils.d(TAG, "ImageView 尺寸调整完成:宽=" + imageViewWidth + ", 高=" + imageViewHeight);
}
/**
* 带压缩的 Bitmap 解码(避免 OOM
* 带压缩的 Bitmap 解码(保持比例,避免 OOM
*/
private Bitmap decodeBitmapWithCompress(File file, int maxWidth, int maxHeight) {
try {
@@ -349,13 +375,14 @@ public class BackgroundView extends RelativeLayout {
}
/**
* 设置默认背景(图片加载失败时兜底
* 设置默认背景(全透明兜底,避免空白
*/
private void setDefaultImageViewBackground() {
ivBackground.setBackgroundResource(R.drawable.default_background);
// 关键:默认背景设为全透明(而非默认图,避免遮挡下层视图)
ivBackground.setBackground(new ColorDrawable(0x00000000)); // 全透明背景
imageAspectRatio = 1.0f;
adjustImageViewSize();
LogUtils.d(TAG, "已设置 ImageView 默认背景");
LogUtils.d(TAG, "已设置默认透明背景");
}
@Override

View File

@@ -21,8 +21,7 @@
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/activitymainRelativeLayout1"
android:background="#FFB7B7B7"/>
android:id="@+id/activitymainRelativeLayout1"/>
<FrameLayout
android:layout_width="match_parent"

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<cc.winboll.studio.libaes.views.AToolbar
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height"
android:id="@+id/toolbar"
style="@style/DefaultAToolbar"/>
<cc.winboll.studio.libaes.views.ADsControlView
android:id="@+id/ads_control_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

View File

@@ -9,7 +9,10 @@
<item
android:id="@+id/action_changepicture"
android:title="@string/item_changepicture"/>
<item
android:id="@+id/action_settings"
android:title="@string/item_settings"/>
<item
android:id="@+id/action_about"
android:title="@string/item_aboutview"/>
android:title="@string/item_about"/>
</menu>

View File

@@ -4,13 +4,16 @@
<string name="app_name_cn2">泡额呗额</string>
<string name="app_description">一个接收手机电量信息的应用,当电量值达到设定范围时会提醒用户。</string>
<string name="about_crashed">本应用崩溃了,作者水平有限,敬请谅解!</string>
<string name="item_mainview">Main View</string>
<string name="item_aboutview">About</string>
<string name="item_clearrecord">Clear Record</string>
<string name="item_changepicture">Change Picture</string>
<string name="item_devoloperoptionsview">Developer View</string>
<string name="item_logview">Log View</string>
<string name="item_sourceview">Source View</string>
<string name="item_main">主窗口</string>
<string name="item_about">关于</string>
<string name="item_settings">应用设置</string>
<string name="item_battery_report">应用耗电记录</string>
<string name="item_mainunittestactivity">开发调试窗口</string>
<string name="item_clearrecord">清理电量记录</string>
<string name="item_changepicture">更换背景图片</string>
<string name="item_devoloperoptionsview">开发调试窗口</string>
<string name="item_logview">日志窗口</string>
<string name="item_sourceview">源码窗口</string>
<string name="txt_aboveswitch">消息总开关</string>
<string name="txt_aboveswitchtips">当电量低于左边(放电状态)或高于右边(充电状态),就会发送一个提醒铃声。</string>
<string name="texthint_CustomSlideToCleanRecord">Slide Right To Clean Up APP Record.</string>

View File

@@ -9,11 +9,12 @@
<string name="switchto_en1">PowerBell</string>
<string name="switchto_cn1">能源钟</string>
<string name="switchto_cn2">泡额呗额</string>
<string name="en1_switch_disabled">PowerBell</string>
<string name="cn1_switch_disabled">能源钟</string>
<string name="cn2_switch_disabled">泡额呗额</string>
<string name="en1_switch_disabled">PowerBell X</string>
<string name="cn1_switch_disabled">能源钟 X</string>
<string name="cn2_switch_disabled">泡额呗额 X</string>
<string name="item_mainview">Main View</string>
<string name="item_aboutview">About</string>
<string name="item_about">About</string>
<string name="item_settings">Settings</string>
<string name="item_battery_report">Battery Report</string>
<string name="item_clearrecord">Clear Record</string>
<string name="item_changepicture">Change Picture</string>