Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d0f6ccac9b | |||
| efbb2f6681 | |||
| 3b900eafe5 | |||
| 4d6006dbf9 | |||
| c0fbfcaa1b | |||
| 4e2e03d0fb | |||
| c2f96568a7 | |||
| 4cfece1a50 | |||
| f481a4807f | |||
| 7b532adb2c | |||
| 2fa62394ef | |||
| aecca3fc88 | |||
| 204e2c6f0f | |||
| ab03d3166d | |||
| 1045e01a55 | |||
| c01be3f909 | |||
| 7ff4bf64f7 | |||
| c3b50a23f6 | |||
| 2878e69c22 | |||
| 44d04eaa77 | |||
| 99de32cf57 | |||
| 80c22ecb6d | |||
| cf79d84d00 | |||
| 9a0a44fdde |
1
winboll/app_update_description.txt
Normal file
1
winboll/app_update_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -18,34 +18,35 @@ def genVersionName(def versionName){
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 32
|
||||
buildToolsVersion "32.0.0"
|
||||
|
||||
// 1. compileSdkVersion:必须 ≥ targetSdkVersion,建议直接等于 targetSdkVersion(30)
|
||||
compileSdkVersion 30
|
||||
|
||||
// 2. buildToolsVersion:需匹配 compileSdkVersion,建议使用 30.x.x 最新稳定版(无需高于 compileSdkVersion)
|
||||
buildToolsVersion "30.0.3" // 这是 30 对应的最新稳定版,避免使用 beta 版
|
||||
|
||||
defaultConfig {
|
||||
applicationId "cc.winboll.studio.winboll"
|
||||
minSdkVersion 24
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
// versionName 更新后需要手动设置
|
||||
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
|
||||
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
||||
versionName "15.0"
|
||||
versionName "15.11"
|
||||
if(true) {
|
||||
versionName = genVersionName("${versionName}")
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
// 米盟 SDK
|
||||
packagingOptions {
|
||||
doNotStrip "*/*/libmimo_1011.so"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
|
||||
api 'com.google.code.gson:gson:2.10.1'
|
||||
|
||||
// 下拉控件
|
||||
@@ -60,19 +61,28 @@ dependencies {
|
||||
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 类库
|
||||
|
||||
// AndroidX 类库
|
||||
api 'androidx.appcompat:appcompat:1.1.0'
|
||||
api 'com.google.android.material:material:1.4.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.10.2'
|
||||
api 'cc.winboll.studio:libapputils:15.10.2'
|
||||
api 'cc.winboll.studio:libappbase:15.10.9'
|
||||
|
||||
// 米盟
|
||||
api 'com.miui.zeus:mimo-ad-sdk:5.3.+'//请使用最新版sdk
|
||||
//注意:以下5个库必须要引入
|
||||
//implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
api 'androidx.recyclerview:recyclerview:1.0.0'
|
||||
api 'com.google.code.gson:gson:2.8.5'
|
||||
api 'com.github.bumptech.glide:glide:4.9.0'
|
||||
//annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
|
||||
|
||||
api 'cc.winboll.studio:libaes:15.11.8'
|
||||
api 'cc.winboll.studio:libappbase:15.11.6'
|
||||
|
||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#Created by .winboll/winboll_app_build.gradle
|
||||
#Thu Nov 27 01:06:01 GMT 2025
|
||||
stageCount=3
|
||||
#Thu Dec 04 21:06:15 HKT 2025
|
||||
stageCount=6
|
||||
libraryProject=
|
||||
baseVersion=15.0
|
||||
publishVersion=15.0.2
|
||||
buildCount=15
|
||||
baseBetaVersion=15.0.3
|
||||
baseVersion=15.11
|
||||
publishVersion=15.11.5
|
||||
buildCount=0
|
||||
baseBetaVersion=15.11.6
|
||||
|
||||
158
winboll/proguard-rules.pro
vendored
158
winboll/proguard-rules.pro
vendored
@@ -1,21 +1,137 @@
|
||||
# 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
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in C:\tools\adt-bundle-windows-x86_64-20131030\sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# ============================== 基础通用规则 ==============================
|
||||
# 保留系统组件
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||
-keep public class * extends android.preference.Preference
|
||||
|
||||
# 保留 WinBoLL 核心包及子类(合并简化规则)
|
||||
-keep class cc.winboll.studio.** { *; }
|
||||
-keepclassmembers class cc.winboll.studio.** { *; }
|
||||
|
||||
# 保留所有类中的 public static final String TAG 字段(便于日志定位)
|
||||
-keepclassmembers class * {
|
||||
public static final java.lang.String TAG;
|
||||
}
|
||||
|
||||
# 保留序列化类(避免Parcelable/Gson解析异常)
|
||||
-keep class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
||||
-keepclassmembers class * implements java.io.Serializable {
|
||||
static final long serialVersionUID;
|
||||
private static final java.io.ObjectStreamField[] serialPersistentFields;
|
||||
private void writeObject(java.io.ObjectOutputStream);
|
||||
private void readObject(java.io.ObjectInputStream);
|
||||
java.lang.Object writeReplace();
|
||||
java.lang.Object readResolve();
|
||||
}
|
||||
|
||||
# 保留 R 文件(避免资源ID混淆)
|
||||
-keepclassmembers class **.R$* {
|
||||
public static <fields>;
|
||||
}
|
||||
|
||||
# 保留 native 方法(避免JNI调用失败)
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
# 保留注解和泛型(避免反射/序列化异常)
|
||||
-keepattributes *Annotation*
|
||||
-keepattributes Signature
|
||||
|
||||
# 屏蔽 Java 8+ 警告(适配 Java 7 语法)
|
||||
-dontwarn java.lang.invoke.*
|
||||
-dontwarn android.support.v8.renderscript.*
|
||||
-dontwarn java.util.function.**
|
||||
|
||||
# ============================== 第三方框架专项规则 ==============================
|
||||
# OkHttp 4.4.1(米盟广告请求依赖,完善Lambda兼容)
|
||||
-keep class okhttp3.** { *; }
|
||||
-keep interface okhttp3.** { *; }
|
||||
-keep class okhttp3.internal.** { *; }
|
||||
-keep class okio.** { *; }
|
||||
-dontwarn okhttp3.internal.platform.**
|
||||
-dontwarn okio.**
|
||||
|
||||
# Glide 4.9.0(米盟广告图片加载依赖)
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
-keep public class * extends com.bumptech.glide.module.AppGlideModule
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$ImageType {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
-keepclassmembers class * implements com.bumptech.glide.module.AppGlideModule {
|
||||
<init>();
|
||||
}
|
||||
-dontwarn com.bumptech.glide.**
|
||||
|
||||
# Gson 2.8.5(米盟广告数据序列化依赖)
|
||||
-keep class com.google.gson.** { *; }
|
||||
-keep interface com.google.gson.** { *; }
|
||||
-keepclassmembers class * {
|
||||
@com.google.gson.annotations.SerializedName <fields>;
|
||||
}
|
||||
|
||||
# 米盟 SDK(核心广告组件,完整保留避免加载失败)
|
||||
-keep class com.miui.zeus.** { *; }
|
||||
-keep interface com.miui.zeus.** { *; }
|
||||
# 保留米盟日志字段(便于广告加载失败排查)
|
||||
-keepclassmembers class com.miui.zeus.mimo.sdk.** {
|
||||
public static final java.lang.String TAG;
|
||||
}
|
||||
|
||||
# RecyclerView 1.0.0(米盟广告布局渲染依赖)
|
||||
-keep class androidx.recyclerview.** { *; }
|
||||
-keep interface androidx.recyclerview.** { *; }
|
||||
-keepclassmembers class androidx.recyclerview.widget.RecyclerView$Adapter {
|
||||
public *;
|
||||
}
|
||||
|
||||
# 其他第三方框架(按引入依赖保留,无则可删除)
|
||||
# XXPermissions 18.63
|
||||
-keep class com.hjq.permissions.** { *; }
|
||||
-keep interface com.hjq.permissions.** { *; }
|
||||
|
||||
# ZXing 二维码(核心解析组件)
|
||||
-keep class com.google.zxing.** { *; }
|
||||
-keep class com.journeyapps.zxing.** { *; }
|
||||
|
||||
# Jsoup HTML解析
|
||||
-keep class org.jsoup.** { *; }
|
||||
|
||||
# Pinyin4j 拼音搜索
|
||||
-keep class net.sourceforge.pinyin4j.** { *; }
|
||||
|
||||
# JSch SSH组件
|
||||
-keep class com.jcraft.jsch.** { *; }
|
||||
|
||||
# AndroidX 基础组件
|
||||
-keep class androidx.appcompat.** { *; }
|
||||
-keep interface androidx.appcompat.** { *; }
|
||||
|
||||
# ============================== 优化与调试配置 ==============================
|
||||
# 优化级别(平衡混淆效果与性能)
|
||||
-optimizationpasses 5
|
||||
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
|
||||
|
||||
# 调试辅助(保留行号便于崩溃定位)
|
||||
-verbose
|
||||
-dontpreverify
|
||||
-dontusemixedcaseclassnames
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/MyAppTheme"
|
||||
android:resizeableActivity="true"
|
||||
android:name=".App">
|
||||
android:name=".App"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
@@ -57,7 +59,7 @@
|
||||
android:targetActivity=".MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name_cn1"
|
||||
android:icon="@drawable/ic_launcher_stage"
|
||||
android:icon="@drawable/ic_winboll_jindouyun1"
|
||||
android:enabled="false">
|
||||
|
||||
<intent-filter>
|
||||
@@ -79,7 +81,7 @@
|
||||
android:targetActivity=".MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name_cn2"
|
||||
android:icon="@drawable/ic_launcher_stage"
|
||||
android:icon="@drawable/ic_winboll_jindouyun2"
|
||||
android:enabled="false">
|
||||
|
||||
<intent-filter>
|
||||
|
||||
@@ -22,10 +22,8 @@ import android.widget.HorizontalScrollView;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||
import com.hjq.toast.ToastUtils;
|
||||
import com.hjq.toast.style.WhiteToastStyle;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
@@ -59,20 +57,29 @@ public class App extends GlobalApplication {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
setIsDebugging(BuildConfig.DEBUG);
|
||||
|
||||
WinBoLLActivityManager.init(this);
|
||||
//WinBoLLActivityManager.init(this);
|
||||
|
||||
// 初始化 Toast 框架
|
||||
ToastUtils.init(this);
|
||||
// 设置 Toast 布局样式
|
||||
//ToastUtils.setView(R.layout.view_toast);
|
||||
ToastUtils.setStyle(new WhiteToastStyle());
|
||||
ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
|
||||
//ToastUtils.setStyle(new WhiteToastStyle());
|
||||
//ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
|
||||
|
||||
//CrashHandler.getInstance().registerGlobal(this);
|
||||
//CrashHandler.getInstance().registerPart(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTerminate() {
|
||||
super.onTerminate();
|
||||
ToastUtils.release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void write(InputStream input, OutputStream output) throws IOException {
|
||||
byte[] buf = new byte[1024 * 8];
|
||||
int len;
|
||||
|
||||
@@ -12,7 +12,8 @@ import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.IBinder;
|
||||
import cc.winboll.studio.libaes.models.WinBoLLClientServiceBean;
|
||||
import cc.winboll.studio.libapputils.utils.ServiceUtils;
|
||||
import cc.winboll.studio.winboll.WinBoLLClientService;
|
||||
import cc.winboll.studio.winboll.utils.ServiceUtils;
|
||||
|
||||
public class AssistantService extends Service {
|
||||
|
||||
|
||||
@@ -1,39 +1,31 @@
|
||||
package cc.winboll.studio.winboll;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.Toast;
|
||||
import cc.winboll.studio.libaes.activitys.DrawerFragmentActivity;
|
||||
import cc.winboll.studio.libaes.dialogs.LocalFileSelectDialog;
|
||||
import cc.winboll.studio.libaes.dialogs.StoragePathDialog;
|
||||
import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
|
||||
import cc.winboll.studio.libaes.models.DrawerMenuBean;
|
||||
import cc.winboll.studio.libaes.unittests.SecondaryLibraryActivity;
|
||||
import cc.winboll.studio.libaes.unittests.TestAButtonFragment;
|
||||
import cc.winboll.studio.libaes.unittests.TestASupportToolbarActivity;
|
||||
import cc.winboll.studio.libaes.unittests.TestAToolbarActivity;
|
||||
import cc.winboll.studio.libaes.unittests.TestDrawerFragmentActivity;
|
||||
import cc.winboll.studio.libaes.unittests.TestViewPageFragment;
|
||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.winboll.R;
|
||||
import cc.winboll.studio.winboll.fragments.MainFragment;
|
||||
import com.a4455jkjh.colorpicker.ColorPickerDialog;
|
||||
import java.util.ArrayList;
|
||||
import cc.winboll.studio.winboll.activities.AboutActivity;
|
||||
import cc.winboll.studio.winboll.fragments.MainFragment;
|
||||
import java.util.ArrayList;
|
||||
import cc.winboll.studio.winboll.fragments.BrowserFragment;
|
||||
|
||||
public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActivity {
|
||||
|
||||
|
||||
public static final String TAG = "MainActivity";
|
||||
|
||||
MainFragment mMainFragment;
|
||||
|
||||
BrowserFragment mBrowserFragment;
|
||||
|
||||
@Override
|
||||
public Activity getActivity() {
|
||||
return null;
|
||||
@@ -47,11 +39,11 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActi
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (mMainFragment == null) {
|
||||
mMainFragment = new MainFragment();
|
||||
addFragment(mMainFragment);
|
||||
if (mBrowserFragment == null) {
|
||||
mBrowserFragment = new BrowserFragment();
|
||||
addFragment(mBrowserFragment);
|
||||
}
|
||||
showFragment(mMainFragment);
|
||||
showFragment(mBrowserFragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,9 +76,9 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActi
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.toolbar_main, menu);
|
||||
if(App.isDebuging()) {
|
||||
getMenuInflater().inflate(cc.winboll.studio.libapputils.R.menu.toolbar_studio_debug, menu);
|
||||
}
|
||||
// if (App.isDebugging()) {
|
||||
// getMenuInflater().inflate(cc.winboll.studio.libapputils.R.menu.toolbar_studio_debug, menu);
|
||||
// }
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@@ -95,11 +87,11 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActi
|
||||
super.onItemClick(parent, view, position, id);
|
||||
switch (position) {
|
||||
case 0 : {
|
||||
if (mMainFragment == null) {
|
||||
mMainFragment = new MainFragment();
|
||||
addFragment(mMainFragment);
|
||||
if (mBrowserFragment == null) {
|
||||
mBrowserFragment = new BrowserFragment();
|
||||
addFragment(mBrowserFragment);
|
||||
}
|
||||
showFragment(mMainFragment);
|
||||
showFragment(mBrowserFragment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -117,6 +109,6 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActi
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,14 @@ package cc.winboll.studio.winboll.activities;
|
||||
* @Date 2025/09/29 13:30
|
||||
* @Describe 应用介绍窗口
|
||||
*/
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import cc.winboll.studio.winboll.BuildConfig;
|
||||
import cc.winboll.studio.winboll.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
@@ -16,8 +24,6 @@ import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
|
||||
import cc.winboll.studio.libaes.models.APPInfo;
|
||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||
import cc.winboll.studio.libaes.views.AboutView;
|
||||
import cc.winboll.studio.winboll.R;
|
||||
import cc.winboll.studio.libaes.BuildConfig;
|
||||
|
||||
public class AboutActivity extends WinBoLLActivity implements IWinBoLLActivity {
|
||||
|
||||
@@ -75,6 +81,8 @@ public class AboutActivity extends WinBoLLActivity implements IWinBoLLActivity {
|
||||
WinBoLLActivityManager.getInstance().registeRemove(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public AboutView CreateAboutView() {
|
||||
String szBranchName = "winboll";
|
||||
APPInfo appInfo = new APPInfo();
|
||||
@@ -89,7 +97,7 @@ public class AboutActivity extends WinBoLLActivity implements IWinBoLLActivity {
|
||||
appInfo.setAppAPKName("WinBoLL");
|
||||
appInfo.setAppAPKFolderName("WinBoLL");
|
||||
//appInfo.setIsAddDebugTools(false);
|
||||
appInfo.setIsAddDebugTools(BuildConfig.DEBUG);
|
||||
//appInfo.setIsAddDebugTools(BuildConfig.DEBUG);
|
||||
return new AboutView(mContext, appInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,27 +11,15 @@ import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Toolbar;
|
||||
import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
|
||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||
import cc.winboll.studio.winboll.R;
|
||||
|
||||
public class New2Activity extends WinBoLLActivity implements IWinBoLLActivity {
|
||||
public class New2Activity extends WinBoLLActivity {
|
||||
|
||||
public static final String TAG = "New2Activity";
|
||||
|
||||
Toolbar mToolbar;
|
||||
//LogView mLogView;
|
||||
|
||||
@Override
|
||||
public Activity getActivity() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -51,15 +39,15 @@ public class New2Activity extends WinBoLLActivity implements IWinBoLLActivity {
|
||||
}
|
||||
|
||||
public void onCloseThisActivity(View view) {
|
||||
WinBoLLActivityManager.getInstance().finish(this);
|
||||
//WinBoLLActivityManager.getInstance().finish(this);
|
||||
}
|
||||
|
||||
public void onCloseAllActivity(View view) {
|
||||
WinBoLLActivityManager.getInstance().finishAll();
|
||||
//WinBoLLActivityManager.getInstance().finishAll();
|
||||
}
|
||||
|
||||
public void onNewActivity(View view) {
|
||||
WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, NewActivity.class);
|
||||
//WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, NewActivity.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import android.widget.Toolbar;
|
||||
import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
|
||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||
import cc.winboll.studio.winboll.R;
|
||||
import cc.winboll.studio.winboll.App;
|
||||
|
||||
public class NewActivity extends WinBoLLActivity implements IWinBoLLActivity {
|
||||
|
||||
@@ -58,7 +59,7 @@ public class NewActivity extends WinBoLLActivity implements IWinBoLLActivity {
|
||||
}
|
||||
|
||||
public void onNew2Activity(View view) {
|
||||
WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, New2Activity.class);
|
||||
// WinBoLLActivityManager.getInstance().startWinBoLLActivity(App.getInstance(), New2Activity.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ public class ShortcutActionActivity extends Activity {
|
||||
* 处理应用图标快捷菜单的请求
|
||||
*/
|
||||
private void handleSwitchRequest() {
|
||||
//ToastUtils.show("handleSwitchRequest");
|
||||
Intent intent = getIntent();
|
||||
if (intent != null && "switchto_en1".equals(intent.getDataString())) {
|
||||
APPPlusUtils.switchAppLauncherToComponent(this, App.COMPONENT_EN1);
|
||||
|
||||
@@ -9,28 +9,15 @@ import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
|
||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
|
||||
public class WinBoLLActivity extends AppCompatActivity implements IWinBoLLActivity {
|
||||
public class WinBoLLActivity extends AppCompatActivity {
|
||||
|
||||
public static final String TAG = "WinBoLLActivity";
|
||||
|
||||
@Override
|
||||
public Activity getActivity() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
LogUtils.d(TAG, String.format("onResume %s", getTag()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,12 +36,12 @@ public class WinBoLLActivity extends AppCompatActivity implements IWinBoLLActivi
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
WinBoLLActivityManager.getInstance().add(this);
|
||||
//WinBoLLActivityManager.getInstance().add(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
WinBoLLActivityManager.getInstance().registeRemove(this);
|
||||
//WinBoLLActivityManager.getInstance().registeRemove(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class WinBoLLUnitTestActivity extends AppCompatActivity {
|
||||
setSupportActionBar(mToolbar);
|
||||
|
||||
CheckBox cbIsDebugMode = findViewById(R.id.activitymainCheckBox1);
|
||||
cbIsDebugMode.setChecked(GlobalApplication.isDebuging());
|
||||
cbIsDebugMode.setChecked(GlobalApplication.isDebugging());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,11 +51,11 @@ public class WinBoLLUnitTestActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if(item.getItemId() == R.id.item_yun) {
|
||||
WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, cc.winboll.studio.winboll.activities.YunActivity.class);
|
||||
} else if(item.getItemId() == R.id.item_logon) {
|
||||
WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, cc.winboll.studio.winboll.activities.LogonActivity.class);
|
||||
}
|
||||
// if(item.getItemId() == R.id.item_yun) {
|
||||
// WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, cc.winboll.studio.winboll.activities.YunActivity.class);
|
||||
// } else if(item.getItemId() == R.id.item_logon) {
|
||||
// WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, cc.winboll.studio.winboll.activities.LogonActivity.class);
|
||||
// }
|
||||
// 在switch语句中处理每个ID,并在处理完后返回true,未处理的情况返回false。
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
@@ -70,13 +70,13 @@ public class WinBoLLUnitTestActivity extends AppCompatActivity {
|
||||
|
||||
public void onSwitchDebugMode(View view) {
|
||||
boolean isDebuging = ((CheckBox)view).isChecked();
|
||||
GlobalApplication.setIsDebuging(isDebuging);
|
||||
GlobalApplication.saveDebugStatus(this);
|
||||
GlobalApplication.setIsDebugging(isDebuging);
|
||||
GlobalApplication.saveDebugStatus((App.getInstance()));
|
||||
}
|
||||
|
||||
public void onPreviewGlobalCrashActivity(View view) {
|
||||
Intent intent = new Intent(this, GlobalCrashActivity.class);
|
||||
intent.putExtra(CrashHandler.EXTRA_CRASH_INFO, "Demo log...");
|
||||
intent.putExtra(CrashHandler.EXTRA_CRASH_LOG, "Demo log...");
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public class WinBoLLUnitTestActivity extends AppCompatActivity {
|
||||
public void onTestDemoServiceSOS(View view) {
|
||||
Intent intent = new Intent(this, TestDemoService.class);
|
||||
stopService(intent);
|
||||
if (App.isDebuging()) {
|
||||
if (App.isDebugging()) {
|
||||
SOS.sosToAppBaseBeta(this, TestDemoService.class.getName());
|
||||
} else {
|
||||
SOS.sosToAppBase(this, TestDemoService.class.getName());
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
package cc.winboll.studio.winboll.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import cc.winboll.studio.winboll.R;
|
||||
import cc.winboll.studio.winboll.views.WinBoLLView;
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Date 2025/11/27 11:09
|
||||
* @Describe 浏览器Fragment(Java 7 语法完整版)
|
||||
* 适配Java 7特性,移除Lambda/方法引用,兼容低版本Android系统
|
||||
*/
|
||||
public class BrowserFragment extends Fragment implements View.OnClickListener, WinBoLLView.OnPageStatusListener {
|
||||
|
||||
// 控件声明(Java 7 成员变量显式声明)
|
||||
private EditText mEtUrl;
|
||||
private Button mBtnLoad;
|
||||
private Button mBtnRefresh;
|
||||
private Button mBtnStop;
|
||||
private Button mBtnForward;
|
||||
private Button mBtnBack;
|
||||
private ProgressBar mProgressBar;
|
||||
private WinBoLLView mWinBoLLView;
|
||||
|
||||
// 单例创建方法(Java 7 静态工厂模式)
|
||||
public static BrowserFragment newInstance() {
|
||||
return new BrowserFragment();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
// 加载布局(Java 7 显式强转,无菱形语法)
|
||||
View view = inflater.inflate(R.layout.fragment_browser, container, false);
|
||||
// 初始化控件
|
||||
initViews(view);
|
||||
// 绑定事件
|
||||
initEvents();
|
||||
// 初始化WinBoLLView
|
||||
initWinBoLLView();
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件(Java 7 显式绑定,无Stream简化)
|
||||
*/
|
||||
private void initViews(View view) {
|
||||
mEtUrl = (EditText) view.findViewById(R.id.et_url);
|
||||
mBtnLoad = (Button) view.findViewById(R.id.btn_load);
|
||||
mBtnRefresh = (Button) view.findViewById(R.id.btn_refresh);
|
||||
mBtnStop = (Button) view.findViewById(R.id.btn_stop);
|
||||
mBtnForward = (Button) view.findViewById(R.id.btn_forward);
|
||||
mBtnBack = (Button) view.findViewById(R.id.btn_back);
|
||||
mProgressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
|
||||
mWinBoLLView = (WinBoLLView) view.findViewById(R.id.winboll_webview);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定点击事件(Java 7 匿名内部类,无Lambda)
|
||||
*/
|
||||
private void initEvents() {
|
||||
// 功能按钮点击事件
|
||||
mBtnLoad.setOnClickListener(this);
|
||||
mBtnRefresh.setOnClickListener(this);
|
||||
mBtnStop.setOnClickListener(this);
|
||||
mBtnForward.setOnClickListener(this);
|
||||
mBtnBack.setOnClickListener(this);
|
||||
|
||||
// 输入框软键盘“前往”按钮事件(Java 7 匿名内部类实现)
|
||||
mEtUrl.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, android.view.KeyEvent event) {
|
||||
// 处理软键盘“前往”点击
|
||||
loadUrlFromInput();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化WinBoLLView(Java 7 显式调用,无方法引用)
|
||||
*/
|
||||
private void initWinBoLLView() {
|
||||
// 绑定进度条
|
||||
mWinBoLLView.setProgressBar(mProgressBar);
|
||||
// 设置页面状态监听(this 实现 OnPageStatusListener)
|
||||
mWinBoLLView.setOnPageStatusListener(this);
|
||||
// 预加载默认页面(兼容Java 7 字符串拼接)
|
||||
//String defaultUrl = "https://www.baidu.com";
|
||||
String defaultUrl = "https://www.winboll.cc";
|
||||
mWinBoLLView.loadUrlSafe(defaultUrl);
|
||||
mEtUrl.setText(defaultUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击事件处理(Java 7 switch-case 语句,无增强switch)
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int id = v.getId();
|
||||
if (id == R.id.btn_load) {
|
||||
// 加载输入框中的URL
|
||||
loadUrlFromInput();
|
||||
} else if (id == R.id.btn_refresh) {
|
||||
// 刷新当前页面
|
||||
mWinBoLLView.refreshPage();
|
||||
} else if (id == R.id.btn_stop) {
|
||||
// 停止页面加载
|
||||
mWinBoLLView.stopPageLoad();
|
||||
} else if (id == R.id.btn_forward) {
|
||||
// 前进(无历史则提示)
|
||||
if (!mWinBoLLView.goForwardSafe()) {
|
||||
showToast("无前进历史");
|
||||
}
|
||||
} else if (id == R.id.btn_back) {
|
||||
// 后退(无历史则提示)
|
||||
if (!mWinBoLLView.goBackSafe()) {
|
||||
showToast("无后退历史");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从输入框获取URL并加载(Java 7 显式空值校验)
|
||||
*/
|
||||
private void loadUrlFromInput() {
|
||||
// 空值校验(Java 7 显式判断,无Objects.requireNonNull)
|
||||
if (mEtUrl == null) {
|
||||
showToast("控件初始化失败");
|
||||
return;
|
||||
}
|
||||
String url = mEtUrl.getText().toString().trim();
|
||||
// 调用WinBoLLView安全加载方法
|
||||
mWinBoLLView.loadUrlSafe(url);
|
||||
// 隐藏软键盘
|
||||
hideSoftKeyboard();
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏软键盘(Java 7 显式获取系统服务,无Lambda简化)
|
||||
*/
|
||||
private void hideSoftKeyboard() {
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
// 获取InputMethodManager(Java 7 显式强转)
|
||||
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(android.content.Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null && getActivity().getCurrentFocus() != null) {
|
||||
imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示Toast提示(Java 7 简化封装,避免重复代码)
|
||||
*/
|
||||
private void showToast(String msg) {
|
||||
if (getActivity() == null || msg == null) {
|
||||
return;
|
||||
}
|
||||
// Java 7 显式创建Toast,无Toast.makeText简化链式调用
|
||||
Toast toast = Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT);
|
||||
toast.show();
|
||||
}
|
||||
|
||||
// ------------------- WinBoLLView.OnPageStatusListener 实现(Java 7 显式重写) -------------------
|
||||
@Override
|
||||
public void onPageStarted(String url) {
|
||||
// 页面开始加载:更新输入框URL(Java 7 显式非空判断)
|
||||
if (mEtUrl != null && url != null) {
|
||||
mEtUrl.setText(url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageFinished(String url) {
|
||||
// 页面加载完成:更新输入框URL
|
||||
if (mEtUrl != null && url != null) {
|
||||
mEtUrl.setText(url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageError(String errorMsg) {
|
||||
// 页面加载错误:显示错误提示
|
||||
showToast("加载失败:" + errorMsg);
|
||||
}
|
||||
|
||||
// ------------------- 生命周期管理(防止内存泄漏,Java 7 显式重写) -------------------
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
// 销毁WinBoLLView(释放资源,避免内存泄漏)
|
||||
if (mWinBoLLView != null) {
|
||||
mWinBoLLView.destroyWebView();
|
||||
mWinBoLLView = null;
|
||||
}
|
||||
// 置空控件(帮助GC回收)
|
||||
mEtUrl = null;
|
||||
mBtnLoad = null;
|
||||
mBtnRefresh = null;
|
||||
mBtnStop = null;
|
||||
mBtnForward = null;
|
||||
mBtnBack = null;
|
||||
mProgressBar = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
// 彻底释放资源
|
||||
if (mWinBoLLView != null) {
|
||||
mWinBoLLView.destroyWebView();
|
||||
mWinBoLLView = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,10 @@ import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import cc.winboll.studio.winboll.R;
|
||||
import cc.winboll.studio.libaes.views.AButton;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import android.widget.Switch;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import cc.winboll.studio.winboll.R;
|
||||
|
||||
|
||||
public class MainFragment extends Fragment {
|
||||
|
||||
@@ -13,7 +13,6 @@ import android.content.IntentFilter;
|
||||
import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import cc.winboll.studio.libapputils.utils.AppUtils;
|
||||
import cc.winboll.studio.winboll.WinBoLL;
|
||||
import cc.winboll.studio.winboll.models.WinBoLLModel;
|
||||
import cc.winboll.studio.winboll.models.WinBoLLNewsBean;
|
||||
@@ -65,41 +64,41 @@ public class MainReceiver extends BroadcastReceiver {
|
||||
}
|
||||
} else if (intent.getAction().equals(SOS.ACTION_SOS)) {
|
||||
LogUtils.d(TAG, "ACTION_SOS");
|
||||
String sos = intent.getStringExtra(SOS.EXTRA_OBJECT);
|
||||
LogUtils.d(TAG, String.format("SOS %s", sos));
|
||||
if (sos != null && !sos.equals("")) {
|
||||
SOSObject bean = SOS.parseSOSObject(sos);
|
||||
if (bean != null) {
|
||||
String szObjectPackageName = bean.getObjectPackageName();
|
||||
LogUtils.d(TAG, String.format("szObjectPackageName %s", szObjectPackageName));
|
||||
String szObjectServiveName = bean.getObjectServiveName();
|
||||
LogUtils.d(TAG, String.format("szObjectServiveName %s", szObjectServiveName));
|
||||
|
||||
Intent intentService = new Intent();
|
||||
intentService.setComponent(new ComponentName(szObjectPackageName, szObjectServiveName));
|
||||
context.startService(intentService);
|
||||
|
||||
String appName = AppUtils.getAppNameByPackageName(context, szObjectPackageName);
|
||||
LogUtils.d(TAG, String.format("appName %s", appName));
|
||||
WinBoLLNewsBean appWinBoLLNewsBean = new WinBoLLNewsBean(appName);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
|
||||
String currentTime = sdf.format(new Date());
|
||||
StringBuilder sbLine = new StringBuilder();
|
||||
sbLine.append("[");
|
||||
sbLine.append(currentTime);
|
||||
sbLine.append("] Power to ");
|
||||
sbLine.append(appName);
|
||||
appWinBoLLNewsBean.setMessage(sbLine.toString());
|
||||
|
||||
APPNewsWidget.addWinBoLLNewsBean(context, appWinBoLLNewsBean);
|
||||
|
||||
Intent intentWidget = new Intent(context, APPNewsWidget.class);
|
||||
intentWidget.setAction(APPNewsWidget.ACTION_RELOAD_REPORT);
|
||||
context.sendBroadcast(intentWidget);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// String sos = intent.getStringExtra(SOS.EXTRA_OBJECT);
|
||||
// LogUtils.d(TAG, String.format("SOS %s", sos));
|
||||
// if (sos != null && !sos.equals("")) {
|
||||
// SOSObject bean = SOS.parseSOSObject(sos);
|
||||
// if (bean != null) {
|
||||
// String szObjectPackageName = bean.getObjectPackageName();
|
||||
// LogUtils.d(TAG, String.format("szObjectPackageName %s", szObjectPackageName));
|
||||
// String szObjectServiveName = bean.getObjectServiveName();
|
||||
// LogUtils.d(TAG, String.format("szObjectServiveName %s", szObjectServiveName));
|
||||
//
|
||||
// Intent intentService = new Intent();
|
||||
// intentService.setComponent(new ComponentName(szObjectPackageName, szObjectServiveName));
|
||||
// context.startService(intentService);
|
||||
//
|
||||
// String appName = AppUtils.getAppNameByPackageName(context, szObjectPackageName);
|
||||
// LogUtils.d(TAG, String.format("appName %s", appName));
|
||||
// WinBoLLNewsBean appWinBoLLNewsBean = new WinBoLLNewsBean(appName);
|
||||
// SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
|
||||
// String currentTime = sdf.format(new Date());
|
||||
// StringBuilder sbLine = new StringBuilder();
|
||||
// sbLine.append("[");
|
||||
// sbLine.append(currentTime);
|
||||
// sbLine.append("] Power to ");
|
||||
// sbLine.append(appName);
|
||||
// appWinBoLLNewsBean.setMessage(sbLine.toString());
|
||||
//
|
||||
// APPNewsWidget.addWinBoLLNewsBean(context, appWinBoLLNewsBean);
|
||||
//
|
||||
// Intent intentWidget = new Intent(context, APPNewsWidget.class);
|
||||
// intentWidget.setAction(APPNewsWidget.ACTION_RELOAD_REPORT);
|
||||
// context.sendBroadcast(intentWidget);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
} else {
|
||||
ToastUtils.show(szAction);
|
||||
}
|
||||
|
||||
@@ -17,13 +17,13 @@ public class MyBroadcastReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (context.getString(R.string.action_sos).equals(intent.getAction())) {
|
||||
String message = intent.getStringExtra("message");
|
||||
String sosPackage = intent.getStringExtra("sosPackage");
|
||||
|
||||
// 处理接收到的广播消息
|
||||
LogUtils.d(TAG, String.format("MyBroadcastReceiver action %s \n%s\n%s", intent.getAction(), sosPackage, message));
|
||||
}
|
||||
// if (context.getString(R.string.action_sos).equals(intent.getAction())) {
|
||||
// String message = intent.getStringExtra("message");
|
||||
// String sosPackage = intent.getStringExtra("sosPackage");
|
||||
//
|
||||
// // 处理接收到的广播消息
|
||||
// LogUtils.d(TAG, String.format("MyBroadcastReceiver action %s \n%s\n%s", intent.getAction(), sosPackage, message));
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ public class TestDemoBindService extends Service {
|
||||
// 所以退出时检查本服务是否配置启用,如果启用就发送一个 SOS 信号。
|
||||
// 这样 APPBase 就会用组件方式启动本服务。
|
||||
if (bean.isEnable()) {
|
||||
if (App.isDebuging()) {
|
||||
if (App.isDebugging()) {
|
||||
SOS.sosToAppBaseBeta(this, TestDemoBindService.class.getName());
|
||||
} else {
|
||||
SOS.sosToAppBase(this, TestDemoBindService.class.getName());
|
||||
@@ -156,7 +156,7 @@ public class TestDemoBindService extends Service {
|
||||
isStarted = true;
|
||||
super.run();
|
||||
LogUtils.d(TAG, "run() start");
|
||||
if (App.isDebuging()) {
|
||||
if (App.isDebugging()) {
|
||||
WinBoLL.bindToAPPBaseBeta(mContext, TestDemoBindService.class.getName());
|
||||
} else {
|
||||
WinBoLL.bindToAPPBase(mContext, TestDemoBindService.class.getName());
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package cc.winboll.studio.winboll.utils;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Date 2025/11/27 10:25
|
||||
* @Describe ServiceUtils
|
||||
*/
|
||||
public class ServiceUtils {
|
||||
|
||||
public static final String TAG = ServiceUtils.class.getSimpleName();
|
||||
|
||||
public static boolean isServiceAlive(Context context, String szServiceName) {
|
||||
// 获取Activity管理者对象
|
||||
ActivityManager manager = (ActivityManager) context
|
||||
.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
// 获取正在运行的服务(此处设置最多取1000个)
|
||||
List<ActivityManager.RunningServiceInfo> runningServices = manager
|
||||
.getRunningServices(1000);
|
||||
if (runningServices.size() <= 0) {
|
||||
return false;
|
||||
}
|
||||
// 遍历,若存在名字和传入的serviceName的一致则说明存在
|
||||
for (ActivityManager.RunningServiceInfo runningServiceInfo : runningServices) {
|
||||
if (runningServiceInfo.service.getClassName().equals(szServiceName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.winboll.models.ResponseData;
|
||||
import cc.winboll.studio.winboll.models.UserInfoModel;
|
||||
import com.google.gson.Gson;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -26,9 +28,6 @@ import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import cc.winboll.studio.winboll.models.UserInfoModel;
|
||||
import cc.winboll.studio.winboll.models.ResponseData;
|
||||
import cc.winboll.studio.libapputils.utils.FileUtils;
|
||||
|
||||
public class YunUtils {
|
||||
public static final String TAG = "YunUtils";
|
||||
@@ -138,62 +137,63 @@ public class YunUtils {
|
||||
}
|
||||
|
||||
UserInfoModel loadUserInfoModel() {
|
||||
LogUtils.d(TAG, "loadUserInfoModel");
|
||||
if (new File(mUserInfoModelPath).exists()) {
|
||||
try {
|
||||
// 加载加密后的模型数据
|
||||
byte[] encryptedData = FileUtils.readByteArrayFromFile(mUserInfoModelPath);
|
||||
// 加载 RSA 工具
|
||||
RSAUtils utils = RSAUtils.getInstance(mContext);
|
||||
KeyPair keyPair = utils.getOrGenerateKeys();
|
||||
//PublicKey publicKey = keyPair.getPublic();
|
||||
PrivateKey privateKey = keyPair.getPrivate();
|
||||
// 私钥解密模型数据
|
||||
String szInfo = utils.decryptWithPrivateKey(encryptedData, keyPair.getPrivate());
|
||||
LogUtils.d(TAG, String.format("szInfo %s", szInfo));
|
||||
mUserInfoModel = UserInfoModel.parseStringToBean(szInfo, UserInfoModel.class);
|
||||
if (mUserInfoModel == null) {
|
||||
LogUtils.d(TAG, "模型数据解析为空数据。");
|
||||
}
|
||||
LogUtils.d(TAG, "UserInfoModel 解密加载结束。");
|
||||
} catch (Exception e) {
|
||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||
}
|
||||
} else {
|
||||
LogUtils.d(TAG, "云服务登录信息不存在。");
|
||||
mUserInfoModel = null;
|
||||
}
|
||||
return mUserInfoModel;
|
||||
// LogUtils.d(TAG, "loadUserInfoModel");
|
||||
// if (new File(mUserInfoModelPath).exists()) {
|
||||
// try {
|
||||
// // 加载加密后的模型数据
|
||||
// byte[] encryptedData = FileUtils.readByteArrayFromFile(mUserInfoModelPath);
|
||||
// // 加载 RSA 工具
|
||||
// RSAUtils utils = RSAUtils.getInstance(mContext);
|
||||
// KeyPair keyPair = utils.getOrGenerateKeys();
|
||||
// //PublicKey publicKey = keyPair.getPublic();
|
||||
// PrivateKey privateKey = keyPair.getPrivate();
|
||||
// // 私钥解密模型数据
|
||||
// String szInfo = utils.decryptWithPrivateKey(encryptedData, keyPair.getPrivate());
|
||||
// LogUtils.d(TAG, String.format("szInfo %s", szInfo));
|
||||
// mUserInfoModel = UserInfoModel.parseStringToBean(szInfo, UserInfoModel.class);
|
||||
// if (mUserInfoModel == null) {
|
||||
// LogUtils.d(TAG, "模型数据解析为空数据。");
|
||||
// }
|
||||
// LogUtils.d(TAG, "UserInfoModel 解密加载结束。");
|
||||
// } catch (Exception e) {
|
||||
// LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||
// }
|
||||
// } else {
|
||||
// LogUtils.d(TAG, "云服务登录信息不存在。");
|
||||
// mUserInfoModel = null;
|
||||
// }
|
||||
// return mUserInfoModel;
|
||||
return null;
|
||||
}
|
||||
|
||||
void saveUserInfoModel(UserInfoModel userInfoModel) {
|
||||
LogUtils.d(TAG, "saveUserInfoModel");
|
||||
try {
|
||||
String szInfo = userInfoModel.toString();
|
||||
LogUtils.d(TAG, "原始数据: " + szInfo);
|
||||
|
||||
RSAUtils utils = RSAUtils.getInstance(mContext);
|
||||
KeyPair keyPair = utils.getOrGenerateKeys();
|
||||
PublicKey publicKey = keyPair.getPublic();
|
||||
|
||||
// 公钥加密(传入字节数组,避免中间字符串转换)
|
||||
byte[] encryptedData = utils.encryptWithPublicKey(szInfo, publicKey);
|
||||
|
||||
// 保存加密字节数组到文件(直接操作字节,无需转字符串)
|
||||
FileUtils.writeByteArrayToFile(encryptedData, mUserInfoModelPath);
|
||||
LogUtils.d(TAG, "加密数据已保存");
|
||||
|
||||
// 测试解密(仅调试用)
|
||||
String szInfo2 = utils.decryptWithPrivateKey(encryptedData, keyPair.getPrivate());
|
||||
LogUtils.d(TAG, "解密结果: " + szInfo2);
|
||||
|
||||
mUserInfoModel = UserInfoModel.parseStringToBean(szInfo2, UserInfoModel.class);
|
||||
if (mUserInfoModel == null) {
|
||||
LogUtils.d(TAG, "模型解析失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.d(TAG, "加密/解密失败: " + e.getMessage());
|
||||
}
|
||||
// LogUtils.d(TAG, "saveUserInfoModel");
|
||||
// try {
|
||||
// String szInfo = userInfoModel.toString();
|
||||
// LogUtils.d(TAG, "原始数据: " + szInfo);
|
||||
//
|
||||
// RSAUtils utils = RSAUtils.getInstance(mContext);
|
||||
// KeyPair keyPair = utils.getOrGenerateKeys();
|
||||
// PublicKey publicKey = keyPair.getPublic();
|
||||
//
|
||||
// // 公钥加密(传入字节数组,避免中间字符串转换)
|
||||
// byte[] encryptedData = utils.encryptWithPublicKey(szInfo, publicKey);
|
||||
//
|
||||
// // 保存加密字节数组到文件(直接操作字节,无需转字符串)
|
||||
// FileUtils.writeByteArrayToFile(encryptedData, mUserInfoModelPath);
|
||||
// LogUtils.d(TAG, "加密数据已保存");
|
||||
//
|
||||
// // 测试解密(仅调试用)
|
||||
// String szInfo2 = utils.decryptWithPrivateKey(encryptedData, keyPair.getPrivate());
|
||||
// LogUtils.d(TAG, "解密结果: " + szInfo2);
|
||||
//
|
||||
// mUserInfoModel = UserInfoModel.parseStringToBean(szInfo2, UserInfoModel.class);
|
||||
// if (mUserInfoModel == null) {
|
||||
// LogUtils.d(TAG, "模型解析失败");
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// LogUtils.d(TAG, "加密/解密失败: " + e.getMessage());
|
||||
// }
|
||||
}
|
||||
|
||||
// 发送 POST 请求(JSON 数据)
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
package cc.winboll.studio.winboll.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebResourceError;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Date 2025/11/27 11:05
|
||||
* @Describe 自定义WebView控件(WinBoLLView)
|
||||
* 集成进度监听、页面加载控制、安全配置等核心能力
|
||||
*/
|
||||
public class WinBoLLView extends WebView {
|
||||
public static final String TAG = "WinBoLLView";
|
||||
|
||||
private ProgressBar mProgressBar; // 页面加载进度条(可选,增强用户体验)
|
||||
private OnPageStatusListener mStatusListener; // 页面状态监听回调
|
||||
private boolean mIsLoading = false; // 自定义加载状态标记(替代系统isLoading())
|
||||
|
||||
// 构造方法(兼容代码创建和XML布局引用)
|
||||
public WinBoLLView(Context context) {
|
||||
super(context);
|
||||
initWebViewSettings();
|
||||
initWebViewClient();
|
||||
}
|
||||
|
||||
public WinBoLLView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initWebViewSettings();
|
||||
initWebViewClient();
|
||||
}
|
||||
|
||||
public WinBoLLView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initWebViewSettings();
|
||||
initWebViewClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化WebView基础配置(安全+性能+兼容性)
|
||||
*/
|
||||
private void initWebViewSettings() {
|
||||
WebSettings settings = getSettings();
|
||||
|
||||
// 基础功能配置
|
||||
settings.setJavaScriptEnabled(true); // 启用JS(根据需求决定是否开启)
|
||||
settings.setSupportZoom(true); // 支持缩放
|
||||
settings.setBuiltInZoomControls(true); // 显示缩放控件
|
||||
settings.setDisplayZoomControls(false); // 隐藏系统缩放控件(优化UI)
|
||||
settings.setLoadWithOverviewMode(true); // 自适应屏幕
|
||||
settings.setUseWideViewPort(true); // 支持宽视角
|
||||
|
||||
// 缓存配置(提升加载速度)
|
||||
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
|
||||
settings.setDomStorageEnabled(true); // 启用DOM存储
|
||||
settings.setDatabaseEnabled(true); // 启用数据库存储
|
||||
|
||||
// 安全配置(防止XSS和恶意跳转)
|
||||
settings.setJavaScriptCanOpenWindowsAutomatically(false); // 禁止JS自动打开窗口
|
||||
setBackgroundColor(0x00000000); // 透明背景(避免白屏闪烁)
|
||||
|
||||
// 适配HTTPS和HTTP混合内容(Android 5.0+)
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
|
||||
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化WebViewClient和ChromeClient(控制页面加载和进度)
|
||||
*/
|
||||
private void initWebViewClient() {
|
||||
// 控制页面跳转(不打开系统浏览器)
|
||||
setWebViewClient(new WebViewClient() {
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
||||
// 拦截URL加载,使用当前WebView打开
|
||||
view.loadUrl(request.getUrl().toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageStarted(WebView view, String url, android.graphics.Bitmap favicon) {
|
||||
super.onPageStarted(view, url, favicon);
|
||||
// 页面开始加载:更新自定义加载状态标记
|
||||
mIsLoading = true;
|
||||
// 更新进度条+回调状态
|
||||
if (mProgressBar != null) mProgressBar.setVisibility(VISIBLE);
|
||||
if (mStatusListener != null) mStatusListener.onPageStarted(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
super.onPageFinished(view, url);
|
||||
// 页面加载完成:更新自定义加载状态标记
|
||||
mIsLoading = false;
|
||||
// 隐藏进度条+回调状态
|
||||
if (mProgressBar != null) mProgressBar.setVisibility(GONE);
|
||||
if (mStatusListener != null) mStatusListener.onPageFinished(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
|
||||
super.onReceivedError(view, request, error);
|
||||
// 页面加载错误:更新自定义加载状态标记
|
||||
mIsLoading = false;
|
||||
// 回调错误信息
|
||||
if (mStatusListener != null) {
|
||||
String errorMsg = error.getDescription().toString();
|
||||
mStatusListener.onPageError(errorMsg);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 监听页面加载进度
|
||||
setWebChromeClient(new WebChromeClient() {
|
||||
@Override
|
||||
public void onProgressChanged(WebView view, int newProgress) {
|
||||
super.onProgressChanged(view, newProgress);
|
||||
// 更新进度条进度
|
||||
if (mProgressBar != null) mProgressBar.setProgress(newProgress);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ------------------- 对外暴露的控制方法(供Fragment调用) -------------------
|
||||
/**
|
||||
* 加载URL(增加空值校验+优先HTTPS协议)
|
||||
*/
|
||||
public void loadUrlSafe(String url) {
|
||||
if (url == null || url.trim().isEmpty()) {
|
||||
if (mStatusListener != null) mStatusListener.onPageError("URL不能为空");
|
||||
return;
|
||||
}
|
||||
// 协议补全:优先HTTPS,兼容HTTP(解决ERR_CLEARTEXT_NOT_PERMITTED)
|
||||
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
||||
url = "https://" + url; // 改为优先HTTPS,而非HTTP
|
||||
}
|
||||
super.loadUrl(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新当前页面(使用自定义mIsLoading判断加载状态)
|
||||
*/
|
||||
public void refreshPage() {
|
||||
if (mIsLoading) { // 替换原isLoading(),使用自定义标记
|
||||
stopLoading(); // 若正在加载,先停止再刷新
|
||||
}
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止页面加载(使用自定义mIsLoading判断加载状态)
|
||||
*/
|
||||
public void stopPageLoad() {
|
||||
if (mIsLoading) { // 替换原isLoading(),使用自定义标记
|
||||
stopLoading();
|
||||
mIsLoading = false; // 停止后更新状态标记
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 前进(判断是否有前进历史)
|
||||
*/
|
||||
public boolean goForwardSafe() {
|
||||
if (canGoForward()) {
|
||||
goForward();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后退(判断是否有后退历史)
|
||||
*/
|
||||
public boolean goBackSafe() {
|
||||
if (canGoBack()) {
|
||||
goBack();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------- 辅助功能:进度条和状态监听 -------------------
|
||||
/**
|
||||
* 设置进度条(绑定Fragment中的进度条控件)
|
||||
*/
|
||||
public void setProgressBar(ProgressBar progressBar) {
|
||||
this.mProgressBar = progressBar;
|
||||
if (mProgressBar != null) {
|
||||
mProgressBar.setMax(100);
|
||||
mProgressBar.setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置页面状态监听(供Fragment接收加载状态)
|
||||
*/
|
||||
public void setOnPageStatusListener(OnPageStatusListener listener) {
|
||||
this.mStatusListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面状态监听接口
|
||||
*/
|
||||
public interface OnPageStatusListener {
|
||||
void onPageStarted(String url); // 页面开始加载
|
||||
void onPageFinished(String url); // 页面加载完成
|
||||
void onPageError(String errorMsg); // 页面加载错误
|
||||
}
|
||||
|
||||
// ------------------- 资源释放(防止内存泄漏) -------------------
|
||||
/**
|
||||
* 销毁WebView(必须在Fragment销毁时调用)
|
||||
*/
|
||||
public void destroyWebView() {
|
||||
// 停止加载并清空历史
|
||||
stopLoading();
|
||||
mIsLoading = false; // 销毁时重置加载状态
|
||||
clearHistory();
|
||||
// 移除所有WebViewClient(避免内存泄漏)
|
||||
setWebViewClient(null);
|
||||
setWebChromeClient(null);
|
||||
// 销毁WebView
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.widget.RemoteViews;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libapputils.utils.AppUtils;
|
||||
import cc.winboll.studio.winboll.R;
|
||||
import cc.winboll.studio.winboll.WinBoLL;
|
||||
import cc.winboll.studio.winboll.models.WinBoLLModel;
|
||||
@@ -56,43 +55,43 @@ public class APPNewsWidget extends AppWidgetProvider {
|
||||
updateAppWidget(context, appWidgetManager, appWidgetId);
|
||||
}
|
||||
}else if (intent.getAction().equals(ACTION_WAKEUP_SERVICE)) {
|
||||
LogUtils.d(TAG, "ACTION_WAKEUP_SERVICE");
|
||||
String szWinBoLLModel = intent.getStringExtra(WinBoLL.EXTRA_WINBOLLMODEL);
|
||||
LogUtils.d(TAG, String.format("szWinBoLLModel %s", szWinBoLLModel));
|
||||
if (szWinBoLLModel != null && !szWinBoLLModel.equals("")) {
|
||||
try {
|
||||
WinBoLLModel bean = WinBoLLModel.parseStringToBean(szWinBoLLModel, WinBoLLModel.class);
|
||||
if (bean != null) {
|
||||
String szAppPackageName = bean.getAppPackageName();
|
||||
LogUtils.d(TAG, String.format("szAppPackageName %s", szAppPackageName));
|
||||
String szAppMainServiveName = bean.getAppMainServiveName();
|
||||
LogUtils.d(TAG, String.format("szAppMainServiveName %s", szAppMainServiveName));
|
||||
|
||||
|
||||
String appName = AppUtils.getAppNameByPackageName(context, szAppPackageName);
|
||||
LogUtils.d(TAG, String.format("appName %s", appName));
|
||||
WinBoLLNewsBean winBollNewsBean = new WinBoLLNewsBean(appName);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
|
||||
String currentTime = sdf.format(new Date());
|
||||
StringBuilder sbLine = new StringBuilder();
|
||||
sbLine.append("[");
|
||||
sbLine.append(currentTime);
|
||||
sbLine.append("] Wake up ");
|
||||
sbLine.append(appName);
|
||||
winBollNewsBean.setMessage(sbLine.toString());
|
||||
|
||||
addWinBoLLNewsBean(context, winBollNewsBean);
|
||||
|
||||
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
|
||||
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, APPNewsWidget.class));
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
updateAppWidget(context, appWidgetManager, appWidgetId);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||
}
|
||||
}
|
||||
// LogUtils.d(TAG, "ACTION_WAKEUP_SERVICE");
|
||||
// String szWinBoLLModel = intent.getStringExtra(WinBoLL.EXTRA_WINBOLLMODEL);
|
||||
// LogUtils.d(TAG, String.format("szWinBoLLModel %s", szWinBoLLModel));
|
||||
// if (szWinBoLLModel != null && !szWinBoLLModel.equals("")) {
|
||||
// try {
|
||||
// WinBoLLModel bean = WinBoLLModel.parseStringToBean(szWinBoLLModel, WinBoLLModel.class);
|
||||
// if (bean != null) {
|
||||
// String szAppPackageName = bean.getAppPackageName();
|
||||
// LogUtils.d(TAG, String.format("szAppPackageName %s", szAppPackageName));
|
||||
// String szAppMainServiveName = bean.getAppMainServiveName();
|
||||
// LogUtils.d(TAG, String.format("szAppMainServiveName %s", szAppMainServiveName));
|
||||
//
|
||||
//
|
||||
// String appName = AppUtils.getAppNameByPackageName(context, szAppPackageName);
|
||||
// LogUtils.d(TAG, String.format("appName %s", appName));
|
||||
// WinBoLLNewsBean winBollNewsBean = new WinBoLLNewsBean(appName);
|
||||
// SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
|
||||
// String currentTime = sdf.format(new Date());
|
||||
// StringBuilder sbLine = new StringBuilder();
|
||||
// sbLine.append("[");
|
||||
// sbLine.append(currentTime);
|
||||
// sbLine.append("] Wake up ");
|
||||
// sbLine.append(appName);
|
||||
// winBollNewsBean.setMessage(sbLine.toString());
|
||||
//
|
||||
// addWinBoLLNewsBean(context, winBollNewsBean);
|
||||
//
|
||||
// AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
|
||||
// int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, APPNewsWidget.class));
|
||||
// for (int appWidgetId : appWidgetIds) {
|
||||
// updateAppWidget(context, appWidgetManager, appWidgetId);
|
||||
// }
|
||||
// }
|
||||
// } catch (IOException e) {
|
||||
// LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
7
winboll/src/main/res/drawable/bg_browser_top.xml
Normal file
7
winboll/src/main/res/drawable/bg_browser_top.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@android:color/white"/>
|
||||
<corners android:radius="8dp"/>
|
||||
<stroke android:color="@android:color/darker_gray" android:width="1dp"/>
|
||||
</shape>
|
||||
7
winboll/src/main/res/drawable/bg_edittext.xml
Normal file
7
winboll/src/main/res/drawable/bg_edittext.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@android:color/white"/>
|
||||
<corners android:radius="24dp"/>
|
||||
<stroke android:color="@android:color/darker_gray" android:width="1dp"/>
|
||||
</shape>
|
||||
BIN
winboll/src/main/res/drawable/ic_winboll_jindouyun1.png
Normal file
BIN
winboll/src/main/res/drawable/ic_winboll_jindouyun1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
BIN
winboll/src/main/res/drawable/ic_winboll_jindouyun2.png
Normal file
BIN
winboll/src/main/res/drawable/ic_winboll_jindouyun2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
8
winboll/src/main/res/drawable/progress_bar_style.xml
Normal file
8
winboll/src/main/res/drawable/progress_bar_style.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@android:id/background" android:drawable="@android:color/darker_gray"/>
|
||||
<item android:id="@android:id/progress">
|
||||
<clip android:drawable="@android:color/holo_blue_light"/>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
||||
96
winboll/src/main/res/layout/fragment_browser.xml
Normal file
96
winboll/src/main/res/layout/fragment_browser.xml
Normal file
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- 顶部地址栏区域(水平布局:输入框+功能按钮) -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:background="@drawable/bg_browser_top"
|
||||
android:padding="4dp">
|
||||
|
||||
<!-- 地址输入框 -->
|
||||
<EditText
|
||||
android:id="@+id/et_url"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_weight="1"
|
||||
android:hint="请输入URL或搜索内容"
|
||||
android:paddingHorizontal="12dp"
|
||||
android:background="@drawable/bg_edittext"
|
||||
android:singleLine="true"
|
||||
android:imeOptions="actionGo"
|
||||
android:inputType="textUri" /> <!-- 提示输入URL格式 -->
|
||||
|
||||
<!-- 功能按钮区域(水平排列:加载、刷新、停止、前进、后退) -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingHorizontal="4dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_load"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:text="加载"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginHorizontal="2dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_refresh"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:text="刷新"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginHorizontal="2dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_stop"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:text="停止"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginHorizontal="2dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_forward"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:text="前进"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginHorizontal="2dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_back"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:text="后退"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginHorizontal="2dp"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 页面加载进度条(位于地址栏下方,WebView上方) -->
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:progressDrawable="@drawable/progress_bar_style"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<!-- 自定义WebView(WinBoLLView) -->
|
||||
<cc.winboll.studio.winboll.views.WinBoLLView
|
||||
android:id="@+id/winboll_webview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -3,18 +3,5 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/item_home"
|
||||
android:title="HOME"
|
||||
android:icon="@drawable/ic_winboll"/>
|
||||
<item
|
||||
android:id="@+id/item_yun"
|
||||
android:title="YUN"
|
||||
android:icon="@drawable/ic_winboll"/>
|
||||
<item
|
||||
android:id="@+id/item_logon"
|
||||
android:title="Logon"
|
||||
android:icon="@drawable/ic_winboll"/>
|
||||
<item
|
||||
android:id="@+id/item_log"
|
||||
android:title="LOG"
|
||||
android:icon="@drawable/ic_winboll_log"/>
|
||||
android:title="HOME"/>
|
||||
</menu>
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<!-- 允许访问 winboll.cc 及其子域名(原配置) -->
|
||||
<!-- 允许特定域名的HTTP明文请求(如winboll.com) -->
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="true">winboll.cc</domain>
|
||||
</domain-config>
|
||||
|
||||
<!-- **新增:允许访问 IP 地址 10.8.0.250** -->
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="false">10.8.0.250</domain> <!-- 不包含子域名 -->
|
||||
<domain includeSubdomains="true">winboll.cc</domain> <!-- 你的目标域名 -->
|
||||
<domain includeSubdomains="true">www.winboll.cc</domain> <!-- 其他需要兼容的域名 -->
|
||||
</domain-config>
|
||||
<!-- 默认允许HTTPS(全局生效) -->
|
||||
<base-config cleartextTrafficPermitted="false">
|
||||
<trust-anchors>
|
||||
<certificates src="system" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
</network-security-config>
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
android:shortcutLongLabel="@string/switchto_en1"
|
||||
android:shortcutDisabledMessage="@string/en1_switch_disabled">
|
||||
<intent
|
||||
android:action="cc.winboll.studio.powerbell.App.ACTION_SWITCHTO_EN1"
|
||||
android:targetPackage="cc.winboll.studio.powerbell"
|
||||
android:targetClass="cc.winboll.studio.powerbell.activities.ShortcutActionActivity"
|
||||
android:action="cc.winboll.studio.winboll.App.ACTION_SWITCHTO_EN1"
|
||||
android:targetPackage="cc.winboll.studio.winboll"
|
||||
android:targetClass="cc.winboll.studio.winboll.activities.ShortcutActionActivity"
|
||||
android:data="switchto_en1" />
|
||||
<categories android:name="android.shortcut.conversation" />
|
||||
</shortcut>-->
|
||||
@@ -23,9 +23,9 @@
|
||||
android:shortcutLongLabel="@string/switchto_cn1"
|
||||
android:shortcutDisabledMessage="@string/cn1_switch_disabled">
|
||||
<intent
|
||||
android:action="cc.winboll.studio.powerbell.App.ACTION_SWITCHTO_CN1"
|
||||
android:targetPackage="cc.winboll.studio.powerbell"
|
||||
android:targetClass="cc.winboll.studio.powerbell.activities.ShortcutActionActivity"
|
||||
android:action="cc.winboll.studio.winboll.App.ACTION_SWITCHTO_CN1"
|
||||
android:targetPackage="cc.winboll.studio.winboll"
|
||||
android:targetClass="cc.winboll.studio.winboll.activities.ShortcutActionActivity"
|
||||
android:data="switchto_cn1" />
|
||||
<categories android:name="android.shortcut.conversation" />
|
||||
</shortcut>
|
||||
@@ -37,9 +37,9 @@
|
||||
android:shortcutLongLabel="@string/switchto_cn2"
|
||||
android:shortcutDisabledMessage="@string/cn2_switch_disabled">
|
||||
<intent
|
||||
android:action="cc.winboll.studio.powerbell.App.ACTION_SWITCHTO_CN2"
|
||||
android:targetPackage="cc.winboll.studio.powerbell"
|
||||
android:targetClass="cc.winboll.studio.powerbell.activities.ShortcutActionActivity"
|
||||
android:action="cc.winboll.studio.winboll.App.ACTION_SWITCHTO_CN2"
|
||||
android:targetPackage="cc.winboll.studio.winboll"
|
||||
android:targetClass="cc.winboll.studio.winboll.activities.ShortcutActionActivity"
|
||||
android:data="switchto_cn2" />
|
||||
<categories android:name="android.shortcut.conversation" />
|
||||
</shortcut>
|
||||
|
||||
12
winboll/src/stage/AndroidManifest.xml
Normal file
12
winboll/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
winboll/src/stage/res/values/strings.xml
Normal file
6
winboll/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>
|
||||
Reference in New Issue
Block a user