4 Commits

Author SHA1 Message Date
Zhanghu
15cbcc206e 小改动 2026-03-26 11:12:13 +08:00
Zhanghu
e8eff1d512 * 美化启动画面
* 清除冗余代码
2026-03-16 14:38:20 +08:00
Zhanghu
5f1757fed4 #6 服务器不能访问后,长时间下来会闪退 2026-03-16 14:19:45 +08:00
Zhanghu
fcfc964fb6 changelog 2026-03-13 13:01:28 +08:00
19 changed files with 75 additions and 263 deletions

View File

@@ -109,6 +109,7 @@ dependencies {
implementation libs.utilcodex
implementation libs.dialogx
implementation libs.okhttp
implementation libs.banner
implementation libs.glide

View File

@@ -9,7 +9,18 @@ author:
2. $ {VERSION_CODE} (去掉空格),会自动替换实际修订号,比如 1.1.4.$ {VERSION_CODE}
-->
### [1.1.0.${VERSION_CODE}] - 2026.3.13
### [1.1.1.35] - 2026.3.16
#### 文件下载
* [dashboardclient_1.1.1.apk](dashboardclient_1.1.1.apk)
#### 更新记录
* 修正达到重试加载链接上限之后闪退的问题
* 美化启动画面
* 清除冗余代码
### [1.1.0.32] - 2026.3.13
#### 文件下载

View File

@@ -19,7 +19,7 @@
android:exported="false"
android:label="@string/title_activity_settings" />
<activity
android:name=".activity.BuildingDashboardActivity"
android:name=".activity.DashboardActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="false"
android:label="@string/title_activity_building_dashboard"
@@ -32,10 +32,6 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activity.GalleryActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="true" />
<receiver
android:name=".BootBroadcastReceiver"

View File

@@ -1,88 +0,0 @@
package cn.ykbox.dashboard.activity;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
//import cn.slackz.signageapi.PlatformFactory;
public class BaseActivity extends AppCompatActivity {
final private String TAG = "BaseActivity";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
hideSystemUI();
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume " + this);
// PlatformFactory.getInstance().hideNavBar(true);
// PlatformFactory.getInstance().setSlideShowNavBar(false);
// PlatformFactory.getInstance().setSlideShowNotificationBar(false);
hideSystemUI();
}
@Override
protected void onPause() {
super.onPause();
showSystemUI();
Log.d(TAG, "onPause " + this);
// PlatformFactory.getInstance().hideNavBar(false);
// PlatformFactory.getInstance().setSlideShowNotificationBar(true);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// if (hasFocus) {
hideSystemUI();
// }
}
protected void hideSystemUI() {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.hide();
}
// Enables regular immersive mode.
// For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
// Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) {
decorView.setSystemUiVisibility(View.GONE);
} else if (Build.VERSION.SDK_INT >= 19) {
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Hide the nav bar and status bar
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
}
}
// Shows the system bars by removing all the flags
// except for the ones that make the content appear under the system bars.
private void showSystemUI() {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
}

View File

@@ -1,7 +1,6 @@
package cn.ykbox.dashboard.activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
@@ -25,28 +24,28 @@ import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.preference.PreferenceManager;
import com.kongzue.dialogx.dialogs.TipDialog;
import com.kongzue.dialogx.dialogs.WaitDialog;
import cn.ykbox.dashboard.alarm.PowerAlarmManager;
import cn.ykbox.dashboard.databinding.ActivityBuildingDashboardBinding;
import cn.ykbox.dashboard.databinding.ActivityDashboardBinding;
import cn.ykbox.dashboard.perferences.PreferenceConfiguration;
import cn.ykbox.dashboard.serial.SerialPortDetector;
public class BuildingDashboardActivity extends FullscreenActivity {
public class DashboardActivity extends FullscreenActivity {
private final static String TAG = "DashboardActivity";
private static final boolean AUTO_HIDE = true;
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
private Context mContext;
private String mainUrl;
private int retryCount = 0;
private static final int MAX_RETRY = 99; // 最大重试次数
private long retryCount = 0;
private static final long MAX_RETRY = Long.MAX_VALUE; // 最大重试次数
private static final int RETRY_DELAY = 60000; // 1分钟 = 60000毫秒
private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener;
private PowerAlarmManager powerAlarmManager;
private ActivityBuildingDashboardBinding binding;
private ActivityDashboardBinding binding;
private ActivityResultLauncher<Intent> settingsLauncher;
private SerialPortDetector detector;
@@ -70,7 +69,7 @@ public class BuildingDashboardActivity extends FullscreenActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
binding = ActivityBuildingDashboardBinding.inflate(getLayoutInflater());
binding = ActivityDashboardBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
super.setViews(binding.webview, binding.fullscreenContentControls);
@@ -181,11 +180,11 @@ public class BuildingDashboardActivity extends FullscreenActivity {
if (progressDialog != null) {
progressDialog.dismiss();
}
Toast.makeText(BuildingDashboardActivity.this,
Toast.makeText(DashboardActivity.this,
"串口检测成功!\n路径: " + portPath,
Toast.LENGTH_LONG).show();
PreferenceConfiguration.setSerialPortPath(BuildingDashboardActivity.this, portPath);
PreferenceConfiguration.setSerialPortPath(DashboardActivity.this, portPath);
});
}
@@ -210,7 +209,7 @@ public class BuildingDashboardActivity extends FullscreenActivity {
* 显示检测失败的对话框
*/
private void showDetectionFailedDialog() {
Toast.makeText(BuildingDashboardActivity.this,
Toast.makeText(DashboardActivity.this,
"未找到有效的串口设备,请检查设备连接后重试。",
Toast.LENGTH_LONG).show();
}
@@ -225,6 +224,7 @@ public class BuildingDashboardActivity extends FullscreenActivity {
retryCount++;
Log.d("WebView", "加载失败将在1分钟后重试 (第" + retryCount + "次重试)");
WaitDialog.dismiss();
// 使用Handler延迟执行重试
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
@@ -237,7 +237,9 @@ public class BuildingDashboardActivity extends FullscreenActivity {
} else {
Log.e("WebView", "重试次数已达上限,加载失败");
// 这里可以显示错误页面或提示用户
showToast("网页加载失败,请检查网络连接");
runOnUiThread(() -> {
TipDialog.show("重新加载失败次数已达上限,请联系管理员。", WaitDialog.TYPE.ERROR, -1);
});
}
}
@@ -302,13 +304,17 @@ public class BuildingDashboardActivity extends FullscreenActivity {
webSettings.setBuiltInZoomControls(false);
binding.webview.setInitialScale(100);
binding.webview.setWebViewClient(new WebViewClient() {
private boolean hasError = false;
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
hasError = false;
if(retryCount <= 0)
WaitDialog.show("正在加载...");
else
WaitDialog.show( "" + retryCount + " 次重试... ");
}
@Override
@@ -337,6 +343,7 @@ public class BuildingDashboardActivity extends FullscreenActivity {
super.onPageFinished(view, url);
if (!hasError) {
retryCount = 0;
WaitDialog.dismiss();
Log.d("WebView", "加载OK");
}
}
@@ -351,7 +358,7 @@ public class BuildingDashboardActivity extends FullscreenActivity {
Log.d(TAG, "Power control preference changed: " + key);
runOnUiThread(() -> {
if (key.equals("k_power_control_mode")) {
int mode = PreferenceConfiguration.getPowerControlMode(BuildingDashboardActivity.this);
int mode = PreferenceConfiguration.getPowerControlMode(DashboardActivity.this);
powerAlarmManager.onModeChanged(mode);
} else {
// 本地时间变更
@@ -368,10 +375,4 @@ public class BuildingDashboardActivity extends FullscreenActivity {
Intent intent = new Intent(this, SettingsActivity.class);
settingsLauncher.launch(intent);
}
private void showToast(String message) {
runOnUiThread(() -> Toast.makeText(mContext,
message,
Toast.LENGTH_SHORT).show());
}
}

View File

@@ -22,10 +22,14 @@ public class FullscreenActivity extends AppCompatActivity {
private static final int UI_ANIMATION_DELAY = 300;
private final Handler mHideHandler = new Handler(Looper.myLooper());
private View mContentView;
private View mControlsView;
private final Runnable mHidePart2Runnable = new Runnable() {
@SuppressLint("InlinedApi")
@Override
public void run() {
if(mContentView == null)
return;
// Delayed removal of status and navigation bar
if (Build.VERSION.SDK_INT >= 30) {
mContentView.getWindowInsetsController().hide(
@@ -43,7 +47,6 @@ public class FullscreenActivity extends AppCompatActivity {
}
}
};
private View mControlsView;
private final Runnable mShowPart2Runnable = new Runnable() {
@Override
public void run() {
@@ -52,6 +55,8 @@ public class FullscreenActivity extends AppCompatActivity {
if (actionBar != null) {
actionBar.show();
}
if(mControlsView != null)
mControlsView.setVisibility(View.VISIBLE);
}
};
@@ -76,9 +81,8 @@ public class FullscreenActivity extends AppCompatActivity {
// }
// });
mContentView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if(mContentView != null) {
mContentView.setOnTouchListener((view, motionEvent) -> {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
toggle();
@@ -90,9 +94,9 @@ public class FullscreenActivity extends AppCompatActivity {
break;
}
return false;
}
});
}
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
@@ -120,6 +124,7 @@ public class FullscreenActivity extends AppCompatActivity {
if (actionBar != null) {
actionBar.hide();
}
if(mControlsView != null)
mControlsView.setVisibility(View.GONE);
mVisible = false;
@@ -130,6 +135,7 @@ public class FullscreenActivity extends AppCompatActivity {
private void show() {
// Show the system bar
if(mContentView != null) {
if (Build.VERSION.SDK_INT >= 30) {
mContentView.getWindowInsetsController().show(
WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
@@ -137,6 +143,7 @@ public class FullscreenActivity extends AppCompatActivity {
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
}
}
mVisible = true;
// Schedule a runnable to display UI elements after a delay

View File

@@ -1,75 +0,0 @@
package cn.ykbox.dashboard.activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
import com.blankj.utilcode.util.ScreenUtils;
import com.bumptech.glide.Glide;
import com.youth.banner.adapter.BannerImageAdapter;
import com.youth.banner.holder.BannerImageHolder;
import com.youth.banner.indicator.CircleIndicator;
import cn.ykbox.dashboard.data.BannerBean;
import cn.ykbox.dashboard.databinding.ActivityGalleryBinding;
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*/
public class GalleryActivity extends BaseActivity {
private ActivityGalleryBinding binding;
private Context mContext;
private Handler mHandler = new Handler();
private final static int CON_COUNTS = 6;// 连续点击次数
private final static long CON_DURATION = 1500;// 连续点击最小间隔时间
private static long[] CON_Hits = new long[CON_COUNTS];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
binding = ActivityGalleryBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.banner.setAdapter(new BannerImageAdapter<BannerBean>(BannerBean.getTestData()) {
@Override
public void onBindView(BannerImageHolder holder, BannerBean data, int position, int size) {
Log.d("fullshow", "load" + data.imageRes);
Glide.with(holder.itemView)
.load(data.imageRes)
.into(holder.imageView);
}
})
.addBannerLifecycleObserver(this)//添加生命周期观察者
.setIndicator(new CircleIndicator(this))
.setLoopTime(5000);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int h = ScreenUtils.getScreenHeight();
if(ev.getActionMasked() == MotionEvent.ACTION_DOWN && ev.getX() < 100 && ev.getY() > h-100)
finishByHits();
return super.dispatchTouchEvent(ev);
}
public void finishByHits() {
//每次点击时,数组向前移动一位
System.arraycopy(CON_Hits, 1, CON_Hits, 0, CON_Hits.length - 1);
//为数组最后一位赋值
CON_Hits[CON_Hits.length - 1] = SystemClock.uptimeMillis();
if (CON_Hits[0] >= (SystemClock.uptimeMillis() - CON_DURATION)) {
CON_Hits = new long[CON_COUNTS];//重新初始化数组
finish();
}
}
}

View File

@@ -5,34 +5,29 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import cn.ykbox.dashboard.databinding.ActivityDashboardBinding;
import cn.ykbox.dashboard.databinding.ActivityStartBinding;
import cn.ykbox.dashboard.R;
public class StartActivity extends AppCompatActivity {
public class StartActivity extends FullscreenActivity {
private Context mContext;
private ActivityStartBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
binding = ActivityStartBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
super.setViews(binding.flContent, null);
super.onCreate(savedInstanceState);
mContext = this;
EdgeToEdge.enable(this);
setContentView(R.layout.activity_start);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent myIntent = new Intent(mContext, BuildingDashboardActivity.class);
Intent myIntent = new Intent(mContext, DashboardActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(myIntent);

View File

@@ -1,36 +0,0 @@
package cn.ykbox.dashboard.data;
import java.util.ArrayList;
import java.util.List;
import cn.ykbox.dashboard.R;
public class BannerBean {
public Integer imageRes;
public String imageUrl;
public String title;
public int viewType;
public BannerBean(Integer imageRes, String title, int viewType) {
this.imageRes = imageRes;
this.title = title;
this.viewType = viewType;
}
public BannerBean(String imageUrl, String title, int viewType) {
this.imageUrl = imageUrl;
this.title = title;
this.viewType = viewType;
}
public static List<BannerBean> getTestData() {
List<BannerBean> list = new ArrayList<>();
list.add(new BannerBean(R.drawable.image1, "第3代无线智能中控", 1));
list.add(new BannerBean(R.drawable.image2, "智慧班牌", 3));
list.add(new BannerBean(R.drawable.image3, "无线话筒", 3));
list.add(new BannerBean(R.drawable.image4, "可移动式智能讲桌", 1));
list.add(new BannerBean(R.drawable.image5, "TD2+智慧屏集成讲桌", 1));
list.add(new BannerBean(R.drawable.image6, "TD5+智慧屏集成讲台", 3));
return list;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 741 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 385 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 574 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 631 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 671 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 KiB

View File

@@ -5,7 +5,7 @@
android:layout_height="match_parent"
android:background="?attr/fullscreenBackgroundColor"
android:theme="@style/ThemeOverlay.DashBoardClient.FullscreenContainer"
tools:context=".BuildingDashboardActivity">
tools:context=".activity.DashboardActivity">
<!-- The primary full-screen view. This can be replaced with whatever view
is needed to present your content, e.g. VideoView, SurfaceView,

View File

@@ -5,14 +5,12 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".StartActivity">
android:background="@drawable/splash"
tools:context=".activity.StartActivity">
<TextView
<FrameLayout
android:id="@+id/fl_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="启动中,请稍后..."
android:textSize="30sp">
</TextView>
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,3 +1,5 @@
**注意:本项目已停止更新,可完全由 [CastBox](http://code.slackz.cn/ykbox/CastBox) 替代**
# Dashboard Client
## 1. 简介