Compare commits

..

4 Commits

Author SHA1 Message Date
Doubao-Seed-1.8 77e87e7c8c fix(AboutActivity): 修复ClassCastException和NullPointerException崩溃问题
1. 修复Toolbar类型转换异常:
   - 将Toolbar变量改为ASupportToolbar类型
   - 添加类型检查和错误处理
   - 在布局文件中明确指定AppCompat主题

2. 修复AboutView空指针异常:
   - 添加null检查,避免崩溃
   - 增强日志输出,便于问题定位

3. 代码优化:
   - 提升initToolbar()方法的健壮性
   - 添加异常捕获和处理机制
   - 确保即使组件加载失败也能继续执行后续流程

这些修改解决了AboutActivity启动时的两个关键崩溃问题,提升了应用的稳定性。
2026-07-22 04:05:52 +08:00
ZhanGSKen 6eb16f7fb4 恢复ByTheWay_V15.20.7源码
ByTheWay_V15.20.7源码编译参数修改情况:
└─▶ git diff build.properties
diff --git a/bytheway/build.properties b/bytheway/build.properties
index 9719b62..4df5b19 100644
--- a/bytheway/build.properties
+++ b/bytheway/build.properties
@@ -1,8 +1,8 @@
 #Created by .winboll/winboll_app_build.gradle
-#Mon Jul 13 06:10:46 HKT 2026
-stageCount=8
+#Tue Jul 21 18:53:02 GMT 2026
+stageCount=0
 libraryProject=
-baseVersion=15.20
-publishVersion=15.20.7
-buildCount=0
-baseBetaVersion=15.20.8
+baseVersion=15.21
+publishVersion=15.21.0
+buildCount=1
+baseBetaVersion=15.21.1
2026-07-22 03:02:25 +08:00
ZhanGSKen e136045d1f Merge remote-tracking branch 'winboll_https/projects_keeper_tag' into mywinboll 2026-07-11 20:21:13 +08:00
qinglong bd635425a1 合并模块AES 同步最新时间标签aes-v15.20.18 2026-07-11 20:17:35 +08:00
20 changed files with 196 additions and 42 deletions
+4 -4
View File
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Mon Jun 29 11:28:11 HKT 2026
stageCount=18
#Sat Jul 11 20:07:00 HKT 2026
stageCount=19
libraryProject=libaes
baseVersion=15.20
publishVersion=15.20.17
publishVersion=15.20.18
buildCount=0
baseBetaVersion=15.20.18
baseBetaVersion=15.20.19
+1 -1
View File
@@ -5,7 +5,7 @@
</style>
<style name="MyDebugActivityTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:statusBarColor">@color/toolbarBackgroundColor</item>
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
<item name="colorTittle">@color/mainWindowTextColor</item>
<item name="colorTittleBackgound">@color/toolbarBackgroundColor</item>
<item name="colorText">@color/debugTextColor</item>
+1 -1
View File
@@ -5,7 +5,7 @@
</style>
<style name="MyDebugActivityTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:statusBarColor">@color/toolbarBackgroundColor</item>
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
<item name="colorTittle">@color/mainWindowTextColor</item>
<item name="colorTittleBackgound">@color/toolbarBackgroundColor</item>
<item name="colorText">@color/debugTextColor</item>
+3 -3
View File
@@ -33,7 +33,7 @@ android {
// versionName 更新后需要手动设置
// 项目模块目录的 build.gradle 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
versionName "15.20"
versionName "15.21"
if(true) {
versionName = genVersionName("${versionName}")
}
@@ -99,8 +99,8 @@ dependencies {
implementation 'androidx.biometric:biometric:1.1.0'
// WinBoLL库 nexus.winboll.cc 地址
api 'cc.winboll.studio:libappbase:15.20.34'
api 'cc.winboll.studio:libaes:15.20.17'
api 'cc.winboll.studio:libappbase:15.21.+'
api 'cc.winboll.studio:libaes:15.21.+'
// 备用库 jitpack.io 地址
//api 'com.github.ZhanGSKen:libappbase:appbase-v15.20.33'
+6 -6
View File
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Fri Jul 10 20:26:27 HKT 2026
stageCount=5
#Tue Jul 21 18:53:02 GMT 2026
stageCount=0
libraryProject=
baseVersion=15.20
publishVersion=15.20.4
buildCount=0
baseBetaVersion=15.20.5
baseVersion=15.21
publishVersion=15.21.0
buildCount=1
baseBetaVersion=15.21.1
+11
View File
@@ -15,6 +15,9 @@
<!-- 运行前台服务 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- 开机自启权限 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
@@ -51,6 +54,14 @@
android:launchMode="singleInstance"
android:exported="false"/>
<receiver
android:name=".receivers.ServiceCheckReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<activity android:name="cc.winboll.studio.bytheway.activities.SettingsActivity"/>
<activity android:name="cc.winboll.studio.bytheway.activities.AboutActivity"/>
@@ -1,10 +1,12 @@
package cc.winboll.studio.bytheway;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.res.Resources;
import android.graphics.Typeface;
@@ -23,6 +25,7 @@ import android.widget.TextView;
import android.widget.Toast;
import cc.winboll.studio.libaes.utils.AESThemeUtil;
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
import cc.winboll.studio.bytheway.services.GpsReceiveService;
import cc.winboll.studio.libappbase.GlobalApplication;
import cc.winboll.studio.libappbase.ToastUtils;
import cc.winboll.studio.libappbase.utils.CrashHandleNotifyUtils;
@@ -48,6 +51,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class App extends GlobalApplication {
private static Handler MAIN_HANDLER = new Handler(Looper.getMainLooper());
private BroadcastReceiver screenReceiver;
@Override
public void onCreate() {
@@ -60,6 +64,12 @@ public class App extends GlobalApplication {
// 初始化 Toast 工具类(传入应用全局上下文,确保 Toast 可在任意地方调用)
ToastUtils.init(getApplicationContext());
// 检查GPS服务SP标记,系统内存清理后自动恢复服务运行
GpsReceiveService.checkAndStartService(this);
// 动态注册屏幕广播,息屏/亮屏时检查GPS服务运行状态
registerScreenReceiver();
} catch (Throwable e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
@@ -75,6 +85,34 @@ public class App extends GlobalApplication {
}
}
private void registerScreenReceiver() {
screenReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
GpsReceiveService.checkAndStartService(context);
}
};
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
registerReceiver(screenReceiver, filter);
}
@Override
public void onTrimMemory(final int level) {
super.onTrimMemory(level);
if (level >= TRIM_MEMORY_UI_HIDDEN) {
GpsReceiveService.checkAndStartService(this);
}
}
@Override
public void onLowMemory() {
super.onLowMemory();
GpsReceiveService.checkAndStartService(this);
}
public static void write(InputStream input, OutputStream output) throws IOException {
byte[] buf = new byte[1024 * 8];
int len;
@@ -3,6 +3,7 @@ package cc.winboll.studio.bytheway;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -99,6 +100,11 @@ public class MainActivity extends BaseWinBoLLActivity {
final TextView splashTitle = findViewById(R.id.splash_title);
final TextView splashSubtitle = findViewById(R.id.splash_subtitle);
TypedValue typedValue = new TypedValue();
if (getTheme().resolveAttribute(androidx.appcompat.R.attr.colorPrimaryDark, typedValue, true)) {
splashOverlay.setBackgroundColor(typedValue.data);
}
splashOverlay.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, android.view.MotionEvent event) {
@@ -2,10 +2,10 @@ package cc.winboll.studio.bytheway.activities;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.bytheway.MainActivity;
import cc.winboll.studio.bytheway.R;
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
import cc.winboll.studio.libaes.views.ASupportToolbar;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.models.APPInfo;
import cc.winboll.studio.libappbase.views.AboutView;
@@ -19,7 +19,7 @@ public class AboutActivity extends BaseWinBoLLActivity {
public static final String TAG = "AboutActivity";
private Toolbar mToolbar;
private ASupportToolbar mToolbar;
@Override
public String getTag() {
@@ -35,27 +35,41 @@ public class AboutActivity extends BaseWinBoLLActivity {
initToolbar();
AboutView aboutView = findViewById(R.id.aboutview);
aboutView.setAPPInfo(genDefaultAppInfo());
if (aboutView != null) {
aboutView.setAPPInfo(genDefaultAppInfo());
LogUtils.d(TAG, "AboutView初始化完成");
} else {
LogUtils.e(TAG, "onCreate() | AboutView未找到");
}
}
private void initToolbar() {
LogUtils.d(TAG, "initToolbar() 开始初始化");
mToolbar = findViewById(R.id.toolbar);
if (mToolbar == null) {
View toolbarView = findViewById(R.id.toolbar);
if (toolbarView == null) {
LogUtils.e(TAG, "initToolbar() | Toolbar未找到");
return;
}
if (toolbarView instanceof ASupportToolbar) {
mToolbar = (ASupportToolbar) toolbarView;
LogUtils.d(TAG, "initToolbar() 正确获取到ASupportToolbar");
} else {
LogUtils.e(TAG, "initToolbar() | 类型转换失败,实际类型: " + toolbarView.getClass().getName());
// 尝试直接创建一个新的ASupportToolbar
mToolbar = new ASupportToolbar(this);
LogUtils.d(TAG, "initToolbar() 已创建新的ASupportToolbar实例");
}
setSupportActionBar(mToolbar);
mToolbar.setSubtitle(getTag());
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LogUtils.d(TAG, "导航栏 点击返回按钮");
WinBoLLActivityManager.getInstance().resumeActivity(MainActivity.class);
WinBoLLActivityManager.getInstance().finish(AboutActivity.this);
}
});
@Override
public void onClick(View v) {
LogUtils.d(TAG, "导航栏 点击返回按钮");
WinBoLLActivityManager.getInstance().resumeActivity(MainActivity.class);
WinBoLLActivityManager.getInstance().finish(AboutActivity.this);
}
});
LogUtils.d(TAG, "initToolbar() 配置完成");
}
@@ -21,7 +21,7 @@ public abstract class BaseWinBoLLActivity extends AppCompatActivity implements I
@Override
protected void onCreate(Bundle savedInstanceState) {
//AESThemeUtil.applyAppCompatTheme(this);
AESThemeUtil.applyAppCompatTheme(this);
mThemeType = AESThemeBean.getThemeStyleType(AESThemeUtil.getThemeTypeID(getApplicationContext()));
setTheme(AESThemeUtil.getThemeTypeID(getApplicationContext()));
super.onCreate(savedInstanceState);
@@ -17,7 +17,7 @@ public class SettingsActivity extends Activity {
setContentView(R.layout.activity_settings);
Switch swGpsReceiveService = findViewById(R.id.sw_gps_receive_service);
swGpsReceiveService.setChecked(GpsReceiveService.isServiceRunning());
swGpsReceiveService.setChecked(GpsReceiveService.isServiceShouldRun(SettingsActivity.this));
swGpsReceiveService.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@@ -0,0 +1,22 @@
package cc.winboll.studio.bytheway.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import cc.winboll.studio.bytheway.services.GpsReceiveService;
import cc.winboll.studio.libappbase.LogUtils;
/**
* 开机广播接收器,系统启动完成后检查GPS服务SP标记并自动恢复运行
*/
public class ServiceCheckReceiver extends BroadcastReceiver {
public static final String TAG = "ServiceCheckReceiver";
@Override
public void onReceive(final Context context, final Intent intent) {
final String action = intent.getAction();
LogUtils.i(TAG, "收到广播: " + action);
GpsReceiveService.checkAndStartService(context);
}
}
@@ -3,9 +3,11 @@ package cc.winboll.studio.bytheway.services;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
@@ -13,6 +15,8 @@ import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.widget.Toast;
import cc.winboll.studio.bytheway.MainActivity;
import cc.winboll.studio.bytheway.R;
import cc.winboll.studio.bytheway.models.GpsBean;
import cc.winboll.studio.bytheway.utils.GpsUtil;
import cc.winboll.studio.libappbase.LogUtils;
@@ -27,6 +31,8 @@ public class GpsReceiveService extends Service {
public static final String TAG = "GpsReceiveService";
private static final int NOTIFICATION_ID = 1001;
private static final String CHANNEL_ID = "gps_receive_service_channel";
private static final String SP_NAME = "gps_receive_service";
private static final String KEY_SHOULD_RUN = "service_should_run";
private static boolean serviceRunning = false;
private static GpsReceiveService instance;
@@ -51,14 +57,36 @@ public class GpsReceiveService extends Service {
return serviceRunning ? instance.currentGpsBean : null;
}
private static SharedPreferences getSp(final Context context) {
return context.getApplicationContext().getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
}
public static boolean isServiceShouldRun(final Context context) {
return getSp(context).getBoolean(KEY_SHOULD_RUN, false);
}
private static void setServiceShouldRun(final Context context, final boolean shouldRun) {
getSp(context).edit().putBoolean(KEY_SHOULD_RUN, shouldRun).apply();
}
/**
* 检查SP标记,若设置为运行且服务未运行则自动启动
*/
public static void checkAndStartService(final Context context) {
if (isServiceShouldRun(context) && !serviceRunning) {
startGpsReceiveService(context);
}
}
/**
* 外部统一静态启动服务
*/
public static void startGpsReceiveService(final Context context) {
if (serviceRunning) {
if (serviceRunning && instance != null) {
LogUtils.i("GpsReceiveService", "服务已运行,无需重复启动");
return;
}
setServiceShouldRun(context, true);
final Intent intent = new Intent(context, GpsReceiveService.class);
context.startService(intent);
LogUtils.i("GpsReceiveService", "GPS定位消息接收服务启动请求发送");
@@ -68,6 +96,7 @@ public class GpsReceiveService extends Service {
* 外部统一静态关闭服务
*/
public static void stopGpsReceiveService(final Context context) {
setServiceShouldRun(context, false);
if (!serviceRunning) {
LogUtils.i("GpsReceiveService", "服务未运行,无需关闭");
return;
@@ -80,6 +109,11 @@ public class GpsReceiveService extends Service {
@Override
public void onCreate() {
super.onCreate();
if (serviceRunning && instance != null) {
LogUtils.i("GpsReceiveService", "检测到重复实例,停止当前实例");
stopSelf();
return;
}
instance = this;
serviceRunning = true;
gpsReceiveCount = 0;
@@ -110,13 +144,23 @@ public class GpsReceiveService extends Service {
contentText = "等待GPS定位数据...";
}
return new Notification.Builder(this, CHANNEL_ID)
.setContentTitle("ByTheWay")
.setContentTitle(getString(R.string.app_name))
.setContentText(contentText)
.setSmallIcon(android.R.drawable.ic_menu_mylocation)
.setContentIntent(createContentIntent())
.setOngoing(true)
.build();
}
/**
* 创建通知点击跳转主窗口的PendingIntent
*/
private PendingIntent createContentIntent() {
final Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
}
/**
* 更新前台服务通知栏显示
*/
@@ -187,8 +231,16 @@ public class GpsReceiveService extends Service {
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
//单例不重启模式,被杀不自动重启
return START_NOT_STICKY;
if (!isServiceShouldRun(this)) {
LogUtils.i("GpsReceiveService", "SP标记为不运行,停止服务");
stopSelf();
return START_NOT_STICKY;
}
if (serviceRunning && instance != null) {
LogUtils.i("GpsReceiveService", "服务已在运行,忽略重复启动命令");
return START_STICKY;
}
return START_STICKY;
}
@Override
@@ -196,6 +248,12 @@ public class GpsReceiveService extends Service {
return null;
}
@Override
public void onTaskRemoved(final Intent rootIntent) {
super.onTaskRemoved(rootIntent);
LogUtils.i("GpsReceiveService", "应用窗口被移除,前台服务继续运行");
}
@Override
public void onDestroy() {
stopGpsLocationUpdates();
@@ -9,7 +9,9 @@
<cc.winboll.studio.libaes.views.ASupportToolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/toolbar"/>
android:id="@+id/toolbar"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
<cc.winboll.studio.libappbase.views.AboutView
android:layout_width="match_parent"
@@ -9,4 +9,7 @@
<color name="toolbarBackgroundColor">#1E3A5F</color>
<color name="debugTextColor">#00E676</color>
<color name="colorTextBackgound">#121212</color>
<color name="splashBackground">#1565C0</color>
<color name="splashTitleText">#FFFFFF</color>
<color name="splashSubtitleText">#B3FFFFFF</color>
</resources>
+4 -4
View File
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Mon Jun 29 11:28:11 HKT 2026
stageCount=18
#Sat Jul 11 20:07:00 HKT 2026
stageCount=19
libraryProject=libaes
baseVersion=15.20
publishVersion=15.20.17
publishVersion=15.20.18
buildCount=0
baseBetaVersion=15.20.18
baseBetaVersion=15.20.19
+1 -1
View File
@@ -25,7 +25,7 @@
<item name="mainWindowTextColor">@color/mainWindowTextColor</item>
<item name="mainWindowDarkBackgroundColor">@color/mainWindowBackgroundColor</item>
<item name="mainWindowDarkTextColor">@color/mainWindowTextColor</item>
<item name="android:statusBarColor">@color/toolbarBackgroundColor</item>
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
<item name="aToolbar">@style/AESAToolbar</item>
<item name="aSupportToolbar">@style/AESASupportToolbar</item>
+1 -1
View File
@@ -25,7 +25,7 @@
<item name="mainWindowTextColor">@color/mainWindowTextColor</item>
<item name="mainWindowDarkBackgroundColor">@color/mainWindowBackgroundColor</item>
<item name="mainWindowDarkTextColor">@color/mainWindowTextColor</item>
<item name="android:statusBarColor">@color/toolbarBackgroundColor</item>
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
<item name="aToolbar">@style/AESAToolbar</item>
<item name="aSupportToolbar">@style/AESASupportToolbar</item>
+1 -1
View File
@@ -1,3 +1,3 @@
// ByTheWay 项目编译设置
include ':bytheway'
rootProject.name = "bytheway"
rootProject.name = "bytheway"
+1 -1
View File
@@ -4,4 +4,4 @@
// ByTheWay 项目编译设置
//include ':bytheway'
//rootProject.name = "bytheway"
//rootProject.name = "bytheway"