Compare commits
28 Commits
aes-v15.9.
...
powerbell-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e57ce679e | ||
|
|
f9211a8eb4 | ||
|
|
4c31ff9b54 | ||
|
|
8cf610962e | ||
|
|
3071d186ec | ||
|
|
df10306059 | ||
|
|
ccdb9c5abd | ||
|
|
f27209ab87 | ||
|
|
e8682ce410 | ||
|
|
2e4003dae0 | ||
|
|
198b0975ce | ||
|
|
24a578a9d2 | ||
|
|
46de24447f | ||
|
|
2a819e94e4 | ||
|
|
6635358ec5 | ||
|
|
1320984829 | ||
|
|
abf1e5ba42 | ||
|
|
1cd2f88038 | ||
|
|
3f6e583d68 | ||
|
|
271456bfcd | ||
|
|
ee5458d82c | ||
|
|
3a83367f71 | ||
|
|
40a5b9c339 | ||
|
|
fd79113572 | ||
|
|
9b911b583c | ||
|
|
37817c3e8c | ||
|
|
0b5402f5f3 | ||
|
|
bea22e3853 |
@@ -113,10 +113,10 @@ if [[ $? -eq 0 ]]; then
|
|||||||
# 如果Git已经提交了所有代码就执行标签和应用发布操作
|
# 如果Git已经提交了所有代码就执行标签和应用发布操作
|
||||||
|
|
||||||
# 预先询问是否添加工作流标签
|
# 预先询问是否添加工作流标签
|
||||||
echo "Add Github Workflows Tag? (yes/No)"
|
#echo "Add Github Workflows Tag? (yes/No)"
|
||||||
result=$(askAddWorkflowsTag)
|
#result=$(askAddWorkflowsTag)
|
||||||
nAskAddWorkflowsTag=$?
|
#nAskAddWorkflowsTag=$?
|
||||||
echo $result
|
#echo $result
|
||||||
|
|
||||||
# 发布应用
|
# 发布应用
|
||||||
echo "Publishing WinBoLL APK ..."
|
echo "Publishing WinBoLL APK ..."
|
||||||
@@ -138,17 +138,17 @@ if [[ $? -eq 0 ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# 添加 GitHub 工作流标签
|
# 添加 GitHub 工作流标签
|
||||||
if [[ $nAskAddWorkflowsTag -eq 1 ]]; then
|
#if [[ $nAskAddWorkflowsTag -eq 1 ]]; then
|
||||||
# 如果用户选择添加工作流标签
|
# 如果用户选择添加工作流标签
|
||||||
result=$(addWorkflowsTag $1)
|
#result=$(addWorkflowsTag $1)
|
||||||
if [[ $? -eq 0 ]]; then
|
#if [[ $? -eq 0 ]]; then
|
||||||
echo $result
|
# echo $result
|
||||||
# 工作流标签添加成功
|
# 工作流标签添加成功
|
||||||
else
|
#else
|
||||||
echo -e "${0}: addWorkflowsTag $1\n${result}\nAdd workflows tag cancel."
|
#echo -e "${0}: addWorkflowsTag $1\n${result}\nAdd workflows tag cancel."
|
||||||
exit 1 # addWorkflowsTag 异常
|
#exit 1 # addWorkflowsTag 异常
|
||||||
fi
|
#fi
|
||||||
fi
|
#fi
|
||||||
|
|
||||||
## 清理更新描述文件内容
|
## 清理更新描述文件内容
|
||||||
echo "" > $1/app_update_description.txt
|
echo "" > $1/app_update_description.txt
|
||||||
|
|||||||
@@ -114,9 +114,11 @@
|
|||||||
|
|
||||||
# 本项目要实际运用需要注意以下几个步骤:
|
# 本项目要实际运用需要注意以下几个步骤:
|
||||||
# 在项目根目录下:
|
# 在项目根目录下:
|
||||||
## 1. 项目模块编译环境设置(必须),settings.gradle-demo 要复制为 settings.gradle,并取消相应项目模块的注释。
|
## ★. 项目模块编译环境设置(必须),settings.gradle-demo 要复制为 settings.gradle,并取消相应项目模块的注释。
|
||||||
## 2. 项目 Android SDK 编译环境设置(可选),local.properties-demo 要复制为 local.properties,并按需要设置 Android SDK 目录。
|
## ★. 项目 Android SDK 编译环境设置(可选),local.properties-demo 要复制为 local.properties,并按需要设置 Android SDK 目录。
|
||||||
## 3. 类库型模块编译环境设置(可选),winboll.properties-demo 要复制为 winboll.properties,并按需要设置 WinBoLL Maven 库登录用户信息。
|
## ★. 应用签名密钥 keystore 设置问题。一般调试编译只需用【Termux】cd 进 GenKeyStore 目录执行 $ bash gen_debug_keystore.sh 命令即可完成设置。
|
||||||
|
## ☆. 应用 WiBoLL 签名密钥配置问题<非必须考虑>。设置时需要 clone 【keystore】模块源码并拷贝模块目录的 appkey.jks 与 appkey.keystore 到项目根目录即可。
|
||||||
|
## ☆. 类库型模块编译环境设置(可选),winboll.properties-demo 要复制为 winboll.properties,并按需要设置 WinBoLL Maven 库登录用户信息。
|
||||||
|
|
||||||
|
|
||||||
# ☆类库型项目编译方法
|
# ☆类库型项目编译方法
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Mon Jun 09 01:44:28 HKT 2025
|
#Thu Jun 19 20:42:40 HKT 2025
|
||||||
stageCount=1
|
stageCount=2
|
||||||
libraryProject=libaes
|
libraryProject=libaes
|
||||||
baseVersion=15.9
|
baseVersion=15.9
|
||||||
publishVersion=15.9.0
|
publishVersion=15.9.1
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.9.1
|
baseBetaVersion=15.9.2
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Sun Jun 01 08:03:56 GMT 2025
|
#Thu Jun 19 12:49:47 GMT 2025
|
||||||
stageCount=0
|
stageCount=0
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=15.0
|
baseVersion=15.0
|
||||||
publishVersion=15.0.0
|
publishVersion=15.0.0
|
||||||
buildCount=24
|
buildCount=26
|
||||||
baseBetaVersion=15.0.1
|
baseBetaVersion=15.0.1
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Thu Jun 05 08:59:45 GMT 2025
|
#Mon Jun 09 09:38:19 HKT 2025
|
||||||
stageCount=8
|
stageCount=9
|
||||||
libraryProject=libappbase
|
libraryProject=libappbase
|
||||||
baseVersion=15.8
|
baseVersion=15.8
|
||||||
publishVersion=15.8.7
|
publishVersion=15.8.8
|
||||||
buildCount=14
|
buildCount=0
|
||||||
baseBetaVersion=15.8.8
|
baseBetaVersion=15.8.9
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Mon Jun 09 01:44:28 HKT 2025
|
#Thu Jun 19 20:42:26 HKT 2025
|
||||||
stageCount=1
|
stageCount=2
|
||||||
libraryProject=libaes
|
libraryProject=libaes
|
||||||
baseVersion=15.9
|
baseVersion=15.9
|
||||||
publishVersion=15.9.0
|
publishVersion=15.9.1
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.9.1
|
baseBetaVersion=15.9.2
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Thu Jun 05 08:59:45 GMT 2025
|
#Mon Jun 09 09:38:19 HKT 2025
|
||||||
stageCount=8
|
stageCount=9
|
||||||
libraryProject=libappbase
|
libraryProject=libappbase
|
||||||
baseVersion=15.8
|
baseVersion=15.8
|
||||||
publishVersion=15.8.7
|
publishVersion=15.8.8
|
||||||
buildCount=14
|
buildCount=0
|
||||||
baseBetaVersion=15.8.8
|
baseBetaVersion=15.8.9
|
||||||
|
|||||||
1
numtable/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
34
numtable/README.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# NumTable
|
||||||
|
|
||||||
|
#### 介绍
|
||||||
|
桌面图标多元应用。提供一个数字风格化的桌面标识图标,快捷的桌面标识创建途径。主要应用于桌面繁多时的页面环境辅助识别。
|
||||||
|
|
||||||
|
#### 软件架构
|
||||||
|
适配安卓应用 [AIDE Pro] 的 Gradle 编译结构。
|
||||||
|
也适配安卓应用 [AndroidIDE] 的 Gradle 编译结构。
|
||||||
|
|
||||||
|
|
||||||
|
#### Gradle 编译说明
|
||||||
|
调试版编译命令 :gradle assembleBetaDebug
|
||||||
|
阶段版编译命令 :bash .winboll/bashPublishAPKAddTag.sh numtable
|
||||||
|
|
||||||
|
#### 使用说明
|
||||||
|
|
||||||
|
#### 参与贡献
|
||||||
|
|
||||||
|
1. Fork 本仓库
|
||||||
|
2. 新建 Feat_xxx 分支
|
||||||
|
3. 提交代码 : ZhanGSKen(ZhanGSKen<zhangsken@188.com>)
|
||||||
|
4. 新建 Pull Request
|
||||||
|
|
||||||
|
|
||||||
|
#### 特技
|
||||||
|
|
||||||
|
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
||||||
|
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
|
||||||
|
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
|
||||||
|
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
|
||||||
|
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
||||||
|
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||||
|
|
||||||
|
#### 参考文档
|
||||||
1
numtable/app_update_description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
73
numtable/build.gradle
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
apply from: '../.winboll/winboll_app_build.gradle'
|
||||||
|
apply from: '../.winboll/winboll_lint_build.gradle'
|
||||||
|
|
||||||
|
def genVersionName(def versionName){
|
||||||
|
// 检查编译标志位配置
|
||||||
|
assert (winbollBuildProps['stageCount'] != null)
|
||||||
|
assert (winbollBuildProps['baseVersion'] != null)
|
||||||
|
// 保存基础版本号
|
||||||
|
winbollBuildProps.setProperty("baseVersion", "${versionName}");
|
||||||
|
//保存编译标志配置
|
||||||
|
FileOutputStream fos = new FileOutputStream(winbollBuildPropsFile)
|
||||||
|
winbollBuildProps.store(fos, "${winbollBuildPropsDesc}");
|
||||||
|
fos.close();
|
||||||
|
|
||||||
|
// 返回编译版本号
|
||||||
|
return "${versionName}." + winbollBuildProps['stageCount']
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 32
|
||||||
|
buildToolsVersion "32.0.0"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "cc.winboll.studio.numtable"
|
||||||
|
minSdkVersion 24
|
||||||
|
targetSdkVersion 30
|
||||||
|
versionCode 1
|
||||||
|
// versionName 更新后需要手动设置
|
||||||
|
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
|
||||||
|
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
||||||
|
versionName "15.1"
|
||||||
|
if(true) {
|
||||||
|
versionName = genVersionName("${versionName}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
|
||||||
|
// SSH
|
||||||
|
api 'com.jcraft:jsch:0.1.55'
|
||||||
|
// Html 解析
|
||||||
|
api 'org.jsoup:jsoup:1.13.1'
|
||||||
|
// 二维码类库
|
||||||
|
api 'com.google.zxing:core:3.4.1'
|
||||||
|
api 'com.journeyapps:zxing-android-embedded:3.6.0'
|
||||||
|
// 应用介绍页类库
|
||||||
|
api 'io.github.medyo:android-about-page:2.0.0'
|
||||||
|
// 吐司类库
|
||||||
|
api 'com.github.getActivity:ToastUtils:10.5'
|
||||||
|
// 网络连接类库
|
||||||
|
api 'com.squareup.okhttp3:okhttp:4.4.1'
|
||||||
|
// AndroidX 类库
|
||||||
|
api 'androidx.appcompat:appcompat:1.1.0'
|
||||||
|
api 'com.google.android.material:material:1.4.0'
|
||||||
|
//api 'androidx.viewpager:viewpager:1.0.0'
|
||||||
|
//api 'androidx.vectordrawable:vectordrawable:1.1.0'
|
||||||
|
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
|
||||||
|
//api 'androidx.fragment:fragment:1.1.0'
|
||||||
|
|
||||||
|
api 'cc.winboll.studio:libaes:15.8.0'
|
||||||
|
api 'cc.winboll.studio:libapputils:15.8.2'
|
||||||
|
api 'cc.winboll.studio:libappbase:15.8.2'
|
||||||
|
}
|
||||||
8
numtable/build.properties
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
|
#Sun Jun 08 21:21:11 HKT 2025
|
||||||
|
stageCount=1
|
||||||
|
libraryProject=
|
||||||
|
baseVersion=15.1
|
||||||
|
publishVersion=15.1.0
|
||||||
|
buildCount=0
|
||||||
|
baseBetaVersion=15.1.1
|
||||||
21
numtable/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
14
numtable/src/beta/AndroidManifest.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools" >
|
||||||
|
|
||||||
|
<application
|
||||||
|
tools:replace="android:icon"
|
||||||
|
android:icon="@drawable/ic_launcher_beta">
|
||||||
|
|
||||||
|
<!-- Put flavor specific code here -->
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
|
|
||||||
6
numtable/src/beta/res/values/strings.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<string name="app_name">NumTable +</string>
|
||||||
|
|
||||||
|
</resources>
|
||||||
37
numtable/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<manifest
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="cc.winboll.studio.numtable">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@drawable/ic_launcher"
|
||||||
|
android:roundIcon="@drawable/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/MyAppTheme"
|
||||||
|
android:resizeableActivity="true"
|
||||||
|
android:name=".App">
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:label="@string/app_name">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="android.max_aspect"
|
||||||
|
android:value="4.0"/>
|
||||||
|
|
||||||
|
<activity android:name=".GlobalApplication$CrashActivity"/>
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
345
numtable/src/main/java/cc/winboll/studio/numtable/App.java
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
package cc.winboll.studio.numtable;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.HorizontalScrollView;
|
||||||
|
import android.widget.ScrollView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
|
import com.hjq.toast.ToastUtils;
|
||||||
|
import com.hjq.toast.style.WhiteToastStyle;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.lang.Thread.UncaughtExceptionHandler;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
public class App extends GlobalApplication {
|
||||||
|
|
||||||
|
private static Handler MAIN_HANDLER = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
// 初始化 Toast 框架
|
||||||
|
ToastUtils.init(this);
|
||||||
|
// 设置 Toast 布局样式
|
||||||
|
//ToastUtils.setView(R.layout.view_toast);
|
||||||
|
ToastUtils.setStyle(new WhiteToastStyle());
|
||||||
|
ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
|
||||||
|
|
||||||
|
//CrashHandler.getInstance().registerGlobal(this);
|
||||||
|
//CrashHandler.getInstance().registerPart(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(InputStream input, OutputStream output) throws IOException {
|
||||||
|
byte[] buf = new byte[1024 * 8];
|
||||||
|
int len;
|
||||||
|
while ((len = input.read(buf)) != -1) {
|
||||||
|
output.write(buf, 0, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(File file, byte[] data) throws IOException {
|
||||||
|
File parent = file.getParentFile();
|
||||||
|
if (parent != null && !parent.exists()) parent.mkdirs();
|
||||||
|
|
||||||
|
ByteArrayInputStream input = new ByteArrayInputStream(data);
|
||||||
|
FileOutputStream output = new FileOutputStream(file);
|
||||||
|
try {
|
||||||
|
write(input, output);
|
||||||
|
} finally {
|
||||||
|
closeIO(input, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toString(InputStream input) throws IOException {
|
||||||
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
|
write(input, output);
|
||||||
|
try {
|
||||||
|
return output.toString("UTF-8");
|
||||||
|
} finally {
|
||||||
|
closeIO(input, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void closeIO(Closeable... closeables) {
|
||||||
|
for (Closeable closeable : closeables) {
|
||||||
|
try {
|
||||||
|
if (closeable != null) closeable.close();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CrashHandler {
|
||||||
|
|
||||||
|
public static final UncaughtExceptionHandler DEFAULT_UNCAUGHT_EXCEPTION_HANDLER = Thread.getDefaultUncaughtExceptionHandler();
|
||||||
|
|
||||||
|
private static CrashHandler sInstance;
|
||||||
|
|
||||||
|
private PartCrashHandler mPartCrashHandler;
|
||||||
|
|
||||||
|
public static CrashHandler getInstance() {
|
||||||
|
if (sInstance == null) {
|
||||||
|
sInstance = new CrashHandler();
|
||||||
|
}
|
||||||
|
return sInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerGlobal(Context context) {
|
||||||
|
registerGlobal(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerGlobal(Context context, String crashDir) {
|
||||||
|
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandlerImpl(context.getApplicationContext(), crashDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unregister() {
|
||||||
|
Thread.setDefaultUncaughtExceptionHandler(DEFAULT_UNCAUGHT_EXCEPTION_HANDLER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerPart(Context context) {
|
||||||
|
unregisterPart(context);
|
||||||
|
mPartCrashHandler = new PartCrashHandler(context.getApplicationContext());
|
||||||
|
MAIN_HANDLER.postAtFrontOfQueue(mPartCrashHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unregisterPart(Context context) {
|
||||||
|
if (mPartCrashHandler != null) {
|
||||||
|
mPartCrashHandler.isRunning.set(false);
|
||||||
|
mPartCrashHandler = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class PartCrashHandler implements Runnable {
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
|
||||||
|
public AtomicBoolean isRunning = new AtomicBoolean(true);
|
||||||
|
|
||||||
|
public PartCrashHandler(Context context) {
|
||||||
|
this.mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (isRunning.get()) {
|
||||||
|
try {
|
||||||
|
Looper.loop();
|
||||||
|
} catch (final Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
if (isRunning.get()) {
|
||||||
|
MAIN_HANDLER.post(new Runnable(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Toast.makeText(mContext, e.toString(), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (e instanceof RuntimeException) {
|
||||||
|
throw (RuntimeException)e;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class UncaughtExceptionHandlerImpl implements UncaughtExceptionHandler {
|
||||||
|
|
||||||
|
private static DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy_MM_dd-HH_mm_ss");
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
|
||||||
|
private final File mCrashDir;
|
||||||
|
|
||||||
|
public UncaughtExceptionHandlerImpl(Context context, String crashDir) {
|
||||||
|
this.mContext = context;
|
||||||
|
this.mCrashDir = TextUtils.isEmpty(crashDir) ? new File(mContext.getExternalCacheDir(), "crash") : new File(crashDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uncaughtException(Thread thread, Throwable throwable) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
String log = buildLog(throwable);
|
||||||
|
writeLog(log);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(mContext, CrashActivity.class);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
intent.putExtra(Intent.EXTRA_TEXT, log);
|
||||||
|
mContext.startActivity(intent);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
writeLog(e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
throwable.printStackTrace();
|
||||||
|
android.os.Process.killProcess(android.os.Process.myPid());
|
||||||
|
System.exit(0);
|
||||||
|
|
||||||
|
} catch (Throwable e) {
|
||||||
|
if (DEFAULT_UNCAUGHT_EXCEPTION_HANDLER != null) DEFAULT_UNCAUGHT_EXCEPTION_HANDLER.uncaughtException(thread, throwable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildLog(Throwable throwable) {
|
||||||
|
String time = DATE_FORMAT.format(new Date());
|
||||||
|
|
||||||
|
String versionName = "unknown";
|
||||||
|
long versionCode = 0;
|
||||||
|
try {
|
||||||
|
PackageInfo packageInfo = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
|
||||||
|
versionName = packageInfo.versionName;
|
||||||
|
versionCode = Build.VERSION.SDK_INT >= 28 ? packageInfo.getLongVersionCode() : packageInfo.versionCode;
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
|
||||||
|
LinkedHashMap<String, String> head = new LinkedHashMap<String, String>();
|
||||||
|
head.put("Time Of Crash", time);
|
||||||
|
head.put("Device", String.format("%s, %s", Build.MANUFACTURER, Build.MODEL));
|
||||||
|
head.put("Android Version", String.format("%s (%d)", Build.VERSION.RELEASE, Build.VERSION.SDK_INT));
|
||||||
|
head.put("App Version", String.format("%s (%d)", versionName, versionCode));
|
||||||
|
head.put("Kernel", getKernel());
|
||||||
|
head.put("Support Abis", Build.VERSION.SDK_INT >= 21 && Build.SUPPORTED_ABIS != null ? Arrays.toString(Build.SUPPORTED_ABIS): "unknown");
|
||||||
|
head.put("Fingerprint", Build.FINGERPRINT);
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
for (String key : head.keySet()) {
|
||||||
|
if (builder.length() != 0) builder.append("\n");
|
||||||
|
builder.append(key);
|
||||||
|
builder.append(" : ");
|
||||||
|
builder.append(head.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append("\n\n");
|
||||||
|
builder.append(Log.getStackTraceString(throwable));
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeLog(String log) {
|
||||||
|
String time = DATE_FORMAT.format(new Date());
|
||||||
|
File file = new File(mCrashDir, "crash_" + time + ".txt");
|
||||||
|
try {
|
||||||
|
write(file, log.getBytes("UTF-8"));
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getKernel() {
|
||||||
|
try {
|
||||||
|
return App.toString(new FileInputStream("/proc/version")).trim();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
return e.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class CrashActivity extends Activity {
|
||||||
|
|
||||||
|
private String mLog;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setTheme(android.R.style.Theme_DeviceDefault);
|
||||||
|
setTitle("App Crash");
|
||||||
|
|
||||||
|
mLog = getIntent().getStringExtra(Intent.EXTRA_TEXT);
|
||||||
|
|
||||||
|
ScrollView contentView = new ScrollView(this);
|
||||||
|
contentView.setFillViewport(true);
|
||||||
|
|
||||||
|
HorizontalScrollView horizontalScrollView = new HorizontalScrollView(this);
|
||||||
|
|
||||||
|
TextView textView = new TextView(this);
|
||||||
|
int padding = dp2px(16);
|
||||||
|
textView.setPadding(padding, padding, padding, padding);
|
||||||
|
textView.setText(mLog);
|
||||||
|
textView.setTextIsSelectable(true);
|
||||||
|
textView.setTypeface(Typeface.DEFAULT);
|
||||||
|
textView.setLinksClickable(true);
|
||||||
|
|
||||||
|
horizontalScrollView.addView(textView);
|
||||||
|
contentView.addView(horizontalScrollView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
|
||||||
|
setContentView(contentView);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restart() {
|
||||||
|
Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
|
||||||
|
if (intent != null) {
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
finish();
|
||||||
|
android.os.Process.killProcess(android.os.Process.myPid());
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int dp2px(float dpValue) {
|
||||||
|
final float scale = Resources.getSystem().getDisplayMetrics().density;
|
||||||
|
return (int) (dpValue * scale + 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
menu.add(0, android.R.id.copy, 0, android.R.string.copy)
|
||||||
|
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case android.R.id.copy:
|
||||||
|
ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
cm.setPrimaryClip(ClipData.newPlainText(getPackageName(), mLog));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package cc.winboll.studio.numtable;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
import cc.winboll.studio.libappbase.LogView;
|
||||||
|
import com.hjq.toast.ToastUtils;
|
||||||
|
|
||||||
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
LogView mLogView;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
mLogView = findViewById(R.id.logview);
|
||||||
|
|
||||||
|
ToastUtils.show("onCreate");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
mLogView.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108">
|
||||||
|
<path
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="78.5885"
|
||||||
|
android:endY="90.9159"
|
||||||
|
android:startX="48.7653"
|
||||||
|
android:startY="61.0927"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1" />
|
||||||
|
</vector>
|
||||||
13
numtable/src/main/res/drawable/ic_launcher.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="512dp"
|
||||||
|
android:height="512dp"
|
||||||
|
android:viewportWidth="512"
|
||||||
|
android:viewportHeight="512">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF3D8A1C"
|
||||||
|
android:strokeColor="#FFF5DD00"
|
||||||
|
android:strokeWidth="20.0"
|
||||||
|
android:strokeLineCap="round"
|
||||||
|
android:strokeMiterLimit="10"
|
||||||
|
android:pathData="M47.53 417.75C38.23 258.17 97.09 94.95 156.27 94.16 211.66 98.38 260.9 237.99 329.08 242.47 351.54 241.69 397.94 228.17 449.46 88.59 447.52 262.11 394.97 417.45 338.71 418.74 279.06 412.93 220.17 297.22 157.81 295.26 132.98 294.7 116.37 308.69 47.53 417.75Z"/>
|
||||||
|
</vector>
|
||||||
170
numtable/src/main/res/drawable/ic_launcher_background.xml
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFBC41E"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeColor="#33FFFFFF"
|
||||||
|
android:strokeWidth="0.8" />
|
||||||
|
</vector>
|
||||||
11
numtable/src/main/res/drawable/ic_launcher_beta.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:clickable="true">
|
||||||
|
<item android:drawable="@drawable/ic_launcher_background"/>
|
||||||
|
<item
|
||||||
|
android:left="15dp"
|
||||||
|
android:top="15dp"
|
||||||
|
android:right="15dp"
|
||||||
|
android:bottom="15dp"
|
||||||
|
android:drawable="@drawable/ic_launcher"/>
|
||||||
|
</layer-list>
|
||||||
51
numtable/src/main/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?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:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1.0"
|
||||||
|
android:gravity="center_vertical|center_horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="NumTable"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1.0">
|
||||||
|
|
||||||
|
<cc.winboll.studio.libappbase.LogView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/logview"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
5
numtable/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
||||||
BIN
numtable/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
numtable/src/main/res/mipmap-hdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
numtable/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
numtable/src/main/res/mipmap-mdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
numtable/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
numtable/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
numtable/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
numtable/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
numtable/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
numtable/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
6
numtable/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="colorPrimary">#009688</color>
|
||||||
|
<color name="colorPrimaryDark">#00796B</color>
|
||||||
|
<color name="colorAccent">#FF9800</color>
|
||||||
|
</resources>
|
||||||
4
numtable/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">NumTable</string>
|
||||||
|
|
||||||
|
</resources>
|
||||||
11
numtable/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="MyAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
||||||
12
numtable/src/stage/AndroidManifest.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools" >
|
||||||
|
|
||||||
|
<application>
|
||||||
|
|
||||||
|
<!-- Put flavor specific code here -->
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
|
|
||||||
6
numtable/src/stage/res/values/strings.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Put flavor specific strings here -->
|
||||||
|
|
||||||
|
</resources>
|
||||||
@@ -45,9 +45,9 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
api 'cc.winboll.studio:libaes:15.6.0'
|
api 'cc.winboll.studio:libaes:15.9.1'
|
||||||
api 'cc.winboll.studio:libapputils:15.3.4'
|
api 'cc.winboll.studio:libapputils:15.8.4'
|
||||||
api 'cc.winboll.studio:libappbase:15.7.6'
|
api 'cc.winboll.studio:libappbase:15.8.4'
|
||||||
|
|
||||||
// 吐司提示库
|
// 吐司提示库
|
||||||
api 'com.github.getActivity:ToastUtils:10.5'
|
api 'com.github.getActivity:ToastUtils:10.5'
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Thu May 29 09:43:37 HKT 2025
|
#Mon Jun 23 14:49:46 HKT 2025
|
||||||
stageCount=2
|
stageCount=6
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=15.4
|
baseVersion=15.4
|
||||||
publishVersion=15.4.1
|
publishVersion=15.4.5
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.4.2
|
baseBetaVersion=15.4.6
|
||||||
|
|||||||
@@ -121,6 +121,8 @@
|
|||||||
|
|
||||||
<activity android:name="cc.winboll.studio.powerbell.activities.AboutActivity"/>
|
<activity android:name="cc.winboll.studio.powerbell.activities.AboutActivity"/>
|
||||||
|
|
||||||
|
<activity android:name="cc.winboll.studio.powerbell.activities.PixelPickerActivity"/>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package cc.winboll.studio.powerbell;
|
package cc.winboll.studio.powerbell;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Environment;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
import cc.winboll.studio.powerbell.receivers.GlobalApplicationReceiver;
|
import cc.winboll.studio.powerbell.receivers.GlobalApplicationReceiver;
|
||||||
@@ -18,7 +19,7 @@ public class App extends GlobalApplication {
|
|||||||
static AppCacheUtils _mAppCacheUtils;
|
static AppCacheUtils _mAppCacheUtils;
|
||||||
GlobalApplicationReceiver mReceiver;
|
GlobalApplicationReceiver mReceiver;
|
||||||
static String szTempDir = "";
|
static String szTempDir = "";
|
||||||
|
|
||||||
public static String getTempDirPath() {
|
public static String getTempDirPath() {
|
||||||
return szTempDir;
|
return szTempDir;
|
||||||
}
|
}
|
||||||
@@ -26,15 +27,24 @@ public class App extends GlobalApplication {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
|
// 临时文件夹方案1
|
||||||
|
// 获取Pictures文件夹路径(Android 10及以上推荐使用MediaStore,此处为传统方式)
|
||||||
|
File picturesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
|
||||||
|
// 定义目标文件路径(在Pictures目录下创建"PowerBell"子文件夹及文件)
|
||||||
|
File powerBellDir = new File(picturesDir, "PowerBell");
|
||||||
|
|
||||||
// 初始化临时文件夹目录
|
// 临时文件夹方案2 <图片保存失败>
|
||||||
File fTempDir = new File(getExternalCacheDir(), "TempDir");
|
// 获取Pictures文件夹路径(Android 10及以上推荐使用MediaStore,此处为传统方式)
|
||||||
if(!fTempDir.exists()) {
|
//File powerBellDir = getExternalFilesDir("TempDir");
|
||||||
fTempDir.mkdirs();
|
|
||||||
|
// 先创建文件夹(如果不存在)
|
||||||
|
if (!powerBellDir.exists()) {
|
||||||
|
powerBellDir.mkdirs();
|
||||||
}
|
}
|
||||||
szTempDir = fTempDir.getAbsolutePath();
|
szTempDir = powerBellDir.getAbsolutePath();
|
||||||
|
|
||||||
|
|
||||||
// 初始化 Toast 框架
|
// 初始化 Toast 框架
|
||||||
ToastUtils.init(this);
|
ToastUtils.init(this);
|
||||||
// 设置 Toast 布局样式
|
// 设置 Toast 布局样式
|
||||||
@@ -45,7 +55,7 @@ public class App extends GlobalApplication {
|
|||||||
// 设置数据配置存储工具
|
// 设置数据配置存储工具
|
||||||
_mAppConfigUtils = getAppConfigUtils(this);
|
_mAppConfigUtils = getAppConfigUtils(this);
|
||||||
_mAppCacheUtils = getAppCacheUtils(this);
|
_mAppCacheUtils = getAppCacheUtils(this);
|
||||||
|
|
||||||
mReceiver = new GlobalApplicationReceiver(this);
|
mReceiver = new GlobalApplicationReceiver(this);
|
||||||
mReceiver.registerAction();
|
mReceiver.registerAction();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,23 +10,27 @@ import android.os.Bundle;
|
|||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import cc.winboll.studio.libaes.views.AToolbar;
|
import cc.winboll.studio.libaes.views.AToolbar;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.LogView;
|
|
||||||
import cc.winboll.studio.powerbell.MainActivity;
|
import cc.winboll.studio.powerbell.MainActivity;
|
||||||
import cc.winboll.studio.powerbell.activities.AboutActivity;
|
import cc.winboll.studio.powerbell.activities.AboutActivity;
|
||||||
import cc.winboll.studio.powerbell.activities.BackgroundPictureActivity;
|
import cc.winboll.studio.powerbell.activities.BackgroundPictureActivity;
|
||||||
import cc.winboll.studio.powerbell.activities.BatteryReporterActivity;
|
import cc.winboll.studio.powerbell.activities.BatteryReporterActivity;
|
||||||
import cc.winboll.studio.powerbell.activities.ClearRecordActivity;
|
import cc.winboll.studio.powerbell.activities.ClearRecordActivity;
|
||||||
|
import cc.winboll.studio.powerbell.activities.WinBoLLActivity;
|
||||||
|
import cc.winboll.studio.powerbell.beans.BackgroundPictureBean;
|
||||||
import cc.winboll.studio.powerbell.fragments.MainViewFragment;
|
import cc.winboll.studio.powerbell.fragments.MainViewFragment;
|
||||||
|
import cc.winboll.studio.powerbell.utils.BackgroundPictureUtils;
|
||||||
|
|
||||||
|
public class MainActivity extends WinBoLLActivity {
|
||||||
|
|
||||||
public class MainActivity extends Activity {
|
|
||||||
public static final String TAG = "MainActivity";
|
public static final String TAG = "MainActivity";
|
||||||
public static final int BACKGROUND_PICTURE_REQUEST_CODE = 0;
|
public static final int BACKGROUND_PICTURE_REQUEST_CODE = 0;
|
||||||
|
|
||||||
public static MainActivity _mMainActivity;
|
public static MainActivity _mMainActivity;
|
||||||
LogView mLogView;
|
//LogView mLogView;
|
||||||
//ArrayList<Fragment> mlistFragment;
|
//ArrayList<Fragment> mlistFragment;
|
||||||
App mApplication;
|
App mApplication;
|
||||||
//AppConfigUtils mAppConfigUtils;
|
//AppConfigUtils mAppConfigUtils;
|
||||||
@@ -35,6 +39,16 @@ public class MainActivity extends Activity {
|
|||||||
MainViewFragment mMainViewFragment;
|
MainViewFragment mMainViewFragment;
|
||||||
AToolbar mAToolbar;
|
AToolbar mAToolbar;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Activity getActivity() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
//LogUtils.d(TAG, "onCreate(...)");
|
//LogUtils.d(TAG, "onCreate(...)");
|
||||||
@@ -42,10 +56,10 @@ public class MainActivity extends Activity {
|
|||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
// 设置调试日志
|
// 设置调试日志
|
||||||
mLogView = findViewById(R.id.logview);
|
// mLogView = findViewById(R.id.logview);
|
||||||
mLogView.start();
|
// mLogView.start();
|
||||||
//LogUtils.d(TAG, "LogView Start.");
|
// //LogUtils.d(TAG, "LogView Start.");
|
||||||
mLogView.updateLogView();
|
// mLogView.updateLogView();
|
||||||
|
|
||||||
_mMainActivity = MainActivity.this;
|
_mMainActivity = MainActivity.this;
|
||||||
mApplication = (App) getApplication();
|
mApplication = (App) getApplication();
|
||||||
@@ -117,8 +131,8 @@ public class MainActivity extends Activity {
|
|||||||
super.onResume();
|
super.onResume();
|
||||||
// 回到窗口自动取消提醒消息
|
// 回到窗口自动取消提醒消息
|
||||||
//NotificationHelper.cancelRemindNotification(this);
|
//NotificationHelper.cancelRemindNotification(this);
|
||||||
|
|
||||||
reloadBackground();
|
reloadBackground();
|
||||||
|
setBackgroundColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Menu icons are inflated just as they were with actionbar
|
// Menu icons are inflated just as they were with actionbar
|
||||||
@@ -157,6 +171,8 @@ public class MainActivity extends Activity {
|
|||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.setClass(this, BackgroundPictureActivity.class);
|
intent.setClass(this, BackgroundPictureActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
} else if (menuItemId == R.id.action_log) {
|
||||||
|
App.getWinBoLLActivityManager().startLogActivity(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -193,4 +209,12 @@ public class MainActivity extends Activity {
|
|||||||
moveTaskToBack(true);
|
moveTaskToBack(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setBackgroundColor() {
|
||||||
|
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(MainActivity.this);
|
||||||
|
BackgroundPictureBean bean = utils.getBackgroundPictureBean();
|
||||||
|
int nPixelColor = bean.getPixelColor();
|
||||||
|
RelativeLayout mainLayout = findViewById(R.id.activitymainRelativeLayout1);
|
||||||
|
mainLayout.setBackgroundColor(nPixelColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,27 @@
|
|||||||
package cc.winboll.studio.powerbell.activities;
|
package cc.winboll.studio.powerbell.activities;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.Toast;
|
import android.widget.RelativeLayout;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
import cc.winboll.studio.libaes.views.AToolbar;
|
import cc.winboll.studio.libaes.views.AToolbar;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
import cc.winboll.studio.libappbase.utils.ToastUtils;
|
||||||
import cc.winboll.studio.powerbell.App;
|
import cc.winboll.studio.powerbell.App;
|
||||||
import cc.winboll.studio.powerbell.R;
|
import cc.winboll.studio.powerbell.R;
|
||||||
import cc.winboll.studio.powerbell.activities.BackgroundPictureActivity;
|
|
||||||
import cc.winboll.studio.powerbell.beans.BackgroundPictureBean;
|
import cc.winboll.studio.powerbell.beans.BackgroundPictureBean;
|
||||||
import cc.winboll.studio.powerbell.dialogs.BackgroundPicturePreviewDialog;
|
import cc.winboll.studio.powerbell.dialogs.BackgroundPicturePreviewDialog;
|
||||||
import cc.winboll.studio.powerbell.utils.BackgroundPictureUtils;
|
import cc.winboll.studio.powerbell.utils.BackgroundPictureUtils;
|
||||||
@@ -24,42 +29,45 @@ import cc.winboll.studio.powerbell.utils.FileUtils;
|
|||||||
import cc.winboll.studio.powerbell.utils.UriUtil;
|
import cc.winboll.studio.powerbell.utils.UriUtil;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
public class BackgroundPictureActivity extends Activity
|
public class BackgroundPictureActivity extends WinBoLLActivity implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
||||||
implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
|
||||||
|
|
||||||
public static final String TAG = "BackgroundPictureActivity";
|
public static final String TAG = "BackgroundPictureActivity";
|
||||||
|
|
||||||
public BackgroundPictureUtils mBackgroundPictureUtils;
|
public BackgroundPictureUtils mBackgroundPictureUtils;
|
||||||
|
|
||||||
// 图片选择请求
|
// 图片选择请求码
|
||||||
public static final int REQUEST_SELECT_PICTURE = 0;
|
public static final int REQUEST_SELECT_PICTURE = 0;
|
||||||
// 照相选择请求
|
|
||||||
public static final int REQUEST_TAKE_PHOTO = 1;
|
public static final int REQUEST_TAKE_PHOTO = 1;
|
||||||
// 图片裁剪选择请求
|
|
||||||
public static final int REQUEST_CROP_IMAGE = 2;
|
public static final int REQUEST_CROP_IMAGE = 2;
|
||||||
|
private static final int STORAGE_PERMISSION_REQUEST = 100;
|
||||||
|
|
||||||
AToolbar mAToolbar;
|
private AToolbar mAToolbar;
|
||||||
// 所有图片存储的文件夹
|
private File mfBackgroundDir; // 背景图片存储文件夹
|
||||||
File mfBackgroundDir;
|
private File mfPictureDir; // 拍照与剪裁临时文件夹
|
||||||
// 拍照与剪裁的文件夹
|
private File mfTakePhoto; // 拍照文件
|
||||||
File mfPictureDir;
|
private File mfRecivedPicture; // 接收的图片文件
|
||||||
// 拍照文件类
|
private File mfTempCropPicture; // 剪裁临时文件
|
||||||
File mfTakePhoto;
|
private File mfRecivedCropPicture; // 剪裁后的目标文件
|
||||||
// 接收到的图片文件类
|
|
||||||
public File mfRecivedPicture;
|
// 静态变量
|
||||||
// 剪裁文件类
|
|
||||||
File mfTempCropPicture;
|
|
||||||
// 剪裁接收后的文件的文件名
|
|
||||||
public static String _mszRecivedCropPicture = "RecivedCrop.jpg";
|
public static String _mszRecivedCropPicture = "RecivedCrop.jpg";
|
||||||
File mfRecivedCropPicture;
|
private static String _mszCommonFileType = "jpeg";
|
||||||
static String _mszCommonFileType = "jpeg";
|
private int mnPictureCompress = 100;
|
||||||
// 背景图片的压缩比
|
private static String _RecivedPictureFileName;
|
||||||
int mnPictureCompress = 100;
|
|
||||||
static String _RecivedPictureFileName;
|
@Override
|
||||||
|
public Activity getActivity() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -67,30 +75,29 @@ implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
|||||||
setContentView(R.layout.activity_backgroundpicture);
|
setContentView(R.layout.activity_backgroundpicture);
|
||||||
initEnv();
|
initEnv();
|
||||||
|
|
||||||
|
// 初始化工具类和文件夹
|
||||||
mBackgroundPictureUtils = BackgroundPictureUtils.getInstance(this);
|
mBackgroundPictureUtils = BackgroundPictureUtils.getInstance(this);
|
||||||
mfBackgroundDir = new File(mBackgroundPictureUtils.getBackgroundDir());
|
mfBackgroundDir = new File(mBackgroundPictureUtils.getBackgroundDir());
|
||||||
if (!mfBackgroundDir.exists()) {
|
if (!mfBackgroundDir.exists()) {
|
||||||
mfBackgroundDir.mkdirs();
|
mfBackgroundDir.mkdirs();
|
||||||
}
|
}
|
||||||
//mfPictureDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), getString(R.string.app_projectname));
|
|
||||||
mfPictureDir = new File(App.getTempDirPath());
|
mfPictureDir = new File(App.getTempDirPath());
|
||||||
if (!mfPictureDir.exists()) {
|
if (!mfPictureDir.exists()) {
|
||||||
mfPictureDir.mkdirs();
|
mfPictureDir.mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 初始化文件对象
|
||||||
mfTakePhoto = new File(mfPictureDir, "TakePhoto.jpg");
|
mfTakePhoto = new File(mfPictureDir, "TakePhoto.jpg");
|
||||||
mfTempCropPicture = new File(mfPictureDir, "TempCrop.jpg");
|
mfTempCropPicture = new File(mfPictureDir, "TempCrop.jpg");
|
||||||
|
|
||||||
mfRecivedPicture = getRecivedPictureFile(this);
|
mfRecivedPicture = getRecivedPictureFile(this);
|
||||||
mfRecivedCropPicture = new File(mfBackgroundDir, _mszRecivedCropPicture);
|
mfRecivedCropPicture = new File(mfBackgroundDir, _mszRecivedCropPicture);
|
||||||
|
|
||||||
// 初始化工具栏
|
// 初始化工具栏
|
||||||
mAToolbar = (AToolbar) findViewById(R.id.toolbar);
|
mAToolbar = (AToolbar) findViewById(R.id.toolbar);
|
||||||
setActionBar(mAToolbar);
|
setActionBar(mAToolbar);
|
||||||
//mAToolbar.setTitle(getTitle() + "-" + getString(R.string.subtitle_activity_backgroundpicture));
|
|
||||||
mAToolbar.setSubtitle(R.string.subtitle_activity_backgroundpicture);
|
mAToolbar.setSubtitle(R.string.subtitle_activity_backgroundpicture);
|
||||||
//mAToolbar.setTitleTextAppearance(this, R.style.Toolbar_TitleText);
|
|
||||||
//mAToolbar.setSubtitleTextAppearance(this, R.style.Toolbar_SubTitleText);
|
|
||||||
//mAToolbar.setBackgroundColor(getColor(R.color.colorPrimary));
|
|
||||||
setActionBar(mAToolbar);
|
|
||||||
getActionBar().setDisplayHomeAsUpEnabled(true);
|
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
mAToolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
mAToolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -99,41 +106,30 @@ implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//给按钮设置点击事件
|
// 设置按钮点击事件
|
||||||
findViewById(R.id.activitybackgroundpictureAButton5).setOnClickListener(onOriginNullClickListener);
|
findViewById(R.id.activitybackgroundpictureAButton5).setOnClickListener(onOriginNullClickListener);
|
||||||
findViewById(R.id.activitybackgroundpictureAButton4).setOnClickListener(onReceivedPictureClickListener);
|
findViewById(R.id.activitybackgroundpictureAButton4).setOnClickListener(onReceivedPictureClickListener);
|
||||||
findViewById(R.id.activitybackgroundpictureAButton1).setOnClickListener(onTakePhotoClickListener);
|
findViewById(R.id.activitybackgroundpictureAButton1).setOnClickListener(onTakePhotoClickListener);
|
||||||
findViewById(R.id.activitybackgroundpictureAButton2).setOnClickListener(onSelectPictureClickListener);
|
findViewById(R.id.activitybackgroundpictureAButton2).setOnClickListener(onSelectPictureClickListener);
|
||||||
findViewById(R.id.activitybackgroundpictureAButton3).setOnClickListener(onCropPictureClickListener);
|
findViewById(R.id.activitybackgroundpictureAButton3).setOnClickListener(onCropPictureClickListener);
|
||||||
findViewById(R.id.activitybackgroundpictureAButton6).setOnClickListener(onCropFreePictureClickListener);
|
findViewById(R.id.activitybackgroundpictureAButton6).setOnClickListener(onCropFreePictureClickListener);
|
||||||
|
findViewById(R.id.activitybackgroundpictureAButton7).setOnClickListener(onPixelPickerClickListener);
|
||||||
|
findViewById(R.id.activitybackgroundpictureAButton8).setOnClickListener(onCleanPixelClickListener);
|
||||||
|
|
||||||
updatePreviewBackground();
|
updatePreviewBackground();
|
||||||
|
|
||||||
|
// 处理分享的图片
|
||||||
|
|
||||||
// 判断并且处理应用分享到的文件
|
|
||||||
//
|
|
||||||
//ToastUtils.show("Activity Opened.");
|
|
||||||
|
|
||||||
// 预备接收参数
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
String type = intent.getType();
|
String type = intent.getType();
|
||||||
|
|
||||||
//LogUtils.d(TAG, "action : " + action);
|
if (Intent.ACTION_SEND.equals(action) && type != null && isImageType(type)) {
|
||||||
//LogUtils.d(TAG, "type : " + type);
|
BackgroundPicturePreviewDialog dlg = new BackgroundPicturePreviewDialog(this);
|
||||||
|
|
||||||
// 判断是否进入图片分享状态
|
|
||||||
if (Intent.ACTION_SEND.equals(action)
|
|
||||||
&& type != null
|
|
||||||
&& ("image/*".equals(type) || "image/jpeg".equals(type) || "image/jpg".equals(type) || "image/png".equals(type) || "image/webp".equals(type))) {
|
|
||||||
// 预览图片
|
|
||||||
BackgroundPicturePreviewDialog dlg= new BackgroundPicturePreviewDialog(this);
|
|
||||||
dlg.show();
|
dlg.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initEnv() {
|
private void initEnv() {
|
||||||
LogUtils.d(TAG, "initEnv()");
|
LogUtils.d(TAG, "initEnv()");
|
||||||
_RecivedPictureFileName = "Recived.data";
|
_RecivedPictureFileName = "Recived.data";
|
||||||
}
|
}
|
||||||
@@ -144,47 +140,55 @@ implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAcceptRecivedPicture(String szPreRecivedPictureName) {
|
public void onAcceptRecivedPicture(String szPreRecivedPictureName) {
|
||||||
//ToastUtils.show("onAcceptRecivedPicture");
|
|
||||||
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(this);
|
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(this);
|
||||||
utils.getBackgroundPictureBean().setIsUseBackgroundFile(true);
|
utils.getBackgroundPictureBean().setIsUseBackgroundFile(true);
|
||||||
utils.saveData();
|
utils.saveData();
|
||||||
File fPreRecivedPictureName = new File(utils.getBackgroundDir(), szPreRecivedPictureName);
|
|
||||||
FileUtils.copyFile(fPreRecivedPictureName, mfRecivedPicture);
|
|
||||||
// 加载背景
|
|
||||||
startCropImageActivity(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
File sourceFile = new File(utils.getBackgroundDir(), szPreRecivedPictureName);
|
||||||
// 更新预览背景
|
if (FileUtils.copyFile(sourceFile, mfRecivedPicture)) {
|
||||||
//
|
startCropImageActivity(false);
|
||||||
public void updatePreviewBackground() {
|
|
||||||
LogUtils.d(TAG, "updatePreviewBackground");
|
|
||||||
ImageView ivPreviewBackground = findViewById(R.id.activitybackgroundpictureImageView1);
|
|
||||||
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(this);
|
|
||||||
utils.loadBackgroundPictureBean();
|
|
||||||
boolean isUseBackgroundFile = utils.getBackgroundPictureBean().isUseBackgroundFile();
|
|
||||||
if (isUseBackgroundFile && mfRecivedCropPicture.exists()) {
|
|
||||||
try {
|
|
||||||
String szBackgroundFilePath = utils.getBackgroundDir() + getBackgroundFileName();
|
|
||||||
Drawable drawableBackground = FileUtils.getImageDrawable(szBackgroundFilePath);
|
|
||||||
drawableBackground.setAlpha(120);
|
|
||||||
ivPreviewBackground.setImageDrawable(drawableBackground);
|
|
||||||
ToastUtils.show("Use acceptRecived background.");
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ToastUtils.show(" No background.");
|
ToastUtils.show("图片复制失败,请重试");
|
||||||
Drawable drawableBackground = getDrawable(R.drawable.blank10x10);
|
|
||||||
drawableBackground.setAlpha(120);
|
|
||||||
ivPreviewBackground.setImageDrawable(drawableBackground);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新背景图片预览
|
||||||
|
*/
|
||||||
|
public void updatePreviewBackground() {
|
||||||
|
LogUtils.d(TAG, "updatePreviewBackground");
|
||||||
|
ImageView ivPreviewBackground = (ImageView) findViewById(R.id.activitybackgroundpictureImageView1);
|
||||||
|
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(this);
|
||||||
|
utils.loadBackgroundPictureBean();
|
||||||
|
|
||||||
|
boolean isUseBackgroundFile = utils.getBackgroundPictureBean().isUseBackgroundFile();
|
||||||
|
if (isUseBackgroundFile && mfRecivedCropPicture.exists()) {
|
||||||
|
try {
|
||||||
|
String filePath = utils.getBackgroundDir() + getBackgroundFileName();
|
||||||
|
Drawable drawable = FileUtils.getImageDrawable(filePath);
|
||||||
|
if (drawable != null) {
|
||||||
|
//drawable.setAlpha(120);
|
||||||
|
ivPreviewBackground.setImageDrawable(drawable);
|
||||||
|
}
|
||||||
|
//ToastUtils.show("背景图片已更新");
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
ToastUtils.show("背景图片加载失败");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ToastUtils.show("未使用背景图片");
|
||||||
|
Drawable drawable = getResources().getDrawable(R.drawable.blank10x10);
|
||||||
|
if (drawable != null) {
|
||||||
|
drawable.setAlpha(120);
|
||||||
|
ivPreviewBackground.setImageDrawable(drawable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击事件监听器
|
||||||
private View.OnClickListener onOriginNullClickListener = new View.OnClickListener() {
|
private View.OnClickListener onOriginNullClickListener = new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
// 选择原始空白背景
|
|
||||||
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(BackgroundPictureActivity.this);
|
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(BackgroundPictureActivity.this);
|
||||||
BackgroundPictureBean bean = utils.getBackgroundPictureBean();
|
BackgroundPictureBean bean = utils.getBackgroundPictureBean();
|
||||||
bean.setIsUseBackgroundFile(false);
|
bean.setIsUseBackgroundFile(false);
|
||||||
@@ -196,11 +200,10 @@ implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
|||||||
private View.OnClickListener onSelectPictureClickListener = new View.OnClickListener() {
|
private View.OnClickListener onSelectPictureClickListener = new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
// 导入外部图片
|
if (checkAndRequestStoragePermission()) {
|
||||||
Intent intent = new Intent(
|
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
||||||
Intent.ACTION_PICK,
|
startActivityForResult(intent, REQUEST_SELECT_PICTURE);
|
||||||
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
}
|
||||||
startActivityForResult(intent, REQUEST_SELECT_PICTURE);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -211,7 +214,7 @@ implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
|||||||
if (fCheck.exists()) {
|
if (fCheck.exists()) {
|
||||||
startCropImageActivity(false);
|
startCropImageActivity(false);
|
||||||
} else {
|
} else {
|
||||||
ToastUtils.show("There is not any picture to crop.");
|
ToastUtils.show("没有可剪裁的图片");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -223,7 +226,7 @@ implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
|||||||
if (fCheck.exists()) {
|
if (fCheck.exists()) {
|
||||||
startCropImageActivity(true);
|
startCropImageActivity(true);
|
||||||
} else {
|
} else {
|
||||||
ToastUtils.show("There is not any picture to crop.");
|
ToastUtils.show("没有可剪裁的图片");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -233,6 +236,7 @@ implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
|||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
LogUtils.d(TAG, "onTakePhotoClickListener");
|
LogUtils.d(TAG, "onTakePhotoClickListener");
|
||||||
LogUtils.d(TAG, "mfTakePhoto : " + mfTakePhoto.getPath());
|
LogUtils.d(TAG, "mfTakePhoto : " + mfTakePhoto.getPath());
|
||||||
|
|
||||||
if (mfTakePhoto.exists()) {
|
if (mfTakePhoto.exists()) {
|
||||||
mfTakePhoto.delete();
|
mfTakePhoto.delete();
|
||||||
}
|
}
|
||||||
@@ -240,56 +244,94 @@ implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
|||||||
mfTakePhoto.createNewFile();
|
mfTakePhoto.createNewFile();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
ToastUtils.show("拍照文件创建失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkAndRequestStoragePermission()) {
|
||||||
|
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||||
|
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
|
||||||
}
|
}
|
||||||
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
|
||||||
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private View.OnClickListener onReceivedPictureClickListener = new View.OnClickListener() {
|
private View.OnClickListener onReceivedPictureClickListener = new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
// 选择接收到的背景图片
|
|
||||||
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(BackgroundPictureActivity.this);
|
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(BackgroundPictureActivity.this);
|
||||||
utils.getBackgroundPictureBean().setIsUseBackgroundFile(true);
|
utils.getBackgroundPictureBean().setIsUseBackgroundFile(true);
|
||||||
utils.saveData();
|
utils.saveData();
|
||||||
updatePreviewBackground();
|
updatePreviewBackground();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private View.OnClickListener onPixelPickerClickListener = new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
// 从文件路径启动像素拾取活动
|
||||||
|
//String imagePath = "/storage/emulated/0/DCIM/Camera/sample.jpg";
|
||||||
|
String imagePath = mfRecivedCropPicture.toString();
|
||||||
|
Intent intent = new Intent(getApplicationContext(), PixelPickerActivity.class);
|
||||||
|
intent.putExtra("imagePath", imagePath);
|
||||||
|
startActivity(intent);
|
||||||
|
//App.getWinBoLLActivityManager().startWinBoLLActivity(getActivity(), intent, PixelPickerActivity.class);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private View.OnClickListener onCleanPixelClickListener = new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(BackgroundPictureActivity.this);
|
||||||
|
BackgroundPictureBean bean = utils.getBackgroundPictureBean();
|
||||||
|
bean.setPixelColor(0);
|
||||||
|
utils.saveData();
|
||||||
|
setBackgroundColor();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 压缩图片并保存到接收文件
|
||||||
|
*/
|
||||||
void compressQualityToRecivedPicture(Bitmap bitmap) {
|
void compressQualityToRecivedPicture(Bitmap bitmap) {
|
||||||
// 设置输出流
|
|
||||||
OutputStream outStream = null;
|
OutputStream outStream = null;
|
||||||
try {
|
try {
|
||||||
// 创建输出流对象,准备写入压缩后的图片文件
|
|
||||||
mfRecivedPicture = getRecivedPictureFile(this);
|
mfRecivedPicture = getRecivedPictureFile(this);
|
||||||
// 创建新的接收文件
|
|
||||||
if (!mfRecivedPicture.exists()) {
|
if (!mfRecivedPicture.exists()) {
|
||||||
mfRecivedPicture.createNewFile();
|
mfRecivedPicture.createNewFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileOutputStream fos = new FileOutputStream(mfRecivedPicture);
|
FileOutputStream fos = new FileOutputStream(mfRecivedPicture);
|
||||||
|
|
||||||
// 获取输出流对象
|
|
||||||
outStream = new BufferedOutputStream(fos);
|
outStream = new BufferedOutputStream(fos);
|
||||||
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
|
||||||
// 使用默认的质量参数压缩图片
|
|
||||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream); // 70% 的质量
|
|
||||||
|
|
||||||
// 关闭输出流以完成文件操作
|
|
||||||
outStream.flush();
|
outStream.flush();
|
||||||
outStream.close();
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
ToastUtils.show("图片压缩失败");
|
||||||
|
} finally {
|
||||||
|
if (outStream != null) {
|
||||||
|
try {
|
||||||
|
outStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bitmap != null && !bitmap.isRecycled()) {
|
||||||
|
bitmap.recycle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动图片裁剪活动
|
||||||
|
* @param isCropFree 是否自由裁剪
|
||||||
|
*/
|
||||||
public void startCropImageActivity(boolean isCropFree) {
|
public void startCropImageActivity(boolean isCropFree) {
|
||||||
LogUtils.d(TAG, "startCropImageActivity");
|
LogUtils.d(TAG, "startCropImageActivity");
|
||||||
BackgroundPictureBean bean = mBackgroundPictureUtils.loadBackgroundPictureBean();
|
BackgroundPictureBean bean = mBackgroundPictureUtils.loadBackgroundPictureBean();
|
||||||
mfRecivedPicture = getRecivedPictureFile(this);
|
mfRecivedPicture = getRecivedPictureFile(this);
|
||||||
Uri uri = UriUtil.getUriForFile(this, mfRecivedPicture);
|
Uri uri = UriUtil.getUriForFile(this, mfRecivedPicture);
|
||||||
LogUtils.d(TAG, "uri : " + uri.toString());
|
LogUtils.d(TAG, "uri : " + uri.toString());
|
||||||
|
|
||||||
if (mfTempCropPicture.exists()) {
|
if (mfTempCropPicture.exists()) {
|
||||||
mfTempCropPicture.delete();
|
mfTempCropPicture.delete();
|
||||||
}
|
}
|
||||||
@@ -297,27 +339,24 @@ implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
|||||||
mfTempCropPicture.createNewFile();
|
mfTempCropPicture.createNewFile();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
ToastUtils.show("剪裁临时文件创建失败");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// 使用正确的文件路径构建 Uri
|
|
||||||
Uri cropOutPutUri = Uri.fromFile(mfTempCropPicture);
|
Uri cropOutPutUri = Uri.fromFile(mfTempCropPicture);
|
||||||
LogUtils.d(TAG, "mfTempCropPicture : " + mfTempCropPicture.getPath());
|
LogUtils.d(TAG, "mfTempCropPicture : " + mfTempCropPicture.getPath());
|
||||||
|
|
||||||
Intent intent = new Intent("com.android.camera.action.CROP");
|
Intent intent = new Intent("com.android.camera.action.CROP");
|
||||||
intent.setDataAndType(uri, "image/" + _mszCommonFileType);
|
intent.setDataAndType(uri, "image/" + _mszCommonFileType);
|
||||||
// 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
|
|
||||||
intent.putExtra("crop", "true");
|
intent.putExtra("crop", "true");
|
||||||
intent.putExtra("noFaceDetection", true);
|
intent.putExtra("noFaceDetection", true);
|
||||||
|
|
||||||
if (!isCropFree) {
|
if (!isCropFree) {
|
||||||
// aspectX aspectY 是宽高的比例
|
|
||||||
intent.putExtra("aspectX", bean.getBackgroundWidth());
|
intent.putExtra("aspectX", bean.getBackgroundWidth());
|
||||||
intent.putExtra("aspectY", bean.getBackgroundHeight());
|
intent.putExtra("aspectY", bean.getBackgroundHeight());
|
||||||
}
|
}
|
||||||
// outputX outputY 是裁剪图片宽高
|
|
||||||
//intent.putExtra("outputX", 100);
|
|
||||||
//intent.putExtra("outputY", 100);
|
|
||||||
//return-data =false 意味着裁剪成功后不能在onActivityResult 的intent 中获得图片
|
|
||||||
//intent.putExtra("return-data", false);
|
|
||||||
intent.putExtra("return-data", true);
|
intent.putExtra("return-data", true);
|
||||||
//裁剪后的图片输出至 cropOutPutUri
|
|
||||||
intent.putExtra(MediaStore.EXTRA_OUTPUT, cropOutPutUri);
|
intent.putExtra(MediaStore.EXTRA_OUTPUT, cropOutPutUri);
|
||||||
intent.putExtra("scale", true);
|
intent.putExtra("scale", true);
|
||||||
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
|
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
|
||||||
@@ -325,13 +364,102 @@ implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
|||||||
startActivityForResult(intent, REQUEST_CROP_IMAGE);
|
startActivityForResult(intent, REQUEST_CROP_IMAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动裁剪窗口,裁剪操作文件为 uirImage
|
/**
|
||||||
//
|
* 保存剪裁后的Bitmap(优化版)
|
||||||
|
*/
|
||||||
|
private void saveCropBitmap(Bitmap bitmap) {
|
||||||
|
if (bitmap == null) {
|
||||||
|
ToastUtils.show("剪裁图片为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内存优化:大图片自动缩放
|
||||||
|
Bitmap scaledBitmap = bitmap;
|
||||||
|
if (bitmap.getByteCount() > 10 * 1024 * 1024) { // 超过10MB
|
||||||
|
float scale = 1.0f;
|
||||||
|
while (scaledBitmap.getByteCount() > 5 * 1024 * 1024) {
|
||||||
|
scale -= 0.2f; // 每次缩小20%
|
||||||
|
if (scale < 0.2f) break; // 最小缩放到20%
|
||||||
|
scaledBitmap = scaleBitmap(scaledBitmap, scale);
|
||||||
|
}
|
||||||
|
if (scaledBitmap != bitmap) {
|
||||||
|
bitmap.recycle(); // 回收原Bitmap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 优化:创建保存目录
|
||||||
|
File backgroundDir = new File(mBackgroundPictureUtils.getBackgroundDir());
|
||||||
|
if (!backgroundDir.exists()) {
|
||||||
|
if (!backgroundDir.mkdirs()) {
|
||||||
|
ToastUtils.show("无法创建保存目录");
|
||||||
|
if (scaledBitmap != bitmap) scaledBitmap.recycle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File saveFile = new File(backgroundDir, getBackgroundFileName());
|
||||||
|
|
||||||
|
// 优化:检查文件是否可写
|
||||||
|
if (saveFile.exists() && !saveFile.canWrite()) {
|
||||||
|
if (!saveFile.delete()) {
|
||||||
|
ToastUtils.show("无法删除旧文件");
|
||||||
|
if (scaledBitmap != bitmap) scaledBitmap.recycle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileOutputStream fos = null;
|
||||||
|
try {
|
||||||
|
fos = new FileOutputStream(saveFile);
|
||||||
|
boolean success = scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
|
||||||
|
fos.flush();
|
||||||
|
if (success) {
|
||||||
|
ToastUtils.show("保存成功");
|
||||||
|
// 更新数据
|
||||||
|
mBackgroundPictureUtils.getBackgroundPictureBean().setIsUseBackgroundFile(true);
|
||||||
|
updatePreviewBackground();
|
||||||
|
} else {
|
||||||
|
ToastUtils.show("图片压缩保存失败");
|
||||||
|
}
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
LogUtils.e(TAG, "文件未找到" + e);
|
||||||
|
ToastUtils.show("保存失败:文件路径错误");
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogUtils.e(TAG, "写入异常" + e);
|
||||||
|
ToastUtils.show("保存失败:磁盘可能已满或路径错误");
|
||||||
|
} finally {
|
||||||
|
if (fos != null) {
|
||||||
|
try {
|
||||||
|
fos.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogUtils.e(TAG, "流关闭异常" + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (scaledBitmap != null && !scaledBitmap.isRecycled()) {
|
||||||
|
scaledBitmap.recycle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缩放Bitmap
|
||||||
|
*/
|
||||||
|
private Bitmap scaleBitmap(Bitmap original, float scale) {
|
||||||
|
if (original == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int width = (int) (original.getWidth() * scale);
|
||||||
|
int height = (int) (original.getHeight() * scale);
|
||||||
|
return Bitmap.createScaledBitmap(original, width, height, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分享图片
|
||||||
|
*/
|
||||||
void sharePicture() {
|
void sharePicture() {
|
||||||
Uri uri = UriUtil.getUriForFile(this, mfRecivedPicture);
|
Uri uri = UriUtil.getUriForFile(this, mfRecivedPicture);
|
||||||
Intent shareIntent = new Intent();
|
Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
||||||
shareIntent.setAction(Intent.ACTION_SEND);
|
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
|
||||||
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
|
|
||||||
shareIntent.setType("image/" + _mszCommonFileType);
|
shareIntent.setType("image/" + _mszCommonFileType);
|
||||||
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
startActivity(Intent.createChooser(shareIntent, "Share Image"));
|
startActivity(Intent.createChooser(shareIntent, "Share Image"));
|
||||||
@@ -345,45 +473,121 @@ implements BackgroundPicturePreviewDialog.IOnRecivedPictureListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
if (requestCode == REQUEST_SELECT_PICTURE) {
|
if (requestCode == REQUEST_SELECT_PICTURE && resultCode == RESULT_OK) {
|
||||||
// 处理选择后图片
|
try {
|
||||||
if (resultCode == RESULT_OK) {
|
Uri selectedImage = data.getData();
|
||||||
try {
|
LogUtils.d(TAG, "Uri is : " + selectedImage.toString());
|
||||||
Uri selectedImage = data.getData();
|
File fSrcImage = new File(UriUtil.getFilePathFromUri(this, selectedImage));
|
||||||
LogUtils.d(TAG, "Uri is : " + selectedImage.toString());
|
mfRecivedPicture = getRecivedPictureFile(this);
|
||||||
File fSrcImage = new File(UriUtil.getFilePathFromUri(this, selectedImage));
|
if (FileUtils.copyFile(fSrcImage, mfRecivedPicture)) {
|
||||||
mfRecivedPicture = getRecivedPictureFile(this);
|
|
||||||
|
|
||||||
FileUtils.copyFile(fSrcImage, mfRecivedPicture);
|
|
||||||
// 启动剪裁文件窗口
|
|
||||||
startCropImageActivity(false);
|
startCropImageActivity(false);
|
||||||
} catch (Exception e) {
|
} else {
|
||||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
ToastUtils.show("图片复制失败,请重试");
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.e(TAG, "选择图片异常" + e);
|
||||||
|
ToastUtils.show("选择图片失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
} else if (requestCode == REQUEST_TAKE_PHOTO) {
|
} else if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
|
||||||
if (resultCode == RESULT_OK) {
|
LogUtils.d(TAG, "REQUEST_TAKE_PHOTO");
|
||||||
LogUtils.d(TAG, "REQUEST_TAKE_PHOTO");
|
Bundle extras = data.getExtras();
|
||||||
Bundle extras = data.getExtras();
|
if (extras != null) {
|
||||||
Bitmap imageBitmap = (Bitmap) extras.get("data");
|
Bitmap imageBitmap = (Bitmap) extras.get("data");
|
||||||
compressQualityToRecivedPicture(imageBitmap);
|
if (imageBitmap != null) {
|
||||||
startCropImageActivity(false);
|
compressQualityToRecivedPicture(imageBitmap);
|
||||||
}
|
startCropImageActivity(false);
|
||||||
} else if (requestCode == REQUEST_CROP_IMAGE) {
|
} else {
|
||||||
if (resultCode == RESULT_OK) {
|
ToastUtils.show("拍照图片为空");
|
||||||
LogUtils.d(TAG, "CROP_IMAGE_REQUEST_CODE");
|
}
|
||||||
FileUtils.copyFile(mfTempCropPicture, mfRecivedCropPicture);
|
} else {
|
||||||
mfTempCropPicture.delete();
|
ToastUtils.show("拍照数据获取失败");
|
||||||
mBackgroundPictureUtils.getBackgroundPictureBean().setIsUseBackgroundFile(true);
|
|
||||||
updatePreviewBackground();
|
|
||||||
}
|
}
|
||||||
|
} else if (requestCode == REQUEST_CROP_IMAGE && resultCode == RESULT_OK) {
|
||||||
|
LogUtils.d(TAG, "CROP_IMAGE_REQUEST_CODE");
|
||||||
|
try {
|
||||||
|
Bitmap cropBitmap = null;
|
||||||
|
// 方案1:通过Intent获取剪裁后的Bitmap
|
||||||
|
if (data != null && data.hasExtra("data")) {
|
||||||
|
cropBitmap = data.getParcelableExtra("data");
|
||||||
|
} else if (mfTempCropPicture.exists()) {
|
||||||
|
cropBitmap = BitmapFactory.decodeFile(mfTempCropPicture.getPath());
|
||||||
|
} else {
|
||||||
|
ToastUtils.show("剪裁文件不存在");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
if (cropBitmap != null) {
|
||||||
String sz = "Unsolved requestCode = " + Integer.toString(requestCode);
|
saveCropBitmap(cropBitmap);
|
||||||
Toast.makeText(getApplication(), sz, Toast.LENGTH_SHORT).show();
|
} else {
|
||||||
LogUtils.d(TAG, sz);
|
ToastUtils.show("获取剪裁图片失败");
|
||||||
|
}
|
||||||
|
} catch (OutOfMemoryError e) {
|
||||||
|
LogUtils.e(TAG, "内存溢出" + e);
|
||||||
|
ToastUtils.show("保存失败:内存不足,请尝试裁剪更小的图片");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.e(TAG, "剪裁保存异常" + e);
|
||||||
|
ToastUtils.show("保存失败:" + e.getMessage());
|
||||||
|
}/* finally {
|
||||||
|
// 安全删除临时文件
|
||||||
|
if (mfTempCropPicture.exists()) {
|
||||||
|
mfTempCropPicture.delete();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
} else if (resultCode != RESULT_OK) {
|
||||||
|
LogUtils.d(TAG, "操作取消或失败,requestCode: " + requestCode);
|
||||||
|
ToastUtils.show("操作已取消");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查类型是否为图片
|
||||||
|
*/
|
||||||
|
private boolean isImageType(String type) {
|
||||||
|
return type.startsWith("image/") || "image/jpeg".equals(type) ||
|
||||||
|
"image/jpg".equals(type) || "image/png".equals(type) ||
|
||||||
|
"image/webp".equals(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查并申请存储权限
|
||||||
|
*/
|
||||||
|
private boolean checkAndRequestStoragePermission() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
ActivityCompat.requestPermissions(this,
|
||||||
|
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||||
|
STORAGE_PERMISSION_REQUEST);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
if (requestCode == STORAGE_PERMISSION_REQUEST) {
|
||||||
|
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
ToastUtils.show("存储权限已获取");
|
||||||
|
} else {
|
||||||
|
ToastUtils.show("需要存储权限才能保存图片");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBackgroundColor() {
|
||||||
|
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(BackgroundPictureActivity.this);
|
||||||
|
BackgroundPictureBean bean = utils.getBackgroundPictureBean();
|
||||||
|
int nPixelColor = bean.getPixelColor();
|
||||||
|
RelativeLayout mainLayout = findViewById(R.id.activitybackgroundpictureRelativeLayout1);
|
||||||
|
mainLayout.setBackgroundColor(nPixelColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
setBackgroundColor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,231 @@
|
|||||||
|
package cc.winboll.studio.powerbell.activities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen<zhangsken@188.com>
|
||||||
|
* @Date 2025/06/22 14:15
|
||||||
|
*/
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import cc.winboll.studio.libaes.views.AToolbar;
|
||||||
|
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity;
|
||||||
|
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.utils.BackgroundPictureUtils;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
|
public class PixelPickerActivity extends WinBoLLActivity implements IWinBoLLActivity {
|
||||||
|
|
||||||
|
public static final String TAG = "PixelPickerActivity";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Activity getActivity() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AToolbar mAToolbar;
|
||||||
|
private ImageView imageView;
|
||||||
|
private Bitmap originalBitmap;
|
||||||
|
private TextView infoText;
|
||||||
|
private ViewGroup imageContainer;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_pixelpicker);
|
||||||
|
|
||||||
|
|
||||||
|
// 初始化工具栏
|
||||||
|
mAToolbar = (AToolbar) findViewById(R.id.toolbar);
|
||||||
|
setActionBar(mAToolbar);
|
||||||
|
mAToolbar.setSubtitle(R.string.subtitle_activity_pixelpicker);
|
||||||
|
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
mAToolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
imageView = findViewById(R.id.imageView);
|
||||||
|
infoText = findViewById(R.id.infoText);
|
||||||
|
imageContainer = findViewById(R.id.imageContainer);
|
||||||
|
|
||||||
|
// 从Intent获取图片路径并加载
|
||||||
|
String imagePath = getIntent().getStringExtra("imagePath");
|
||||||
|
if (imagePath != null) {
|
||||||
|
loadImage(imagePath);
|
||||||
|
} else {
|
||||||
|
infoText.setText("未找到图片路径");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置图片点击事件
|
||||||
|
imageContainer.setOnTouchListener(new View.OnTouchListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_DOWN && originalBitmap != null) {
|
||||||
|
// 计算点击位置在图片上的实际坐标
|
||||||
|
float touchX = event.getX();
|
||||||
|
float touchY = event.getY();
|
||||||
|
|
||||||
|
int pixelX = -1, pixelY = -1;
|
||||||
|
try {
|
||||||
|
// 获取图片在容器中的实际位置和尺寸
|
||||||
|
int[] imageLocation = new int[2];
|
||||||
|
imageView.getLocationInWindow(imageLocation);
|
||||||
|
int imageWidth = imageView.getWidth();
|
||||||
|
int imageHeight = imageView.getHeight();
|
||||||
|
|
||||||
|
// 计算缩放比例
|
||||||
|
float scaleX = (float) originalBitmap.getWidth() / imageWidth;
|
||||||
|
float scaleY = (float) originalBitmap.getHeight() / imageHeight;
|
||||||
|
|
||||||
|
// 调整触摸坐标到图片坐标系
|
||||||
|
float adjustedX = touchX - imageLocation[0];
|
||||||
|
float adjustedY = touchY - imageLocation[1];
|
||||||
|
|
||||||
|
// 检查是否在图片范围内
|
||||||
|
if (adjustedX >= 0 && adjustedX <= imageWidth && adjustedY >= 0 && adjustedY <= imageHeight) {
|
||||||
|
// 计算实际像素坐标
|
||||||
|
pixelX = (int) (adjustedX * scaleX);
|
||||||
|
pixelY = (int) (adjustedY * scaleY);
|
||||||
|
|
||||||
|
// 再次检查像素坐标是否在有效范围内
|
||||||
|
if (pixelX >= 0 && pixelX < originalBitmap.getWidth() &&
|
||||||
|
pixelY >= 0 && pixelY < originalBitmap.getHeight()) {
|
||||||
|
int pixelColor = originalBitmap.getPixel(pixelX, pixelY);
|
||||||
|
showPixelDialog(pixelColor, pixelX, pixelY);
|
||||||
|
} else {
|
||||||
|
Toast.makeText(PixelPickerActivity.this, "像素坐标超出范围", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(PixelPickerActivity.this, "点击位置超出图片显示范围", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Toast.makeText(PixelPickerActivity.this, "计算像素位置失败", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载图片
|
||||||
|
*/
|
||||||
|
private void loadImage(String imagePath) {
|
||||||
|
try {
|
||||||
|
File file = new File(imagePath);
|
||||||
|
if (file.exists()) {
|
||||||
|
// 解码图片
|
||||||
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||||
|
options.inSampleSize = 1; // 加载原图
|
||||||
|
originalBitmap = BitmapFactory.decodeStream(new FileInputStream(file), null, options);
|
||||||
|
|
||||||
|
if (originalBitmap != null) {
|
||||||
|
imageView.setImageBitmap(originalBitmap);
|
||||||
|
infoText.setText("图片已加载,点击获取像素值");
|
||||||
|
} else {
|
||||||
|
infoText.setText("图片加载失败");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
infoText.setText("图片文件不存在");
|
||||||
|
}
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
infoText.setText("图片文件未找到");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示像素对话框
|
||||||
|
*/
|
||||||
|
private void showPixelDialog(final int pixelColor, int x, int y) {
|
||||||
|
Dialog dialog = new Dialog(this);
|
||||||
|
dialog.setContentView(R.layout.dialog_pixel);
|
||||||
|
dialog.setCancelable(true);
|
||||||
|
|
||||||
|
// 设置像素颜色视图背景
|
||||||
|
TextView colorView = dialog.findViewById(R.id.pixelColorView);
|
||||||
|
colorView.setBackgroundColor(pixelColor);
|
||||||
|
|
||||||
|
// 显示颜色信息
|
||||||
|
TextView infoText = dialog.findViewById(R.id.colorInfoText);
|
||||||
|
String colorInfo = String.format(
|
||||||
|
"RGB: (%d, %d, %d)\n" +
|
||||||
|
"ARGB: #%08X\n" +
|
||||||
|
"实际像素位置: (%d, %d)",
|
||||||
|
Color.red(pixelColor),
|
||||||
|
Color.green(pixelColor),
|
||||||
|
Color.blue(pixelColor),
|
||||||
|
pixelColor,
|
||||||
|
x, y);
|
||||||
|
infoText.setText(colorInfo);
|
||||||
|
|
||||||
|
// 设置确定按钮点击事件
|
||||||
|
Button confirmButton = dialog.findViewById(R.id.confirmButton);
|
||||||
|
confirmButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
dialog.dismiss();
|
||||||
|
// 可以在这里添加确定后的回调逻辑
|
||||||
|
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(PixelPickerActivity.this);
|
||||||
|
BackgroundPictureBean bean = utils.getBackgroundPictureBean();
|
||||||
|
bean.setPixelColor(pixelColor);
|
||||||
|
utils.saveData();
|
||||||
|
Toast.makeText(PixelPickerActivity.this, "已记录像素值", Toast.LENGTH_SHORT).show();
|
||||||
|
setBackgroundColor();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
// 回收Bitmap资源
|
||||||
|
if (originalBitmap != null && !originalBitmap.isRecycled()) {
|
||||||
|
originalBitmap.recycle();
|
||||||
|
originalBitmap = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setBackgroundColor() {
|
||||||
|
BackgroundPictureUtils utils = BackgroundPictureUtils.getInstance(PixelPickerActivity.this);
|
||||||
|
BackgroundPictureBean bean = utils.getBackgroundPictureBean();
|
||||||
|
int nPixelColor = bean.getPixelColor();
|
||||||
|
RelativeLayout mainLayout = findViewById(R.id.activitypixelpickerRelativeLayout1);
|
||||||
|
mainLayout.setBackgroundColor(nPixelColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
setBackgroundColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package cc.winboll.studio.powerbell.activities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen<zhangsken@188.com>
|
||||||
|
* @Date 2025/06/19 20:35
|
||||||
|
* @Describe 应用窗口基类
|
||||||
|
*/
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||||
|
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity;
|
||||||
|
import cc.winboll.studio.powerbell.App;
|
||||||
|
import cc.winboll.studio.powerbell.MainActivity;
|
||||||
|
import cc.winboll.studio.powerbell.R;
|
||||||
|
|
||||||
|
public abstract class WinBoLLActivity extends Activity implements IWinBoLLActivity {
|
||||||
|
|
||||||
|
public static final String TAG = "WinBoLLActivity";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,8 @@ public class BackgroundPictureBean extends BaseBean {
|
|||||||
int backgroundWidth = 100;
|
int backgroundWidth = 100;
|
||||||
int backgroundHeight = 100;
|
int backgroundHeight = 100;
|
||||||
boolean isUseBackgroundFile = false;
|
boolean isUseBackgroundFile = false;
|
||||||
|
// 图片拾取像素颜色
|
||||||
|
int pixelColor = 0;
|
||||||
|
|
||||||
public BackgroundPictureBean() {
|
public BackgroundPictureBean() {
|
||||||
}
|
}
|
||||||
@@ -25,6 +27,14 @@ public class BackgroundPictureBean extends BaseBean {
|
|||||||
this.isUseBackgroundFile = isUseBackgroundFile;
|
this.isUseBackgroundFile = isUseBackgroundFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPixelColor(int pixelColor) {
|
||||||
|
this.pixelColor = pixelColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPixelColor() {
|
||||||
|
return pixelColor;
|
||||||
|
}
|
||||||
|
|
||||||
public void setBackgroundWidth(int backgroundWidth) {
|
public void setBackgroundWidth(int backgroundWidth) {
|
||||||
this.backgroundWidth = backgroundWidth;
|
this.backgroundWidth = backgroundWidth;
|
||||||
}
|
}
|
||||||
@@ -61,6 +71,7 @@ public class BackgroundPictureBean extends BaseBean {
|
|||||||
jsonWriter.name("backgroundWidth").value(bean.getBackgroundWidth());
|
jsonWriter.name("backgroundWidth").value(bean.getBackgroundWidth());
|
||||||
jsonWriter.name("backgroundHeight").value(bean.getBackgroundHeight());
|
jsonWriter.name("backgroundHeight").value(bean.getBackgroundHeight());
|
||||||
jsonWriter.name("isUseBackgroundFile").value(bean.isUseBackgroundFile());
|
jsonWriter.name("isUseBackgroundFile").value(bean.isUseBackgroundFile());
|
||||||
|
jsonWriter.name("pixelColor").value(bean.getPixelColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -75,6 +86,8 @@ public class BackgroundPictureBean extends BaseBean {
|
|||||||
bean.setBackgroundHeight(jsonReader.nextInt());
|
bean.setBackgroundHeight(jsonReader.nextInt());
|
||||||
} else if (name.equals("isUseBackgroundFile")) {
|
} else if (name.equals("isUseBackgroundFile")) {
|
||||||
bean.setIsUseBackgroundFile(jsonReader.nextBoolean());
|
bean.setIsUseBackgroundFile(jsonReader.nextBoolean());
|
||||||
|
} else if (name.equals("pixelColor")) {
|
||||||
|
bean.setPixelColor(jsonReader.nextInt());
|
||||||
} else {
|
} else {
|
||||||
jsonReader.skipValue();
|
jsonReader.skipValue();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -311,11 +311,11 @@ public class MainViewFragment extends Fragment {
|
|||||||
LogUtils.d(TAG, String.format("fBackgroundFilePath.exists() %s", fBackgroundFilePath.exists()));
|
LogUtils.d(TAG, String.format("fBackgroundFilePath.exists() %s", fBackgroundFilePath.exists()));
|
||||||
if (bean.isUseBackgroundFile() && fBackgroundFilePath.exists()) {
|
if (bean.isUseBackgroundFile() && fBackgroundFilePath.exists()) {
|
||||||
Drawable drawableBackground = Drawable.createFromPath(szBackgroundFilePath);
|
Drawable drawableBackground = Drawable.createFromPath(szBackgroundFilePath);
|
||||||
drawableBackground.setAlpha(120);
|
//drawableBackground.setAlpha(120);
|
||||||
imageView.setImageDrawable(drawableBackground);
|
imageView.setImageDrawable(drawableBackground);
|
||||||
} else {
|
} else {
|
||||||
Drawable drawableBackground = getActivity().getDrawable(R.drawable.blank10x10);
|
Drawable drawableBackground = getActivity().getDrawable(R.drawable.blank10x10);
|
||||||
drawableBackground.setAlpha(120);
|
//drawableBackground.setAlpha(120);
|
||||||
imageView.setImageDrawable(drawableBackground);
|
imageView.setImageDrawable(drawableBackground);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
@@ -12,83 +12,110 @@
|
|||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
style="@style/DefaultAToolbar"/>
|
style="@style/DefaultAToolbar"/>
|
||||||
|
|
||||||
<ImageView
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content">
|
||||||
android:id="@+id/activitybackgroundpictureImageView1"
|
|
||||||
android:layout_below="@id/toolbar">
|
|
||||||
|
|
||||||
</ImageView>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@id/toolbar">
|
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/activitybackgroundpictureRelativeLayout1"/>
|
||||||
|
|
||||||
<cc.winboll.studio.libaes.views.AButton
|
|
||||||
android:layout_width="160dp"
|
|
||||||
android:layout_height="36dp"
|
|
||||||
android:text="Origin BG"
|
|
||||||
android:id="@+id/activitybackgroundpictureAButton5"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_margin="5dp"/>
|
|
||||||
|
|
||||||
<cc.winboll.studio.libaes.views.AButton
|
<ImageView
|
||||||
android:layout_width="160dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="36dp"
|
android:layout_height="match_parent"
|
||||||
android:text="Received BG"
|
android:id="@+id/activitybackgroundpictureImageView1"
|
||||||
android:id="@+id/activitybackgroundpictureAButton4"
|
android:layout_below="@id/toolbar">
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_margin="5dp"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</ImageView>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="right">
|
android:layout_below="@id/toolbar">
|
||||||
|
|
||||||
<cc.winboll.studio.libaes.views.AButton
|
<RelativeLayout
|
||||||
android:layout_width="50dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="36dp"
|
android:layout_height="wrap_content">
|
||||||
android:text="◎"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_margin="10dp"
|
|
||||||
android:id="@+id/activitybackgroundpictureAButton1"/>
|
|
||||||
|
|
||||||
<cc.winboll.studio.libaes.views.AButton
|
<cc.winboll.studio.libaes.views.AButton
|
||||||
android:layout_width="50dp"
|
android:layout_width="160dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
android:text="☑"
|
android:text="Origin BG"
|
||||||
android:layout_gravity="center_vertical"
|
android:id="@+id/activitybackgroundpictureAButton5"
|
||||||
android:layout_margin="10dp"
|
android:layout_alignParentLeft="true"
|
||||||
android:id="@+id/activitybackgroundpictureAButton2"/>
|
android:layout_margin="5dp"/>
|
||||||
|
|
||||||
<cc.winboll.studio.libaes.views.AButton
|
<cc.winboll.studio.libaes.views.AButton
|
||||||
android:layout_width="50dp"
|
android:layout_width="160dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
android:text="[+]"
|
android:text="Received BG"
|
||||||
android:layout_gravity="center_vertical"
|
android:id="@+id/activitybackgroundpictureAButton4"
|
||||||
android:layout_margin="10dp"
|
android:layout_alignParentRight="true"
|
||||||
android:id="@+id/activitybackgroundpictureAButton3"/>
|
android:layout_margin="5dp"/>
|
||||||
|
|
||||||
<cc.winboll.studio.libaes.views.AButton
|
</RelativeLayout>
|
||||||
android:layout_width="50dp"
|
|
||||||
android:layout_height="36dp"
|
<LinearLayout
|
||||||
android:text="[+~]"
|
android:orientation="horizontal"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_width="match_parent"
|
||||||
android:layout_margin="10dp"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/activitybackgroundpictureAButton6"/>
|
android:gravity="right">
|
||||||
|
|
||||||
|
<cc.winboll.studio.libaes.views.AButton
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:text="◎"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
android:id="@+id/activitybackgroundpictureAButton1"/>
|
||||||
|
|
||||||
|
<cc.winboll.studio.libaes.views.AButton
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:text="☑"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
android:id="@+id/activitybackgroundpictureAButton2"/>
|
||||||
|
|
||||||
|
<cc.winboll.studio.libaes.views.AButton
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:text="[+]"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
android:id="@+id/activitybackgroundpictureAButton3"/>
|
||||||
|
|
||||||
|
<cc.winboll.studio.libaes.views.AButton
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:text="[+~]"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
android:id="@+id/activitybackgroundpictureAButton6"/>
|
||||||
|
|
||||||
|
<cc.winboll.studio.libaes.views.AButton
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:text="[◐]"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
android:id="@+id/activitybackgroundpictureAButton7"/>
|
||||||
|
|
||||||
|
<cc.winboll.studio.libaes.views.AButton
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:text="[○]"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
android:id="@+id/activitybackgroundpictureAButton8"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</RelativeLayout>
|
||||||
|
</LinearLayout>
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,42 +2,34 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<cc.winboll.studio.libaes.views.AToolbar
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="@dimen/toolbar_height"
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
style="@style/DefaultAToolbar"/>
|
||||||
|
|
||||||
<cc.winboll.studio.libaes.views.AToolbar
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/toolbar_height"
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
style="@style/DefaultAToolbar"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1.0">
|
android:layout_weight="1.0">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/activitymainRelativeLayout1"
|
||||||
|
android:background="#FFEE2121"/>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:id="@+id/activitymainFrameLayout1"/>
|
android:id="@+id/activitymainFrameLayout1"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<cc.winboll.studio.libappbase.LogView
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="200dp"
|
|
||||||
android:id="@+id/logview"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
54
powerbell/src/main/res/layout/activity_pixelpicker.xml
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?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:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<cc.winboll.studio.libaes.views.AToolbar
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/toolbar_height"
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
style="@style/DefaultAToolbar"/>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1.0">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFEE2121"
|
||||||
|
android:id="@+id/activitypixelpickerRelativeLayout1"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/imageContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:src="@drawable/ic_launcher"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/infoText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:background="#80000000"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:text="点击图片获取像素值"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
32
powerbell/src/main/res/layout/dialog_pixel.xml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="240dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pixelColorView"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:layout_gravity="center_horizontal" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/colorInfoText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:textColor="#333333"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/confirmButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="@android:color/holo_blue_light"
|
||||||
|
android:text="确定"
|
||||||
|
android:textColor="@android:color/white" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -43,15 +43,6 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Tips"
|
|
||||||
android:textSize="@dimen/text_content_size"
|
|
||||||
android:id="@+id/fragmentandroidviewTextView1"
|
|
||||||
android:background="@drawable/bg_frame"
|
|
||||||
android:padding="10dp"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@@ -205,6 +196,21 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="match_parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Tips"
|
||||||
|
android:textSize="@dimen/text_content_size"
|
||||||
|
android:id="@+id/fragmentandroidviewTextView1"
|
||||||
|
android:background="@drawable/bg_frame"
|
||||||
|
android:padding="10dp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/action_changepicture"
|
android:id="@+id/action_changepicture"
|
||||||
android:title="@string/item_changepicture"/>
|
android:title="@string/item_changepicture"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_log"
|
||||||
|
android:title="@string/item_logview"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_about"
|
android:id="@+id/action_about"
|
||||||
android:title="@string/item_aboutview"/>
|
android:title="@string/item_aboutview"/>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
<string name="texthint_CustomSlideToCleanRecord">Slide Right To Clean Up APP Record.</string>
|
<string name="texthint_CustomSlideToCleanRecord">Slide Right To Clean Up APP Record.</string>
|
||||||
<string name="subtitle_activity_clearrecord">清理记录</string>
|
<string name="subtitle_activity_clearrecord">清理记录</string>
|
||||||
<string name="subtitle_activity_backgroundpicture">更换背景图片</string>
|
<string name="subtitle_activity_backgroundpicture">更换背景图片</string>
|
||||||
|
<string name="subtitle_activity_pixelpicker">背景像素拾取</string>
|
||||||
<string name="subtitle_activity_about">关于应用</string>
|
<string name="subtitle_activity_about">关于应用</string>
|
||||||
<string name="msg_AOHPCTCSeekBar_ClearRecord">>>>Seek 100% To Clear Battery Record.>>></string>
|
<string name="msg_AOHPCTCSeekBar_ClearRecord">>>>Seek 100% To Clear Battery Record.>>></string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
<string name="texthint_CustomSlideToCleanRecord">Slide Right To Clean Up APP Record.</string>
|
<string name="texthint_CustomSlideToCleanRecord">Slide Right To Clean Up APP Record.</string>
|
||||||
<string name="subtitle_activity_clearrecord">Clean Record</string>
|
<string name="subtitle_activity_clearrecord">Clean Record</string>
|
||||||
<string name="subtitle_activity_backgroundpicture">Background Picture</string>
|
<string name="subtitle_activity_backgroundpicture">Background Picture</string>
|
||||||
|
<string name="subtitle_activity_pixelpicker">Pixel Picker</string>
|
||||||
<string name="subtitle_activity_about">About The APP</string>
|
<string name="subtitle_activity_about">About The APP</string>
|
||||||
<string name="msg_AOHPCTCSeekBar_ClearRecord">>>>Seek 100% To Clear Battery Record.>>></string>
|
<string name="msg_AOHPCTCSeekBar_ClearRecord">>>>Seek 100% To Clear Battery Record.>>></string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -52,3 +52,7 @@
|
|||||||
// Ollama 项目编译设置
|
// Ollama 项目编译设置
|
||||||
//include ':ollama'
|
//include ':ollama'
|
||||||
//rootProject.name = "ollama"
|
//rootProject.name = "ollama"
|
||||||
|
|
||||||
|
// NumTable 项目编译设置
|
||||||
|
//include ':numtable'
|
||||||
|
//rootProject.name = "numtable"
|
||||||
|
|||||||