From e01fd86961540b07946df3a507adf26b020412d6 Mon Sep 17 00:00:00 2001
From: peng <704047449@qq.com>
Date: Wed, 17 Sep 2025 14:42:17 +0800
Subject: [PATCH] =?UTF-8?q?refactor(notification):=20=E5=B0=86=E9=80=9A?=
=?UTF-8?q?=E7=9F=A5=E6=98=BE=E7=A4=BA=E4=BB=8EActivity=E6=94=B9=E4=B8=BAD?=
=?UTF-8?q?ialogFragment?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
重构通知显示机制,使用DialogFragment替代Activity,提升性能和用户体验:
1. 删除CommonNotificationActivity及相关资源
2. 新增NotificationDialogFragment实现全屏弹窗
3. 更新NotificationManager适配新机制
4. 添加全屏样式和布局文件
5. 优化系统UI隐藏逻辑
---
.../project-interpretation-1758003461.md | 0
.../project-interpretation-1758003538.md | 0
.qoder/quests/project-interpretation.md | 0
app/src/main/AndroidManifest.xml | 6 +-
.../com/ismart/ib86/app/MainActivity.java | 22 +-
.../CommonNotificationActivity.java | 228 -------------
.../NotificationDialogFragment.java | 321 ++++++++++++++++++
.../notification/NotificationManager.java | 74 ++--
.../feature/network/NetworkStateManager.java | 5 +-
.../network/NetworkStateManagerComparison.md | 58 ----
.../network/SimpleNetworkStateManager.java | 213 ------------
.../feature/network/TestWiFiScanResult.java | 62 ----
.../network/TestWiFiScanResultWithBSSID.java | 69 ----
.../main/res/layout/dialog_notification.xml | 25 ++
app/src/main/res/values/styles.xml | 12 +
app/src/main/res/values/themes.xml | 4 +-
16 files changed, 417 insertions(+), 682 deletions(-)
create mode 100644 .qoder/quests/project-interpretation-1758003461.md
create mode 100644 .qoder/quests/project-interpretation-1758003538.md
create mode 100644 .qoder/quests/project-interpretation.md
delete mode 100644 app/src/main/java/com/ismart/ib86/common/notification/CommonNotificationActivity.java
create mode 100644 app/src/main/java/com/ismart/ib86/common/notification/NotificationDialogFragment.java
delete mode 100644 app/src/main/java/com/ismart/ib86/feature/network/NetworkStateManagerComparison.md
delete mode 100644 app/src/main/java/com/ismart/ib86/feature/network/SimpleNetworkStateManager.java
delete mode 100644 app/src/main/java/com/ismart/ib86/feature/network/TestWiFiScanResult.java
delete mode 100644 app/src/main/java/com/ismart/ib86/feature/network/TestWiFiScanResultWithBSSID.java
create mode 100644 app/src/main/res/layout/dialog_notification.xml
create mode 100644 app/src/main/res/values/styles.xml
diff --git a/.qoder/quests/project-interpretation-1758003461.md b/.qoder/quests/project-interpretation-1758003461.md
new file mode 100644
index 0000000..e69de29
diff --git a/.qoder/quests/project-interpretation-1758003538.md b/.qoder/quests/project-interpretation-1758003538.md
new file mode 100644
index 0000000..e69de29
diff --git a/.qoder/quests/project-interpretation.md b/.qoder/quests/project-interpretation.md
new file mode 100644
index 0000000..e69de29
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 629a22b..01d83c8 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -61,11 +61,7 @@
android:name="com.ismart.ib86.feature.network.TestBSSIDActivity"
android:exported="true" />
-
-
+
= android.os.Build.VERSION_CODES.KITKAT) {
- getWindow().getDecorView().setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_FULLSCREEN
- | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
- }
-
- initializeViews();
- handleIntent(getIntent());
- setupCloseReceiver();
- playNotificationSound();
- }
-
- private void initializeViews() {
- ivIcon = findViewById(R.id.iv_icon);
- tvMessage = findViewById(R.id.tv_message);
- }
-
- private void handleIntent(Intent intent) {
- if (intent != null) {
- String message = intent.getStringExtra(EXTRA_MESSAGE);
- int iconResId = intent.getIntExtra(EXTRA_ICON, android.R.drawable.ic_dialog_alert); // 默认使用系统警告图标
- int durationSeconds = intent.getIntExtra(EXTRA_DURATION, 5); // 默认5秒
- notificationType = intent.getStringExtra(EXTRA_TYPE);
- soundPath = intent.getStringExtra(EXTRA_SOUND_PATH);
-
- Log.d(TAG, "Received intent with duration: " + durationSeconds + " seconds");
-
- if (message != null) {
- tvMessage.setText(message);
- }
-
- if (iconResId != 0) {
- ivIcon.setImageResource(iconResId);
- }
-
- // 设置自动关闭
- if (durationSeconds > 0) {
- handler = new Handler();
- finishRunnable = () -> {
- Log.d(TAG, "Auto closing notification activity after " + durationSeconds + " seconds");
- finish();
- };
- handler.postDelayed(finishRunnable, durationSeconds * 1000L);
- Log.d(TAG, "Scheduled auto close in " + durationSeconds + " seconds");
- } else {
- Log.d(TAG, "Duration is 0 or negative, no auto close scheduled");
- }
- } else {
- Log.w(TAG, "Received null intent");
- }
- }
-
- private void setupCloseReceiver() {
- closeReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (ACTION_CLOSE_ACTIVITY.equals(intent.getAction())) {
- Log.d(TAG, "Received close activity broadcast");
- finish();
- }
- }
- };
-
- IntentFilter filter = new IntentFilter(ACTION_CLOSE_ACTIVITY);
- registerReceiver(closeReceiver, filter);
- }
-
- private void playNotificationSound() {
- try {
- // 如果提供了自定义音效路径,则使用自定义音效
- if (soundPath != null && !soundPath.isEmpty()) {
- if (soundPath.startsWith("android.resource://")) {
- // 处理res/raw资源
- Uri uri = Uri.parse(soundPath);
- mediaPlayer = MediaPlayer.create(this, uri);
- } else {
- // 处理文件路径
- mediaPlayer = new MediaPlayer();
- mediaPlayer.setDataSource(soundPath);
- mediaPlayer.prepare();
- }
- } else if (notificationType != null) {
- // 根据通知类型使用对应的默认音效
- switch (notificationType) {
- case "NETWORK_LOST":
- mediaPlayer = MediaPlayer.create(this, R.raw.network_lost_notification);
- break;
- case "NETWORK_CONFIG":
- mediaPlayer = MediaPlayer.create(this, R.raw.network_config_notification);
- break;
- case "BATTERY_LOW":
- mediaPlayer = MediaPlayer.create(this, R.raw.battery_low_notification);
- break;
- default:
- mediaPlayer = MediaPlayer.create(this, R.raw.default_notification);
- break;
- }
- } else {
- // 使用系统默认提示音
-// mediaPlayer = MediaPlayer.create(this, android.R.raw.notification_sound);
- }
-
- if (mediaPlayer != null) {
- mediaPlayer.setOnCompletionListener(mp -> {
- try {
- // 在播放完成后释放MediaPlayer资源
- mp.release();
- // 将mediaPlayer引用置为null,避免在onDestroy中重复释放
- mediaPlayer = null;
- } catch (Exception e) {
- Log.e(TAG, "Error releasing media player", e);
- }
- });
- mediaPlayer.start();
- }
- } catch (Exception e) {
- Log.e(TAG, "Failed to play notification sound", e);
- }
- }
-
- @Override
- protected void onDestroy() {
- Log.d(TAG, "onDestroy called");
- super.onDestroy();
-
- // 通知NotificationManager重置显示状态
- Intent intent = new Intent(ACTION_NOTIFICATION_CLOSED);
- sendBroadcast(intent);
-
- // 清理资源
- if (handler != null && finishRunnable != null) {
- Log.d(TAG, "Removing callbacks from handler");
- handler.removeCallbacks(finishRunnable);
- }
-
- if (mediaPlayer != null) {
- try {
- // 在调用isPlaying()之前检查MediaPlayer状态,避免IllegalStateException
- if (mediaPlayer.isPlaying()) {
- Log.d(TAG, "Stopping media player");
- mediaPlayer.stop();
- }
- } catch (IllegalStateException e) {
- // MediaPlayer可能已经处于无效状态,忽略这个异常
- Log.w(TAG, "MediaPlayer is in invalid state, skipping stop()", e);
- } catch (Exception e) {
- Log.e(TAG, "Error stopping media player", e);
- }
-
- try {
- Log.d(TAG, "Releasing media player");
- mediaPlayer.release();
- mediaPlayer = null;
- } catch (Exception e) {
- Log.e(TAG, "Error releasing media player", e);
- }
- }
-
- if (closeReceiver != null) {
- try {
- Log.d(TAG, "Unregistering receiver");
- unregisterReceiver(closeReceiver);
- } catch (Exception e) {
- Log.e(TAG, "Error unregistering receiver", e);
- }
- closeReceiver = null;
- }
-
- Log.d(TAG, "onDestroy completed");
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/ismart/ib86/common/notification/NotificationDialogFragment.java b/app/src/main/java/com/ismart/ib86/common/notification/NotificationDialogFragment.java
new file mode 100644
index 0000000..0967b70
--- /dev/null
+++ b/app/src/main/java/com/ismart/ib86/common/notification/NotificationDialogFragment.java
@@ -0,0 +1,321 @@
+package com.ismart.ib86.common.notification;
+
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.ismart.ib86.app.R;
+
+/**
+ * 通知弹窗DialogFragment
+ */
+public class NotificationDialogFragment extends DialogFragment {
+ public static final String ACTION_NOTIFICATION_CLOSED = "com.ismart.ib86.notification.NOTIFICATION_CLOSED";
+ public static final String ACTION_CLOSE_DIALOG = "com.ismart.ib86.notification.CLOSE_DIALOG";
+
+ private static final String ARG_MESSAGE = "message";
+ private static final String ARG_ICON_RES_ID = "icon_res_id";
+ private static final String ARG_DURATION = "duration";
+ private static final String ARG_TYPE = "type";
+ private static final String ARG_SOUND_PATH = "sound_path";
+ private static final String TAG = "NotificationDialog";
+
+ private String message;
+ private int iconResId;
+ private int durationSeconds;
+ private String notificationType;
+ private String soundPath;
+ private MediaPlayer mediaPlayer;
+ private Handler handler;
+ private Runnable dismissRunnable;
+
+ public static NotificationDialogFragment newInstance(String message, int iconResId,
+ int durationSeconds, String type, String soundPath) {
+ NotificationDialogFragment fragment = new NotificationDialogFragment();
+ Bundle args = new Bundle();
+ args.putString(ARG_MESSAGE, message);
+ args.putInt(ARG_ICON_RES_ID, iconResId);
+ args.putInt(ARG_DURATION, durationSeconds);
+ args.putString(ARG_TYPE, type);
+ args.putString(ARG_SOUND_PATH, soundPath);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setStyle(DialogFragment.STYLE_NORMAL, R.style.FullScreenDialog);
+
+ // 设置DialogFragment的窗口标志以隐藏系统UI
+ setShowsDialog(true);
+
+ if (getArguments() != null) {
+ message = getArguments().getString(ARG_MESSAGE);
+ iconResId = getArguments().getInt(ARG_ICON_RES_ID);
+ durationSeconds = getArguments().getInt(ARG_DURATION);
+ notificationType = getArguments().getString(ARG_TYPE);
+ soundPath = getArguments().getString(ARG_SOUND_PATH);
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Dialog dialog = super.onCreateDialog(savedInstanceState);
+ if (dialog.getWindow() != null) {
+ Window window = dialog.getWindow();
+ window.requestFeature(Window.FEATURE_NO_TITLE);
+
+ // 添加窗口标志以确保全屏并隐藏系统UI
+ window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
+ window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
+ window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); // 防止导航栏显示
+
+ // 设置窗口布局参数
+ WindowManager.LayoutParams params = window.getAttributes();
+ params.width = WindowManager.LayoutParams.MATCH_PARENT;
+ params.height = WindowManager.LayoutParams.MATCH_PARENT;
+ window.setAttributes(params);
+ }
+ return dialog;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.dialog_notification, container, false);
+ return view;
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ // 设置Dialog为全屏并隐藏系统UI
+ Dialog dialog = getDialog();
+ if (dialog != null && dialog.getWindow() != null) {
+ Window window = dialog.getWindow();
+ window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+
+ // 设置窗口标志以确保全屏
+ window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
+ window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
+ window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); // 防止导航栏显示
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ window.getDecorView().setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_IMMERSIVE); // 添加额外的沉浸模式标志
+ }
+
+ // 延迟设置焦点以确保系统UI正确隐藏
+ window.getDecorView().post(() -> {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ window.getDecorView().setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_IMMERSIVE);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ // 确保在恢复时系统UI状态正确
+ Dialog dialog = getDialog();
+ if (dialog != null && dialog.getWindow() != null) {
+ Window window = dialog.getWindow();
+
+ // 设置窗口标志以确保全屏
+ window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
+ window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
+ window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); // 恢复焦点
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ window.getDecorView().setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_IMMERSIVE);
+ }
+
+ // 延迟设置焦点以确保系统UI正确隐藏
+ window.getDecorView().post(() -> {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ window.getDecorView().setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_IMMERSIVE);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ initializeViews(view);
+ playNotificationSound();
+
+ // 设置自动关闭
+ if (durationSeconds > 0) {
+ handler = new Handler();
+ dismissRunnable = () -> {
+ if (getDialog() != null && getDialog().isShowing()) {
+ dismissAllowingStateLoss();
+ }
+ };
+ handler.postDelayed(dismissRunnable, durationSeconds * 1000L);
+ }
+ }
+
+ private void initializeViews(View view) {
+ ImageView ivIcon = view.findViewById(R.id.iv_icon);
+ TextView tvMessage = view.findViewById(R.id.tv_message);
+
+ if (message != null) {
+ tvMessage.setText(message);
+ }
+
+ if (iconResId != 0) {
+ ivIcon.setImageResource(iconResId);
+ }
+ }
+
+ private void playNotificationSound() {
+ try {
+ // 如果提供了自定义音效路径,则使用自定义音效
+ if (soundPath != null && !soundPath.isEmpty() && getActivity() != null) {
+ if (soundPath.startsWith("android.resource://")) {
+ // 处理res/raw资源
+ Uri uri = Uri.parse(soundPath);
+ mediaPlayer = MediaPlayer.create(getActivity(), uri);
+ } else {
+ // 处理文件路径
+ mediaPlayer = new MediaPlayer();
+ mediaPlayer.setDataSource(soundPath);
+ mediaPlayer.prepare();
+ }
+ } else if (notificationType != null && getActivity() != null) {
+ // 根据通知类型使用对应的默认音效
+ switch (notificationType) {
+ case "NETWORK_LOST":
+ mediaPlayer = MediaPlayer.create(getActivity(), R.raw.network_lost_notification);
+ break;
+ case "NETWORK_CONFIG":
+ mediaPlayer = MediaPlayer.create(getActivity(), R.raw.network_config_notification);
+ break;
+ case "BATTERY_LOW":
+ mediaPlayer = MediaPlayer.create(getActivity(), R.raw.battery_low_notification);
+ break;
+ default:
+ mediaPlayer = MediaPlayer.create(getActivity(), R.raw.default_notification);
+ break;
+ }
+ }
+
+ if (mediaPlayer != null) {
+ mediaPlayer.setOnCompletionListener(mp -> {
+ try {
+ // 在播放完成后释放MediaPlayer资源
+ mp.release();
+ // 将mediaPlayer引用置为null,避免在onDestroy中重复释放
+ mediaPlayer = null;
+ } catch (Exception e) {
+ Log.e(TAG, "Error releasing media player", e);
+ }
+ });
+ mediaPlayer.start();
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to play notification sound", e);
+ }
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+
+ // 在销毁视图时确保系统UI状态正确
+ if (getActivity() != null && getActivity().getWindow() != null) {
+ // 恢复Activity的系统UI状态
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ getActivity().getWindow().getDecorView().setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+ }
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ // 通知NotificationManager重置显示状态
+ if (getActivity() != null) {
+ android.content.Intent intent = new android.content.Intent(ACTION_NOTIFICATION_CLOSED);
+ getActivity().sendBroadcast(intent);
+ }
+
+ // 清理资源
+ if (handler != null && dismissRunnable != null) {
+ handler.removeCallbacks(dismissRunnable);
+ }
+
+ if (mediaPlayer != null) {
+ try {
+ // 在调用isPlaying()之前检查MediaPlayer状态,避免IllegalStateException
+ if (mediaPlayer.isPlaying()) {
+ mediaPlayer.stop();
+ }
+ } catch (IllegalStateException e) {
+ // MediaPlayer可能已经处于无效状态,忽略这个异常
+ Log.w(TAG, "MediaPlayer is in invalid state, skipping stop()", e);
+ } catch (Exception e) {
+ Log.e(TAG, "Error stopping media player", e);
+ }
+
+ try {
+ mediaPlayer.release();
+ mediaPlayer = null;
+ } catch (Exception e) {
+ Log.e(TAG, "Error releasing media player", e);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ismart/ib86/common/notification/NotificationManager.java b/app/src/main/java/com/ismart/ib86/common/notification/NotificationManager.java
index 4854de7..842e201 100644
--- a/app/src/main/java/com/ismart/ib86/common/notification/NotificationManager.java
+++ b/app/src/main/java/com/ismart/ib86/common/notification/NotificationManager.java
@@ -1,6 +1,7 @@
package com.ismart.ib86.common.notification;
import android.app.Activity;
+import android.app.FragmentManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -12,6 +13,8 @@ import android.util.Log;
import java.util.LinkedList;
import java.util.Queue;
+import com.ismart.ib86.common.notification.NotificationDialogFragment;
+
/**
* 通知管理器
* 专门负责通知的显示和隐藏
@@ -19,8 +22,8 @@ import java.util.Queue;
public class NotificationManager {
private static final String TAG = "NotificationManager";
private Context context;
- private Activity activityContext; // 保存Activity上下文用于启动Activity
- private boolean isActivityShowing = false;
+ private Activity activityContext; // 保存Activity上下文用于启动DialogFragment
+ private boolean isDialogShowing = false;
private NotificationClosedReceiver notificationClosedReceiver;
private NotificationRequest currentNotification; // 当前正在显示的通知
private Queue notificationQueue = new LinkedList<>(); // 通知队列
@@ -66,7 +69,7 @@ public class NotificationManager {
NotificationRequest request = new NotificationRequest(type, message, iconResId, durationSeconds, soundPath, priority);
// 如果当前没有通知在显示,则直接显示
- if (!isActivityShowing) {
+ if (!isDialogShowing) {
displayNotification(request);
} else {
// 如果有通知在显示,检查优先级
@@ -94,74 +97,75 @@ public class NotificationManager {
private void displayNotification(NotificationRequest request) {
Log.d(TAG, "Displaying notification: " + request);
- if (isActivityShowing) {
- Log.d(TAG, "Notification activity is already showing");
+ if (isDialogShowing) {
+ Log.d(TAG, "Notification dialog is already showing");
return;
}
// 检查是否有可用的Activity上下文
if (activityContext == null) {
- Log.w(TAG, "Activity context is null, cannot show activity");
+ Log.w(TAG, "Activity context is null, cannot show dialog");
return;
}
// 检查Activity是否有效
if (activityContext.isFinishing() || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activityContext.isDestroyed())) {
- Log.w(TAG, "Activity is not valid, cannot show activity");
+ Log.w(TAG, "Activity is not valid, cannot show dialog");
return;
}
activityContext.runOnUiThread(() -> {
try {
- if (isActivityShowing) {
- Log.d(TAG, "Notification activity is already showing");
+ if (isDialogShowing) {
+ Log.d(TAG, "Notification dialog is already showing");
return;
}
- Intent intent = new Intent(activityContext, CommonNotificationActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.putExtra(CommonNotificationActivity.EXTRA_MESSAGE, request.getMessage());
- intent.putExtra(CommonNotificationActivity.EXTRA_ICON, request.getIconResId());
- intent.putExtra(CommonNotificationActivity.EXTRA_DURATION, request.getDurationSeconds());
- intent.putExtra(CommonNotificationActivity.EXTRA_TYPE, request.getType().name());
- if (request.getSoundPath() != null) {
- intent.putExtra(CommonNotificationActivity.EXTRA_SOUND_PATH, request.getSoundPath());
- }
- activityContext.startActivity(intent);
- isActivityShowing = true;
+ // 创建并显示NotificationDialogFragment
+ NotificationDialogFragment dialogFragment = NotificationDialogFragment.newInstance(
+ request.getMessage(),
+ request.getIconResId(),
+ request.getDurationSeconds(),
+ request.getType().name(),
+ request.getSoundPath()
+ );
+
+ FragmentManager fragmentManager = activityContext.getFragmentManager();
+ dialogFragment.show(fragmentManager, "NotificationDialogFragment");
+ isDialogShowing = true;
currentNotification = request;
- Log.d(TAG, "Notification activity shown for " + request.getDurationSeconds() + " seconds, type: " + request.getType() + ", priority: " + request.getPriority());
+ Log.d(TAG, "Notification dialog shown for " + request.getDurationSeconds() + " seconds, type: " + request.getType() + ", priority: " + request.getPriority());
} catch (Exception e) {
- Log.e(TAG, "Failed to show notification activity", e);
+ Log.e(TAG, "Failed to show notification dialog", e);
}
});
}
public void hideNotification() {
- Log.d(TAG, "hideNotification called, isActivityShowing: " + isActivityShowing);
- // 通过发送广播通知CommonNotificationActivity关闭自身
- if (isActivityShowing) {
+ Log.d(TAG, "hideNotification called, isDialogShowing: " + isDialogShowing);
+ // 通过发送广播通知NotificationDialogFragment关闭自身
+ if (isDialogShowing) {
try {
- Intent intent = new Intent(CommonNotificationActivity.ACTION_CLOSE_ACTIVITY);
+ Intent intent = new Intent(NotificationDialogFragment.ACTION_CLOSE_DIALOG);
context.sendBroadcast(intent);
- isActivityShowing = false;
+ isDialogShowing = false;
currentNotification = null;
- Log.d(TAG, "Notification activity hidden");
+ Log.d(TAG, "Notification dialog hidden");
} catch (Exception e) {
- Log.e(TAG, "Failed to hide notification activity", e);
+ Log.e(TAG, "Failed to hide notification dialog", e);
}
} else {
- Log.d(TAG, "Notification activity is not showing, nothing to hide");
+ Log.d(TAG, "Notification dialog is not showing, nothing to hide");
}
}
- public boolean isActivityShowing() {
- return isActivityShowing;
+ public boolean isDialogShowing() {
+ return isDialogShowing;
}
// 添加一个方法用于重置显示状态
public void resetShowingState() {
- isActivityShowing = false;
+ isDialogShowing = false;
currentNotification = null;
processNextNotification();
}
@@ -193,7 +197,7 @@ public class NotificationManager {
private void registerNotificationClosedReceiver() {
notificationClosedReceiver = new NotificationClosedReceiver();
- IntentFilter filter = new IntentFilter(CommonNotificationActivity.ACTION_NOTIFICATION_CLOSED);
+ IntentFilter filter = new IntentFilter(NotificationDialogFragment.ACTION_NOTIFICATION_CLOSED);
context.registerReceiver(notificationClosedReceiver, filter);
}
@@ -211,7 +215,7 @@ public class NotificationManager {
private class NotificationClosedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- if (CommonNotificationActivity.ACTION_NOTIFICATION_CLOSED.equals(intent.getAction())) {
+ if (NotificationDialogFragment.ACTION_NOTIFICATION_CLOSED.equals(intent.getAction())) {
Log.d(TAG, "Received notification closed broadcast, resetting showing state");
resetShowingState();
}
diff --git a/app/src/main/java/com/ismart/ib86/feature/network/NetworkStateManager.java b/app/src/main/java/com/ismart/ib86/feature/network/NetworkStateManager.java
index 82f6807..8af55cf 100644
--- a/app/src/main/java/com/ismart/ib86/feature/network/NetworkStateManager.java
+++ b/app/src/main/java/com/ismart/ib86/feature/network/NetworkStateManager.java
@@ -7,7 +7,6 @@ import android.os.Build;
import android.util.Log;
import com.ismart.ib86.app.R;
-import com.ismart.ib86.common.notification.CommonNotificationActivity;
import com.ismart.ib86.common.notification.NotificationType;
import com.ismart.ib86.common.notification.NotificationManager;
import com.ismart.ib86.common.notification.NotificationPriority;
@@ -121,8 +120,8 @@ public class NetworkStateManager {
}
}
- public boolean isActivityShowing() {
- return notificationManager != null ? notificationManager.isActivityShowing() : false;
+ public boolean isDialogShowing() {
+ return notificationManager != null ? notificationManager.isDialogShowing() : false;
}
public NetworkState getCurrentNetworkState() {
diff --git a/app/src/main/java/com/ismart/ib86/feature/network/NetworkStateManagerComparison.md b/app/src/main/java/com/ismart/ib86/feature/network/NetworkStateManagerComparison.md
deleted file mode 100644
index 96844a9..0000000
--- a/app/src/main/java/com/ismart/ib86/feature/network/NetworkStateManagerComparison.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# NetworkStateManager 设计方案比较
-
-## 方案一:分离式设计(当前实现)
-
-### 组件结构
-1. **NetworkStateMonitor** - 负责网络状态监听
-2. **NetworkStateManager** - 负责状态管理和通知显示
-
-### 优点
-1. **职责分离**:网络监听和状态管理完全分离
-2. **高内聚低耦合**:每个类只负责单一职责
-3. **可复用性**:NetworkStateMonitor可以被其他不涉及通知显示的组件复用
-4. **可测试性**:可以独立测试网络监听功能
-5. **可扩展性**:可以在NetworkStateManager中添加更多的状态管理逻辑
-
-### 缺点
-1. **复杂性**:增加了类的数量和层级
-2. **间接性**:需要通过多个类来完成完整的功能
-
-## 方案二:合并式设计(简化版本)
-
-### 组件结构
-1. **SimpleNetworkStateManager** - 同时负责网络状态监听和状态管理
-
-### 优点
-1. **简洁性**:只有一个类负责所有功能
-2. **直接性**:减少了组件间的依赖关系
-3. **易理解**:代码结构更简单,易于理解
-
-### 缺点
-1. **职责混合**:一个类承担了多个职责
-2. **可复用性差**:网络监听功能难以被其他组件复用
-3. **可测试性差**:难以独立测试网络监听功能
-4. **扩展性差**:添加新功能时可能需要修改现有代码
-
-## 推荐方案
-
-### 如果项目需求简单且稳定
-推荐使用**方案二(合并式设计)**,因为:
-- 代码更简洁,易于维护
-- 减少了不必要的复杂性
-- 满足当前需求即可
-
-### 如果项目需求复杂或多变
-推荐使用**方案一(分离式设计)**,因为:
-- 更好的代码组织和架构
-- 更高的可扩展性和可维护性
-- 符合软件设计原则(单一职责、开闭原则等)
-
-## 当前实现的选择
-
-当前实现采用了方案一(分离式设计),主要考虑:
-1. 项目可能需要扩展更多的网络状态管理功能
-2. 网络监听功能可能在其他地方被复用
-3. 遵循了良好的软件设计原则
-4. 便于单元测试和维护
-
-如果确定项目只需要基本的网络状态监听和通知功能,可以考虑切换到方案二以简化代码结构。
\ No newline at end of file
diff --git a/app/src/main/java/com/ismart/ib86/feature/network/SimpleNetworkStateManager.java b/app/src/main/java/com/ismart/ib86/feature/network/SimpleNetworkStateManager.java
deleted file mode 100644
index 5a7731e..0000000
--- a/app/src/main/java/com/ismart/ib86/feature/network/SimpleNetworkStateManager.java
+++ /dev/null
@@ -1,213 +0,0 @@
-package com.ismart.ib86.feature.network;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.os.Build;
-import android.util.Log;
-import com.ismart.ib86.common.notification.NotificationType;
-import com.ismart.ib86.common.notification.CommonNotificationActivity;
-
-/**
- * 简化版网络状态管理器
- * 将网络监听和状态管理合并为一个类
- */
-public class SimpleNetworkStateManager {
- private static final String TAG = "SimpleNetworkStateManager";
- private Context context;
- private ConnectivityManager connectivityManager;
- private ConnectivityManager.NetworkCallback networkCallback;
- private NetworkState currentState;
- private boolean isActivityShowing = false;
-
- public SimpleNetworkStateManager(Context context) {
- this.context = context.getApplicationContext();
- this.connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- this.currentState = NetworkState.NO_NETWORK;
- initializeNetworkCallback();
- }
-
- private void initializeNetworkCallback() {
- networkCallback = new ConnectivityManager.NetworkCallback() {
- @Override
- public void onAvailable(Network network) {
- super.onAvailable(network);
- Log.d(TAG, "Network available: " + network);
- updateNetworkState();
- }
-
- @Override
- public void onLost(Network network) {
- super.onLost(network);
- Log.d(TAG, "Network lost: " + network);
- updateNetworkState();
- }
-
- @Override
- public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
- super.onCapabilitiesChanged(network, networkCapabilities);
- Log.d(TAG, "Network capabilities changed: " + network);
- updateNetworkState();
- }
- };
- }
-
- public void registerNetworkCallback() {
- if (connectivityManager == null) {
- Log.e(TAG, "ConnectivityManager is null");
- return;
- }
-
- NetworkRequest networkRequest = new NetworkRequest.Builder()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
- .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
- .build();
-
- try {
- connectivityManager.registerNetworkCallback(networkRequest, networkCallback);
- updateNetworkState(); // 初始化当前状态
- Log.d(TAG, "Network callback registered");
- } catch (SecurityException e) {
- Log.e(TAG, "Failed to register network callback due to permission issue", e);
- } catch (Exception e) {
- Log.e(TAG, "Failed to register network callback", e);
- }
- }
-
- public void unregisterNetworkCallback() {
- if (connectivityManager == null) {
- Log.e(TAG, "ConnectivityManager is null");
- return;
- }
-
- try {
- connectivityManager.unregisterNetworkCallback(networkCallback);
- Log.d(TAG, "Network callback unregistered");
- } catch (Exception e) {
- Log.e(TAG, "Failed to unregister network callback", e);
- }
- }
-
- private void updateNetworkState() {
- NetworkState newState = getNetworkState();
- if (newState != currentState) {
- Log.d(TAG, "Network state changed from " + currentState + " to " + newState);
- currentState = newState;
-
- // 处理状态变化
- if (currentState == NetworkState.NO_NETWORK) {
- showNotification(NotificationType.NETWORK_LOST, "设备已断开网络连接,请检查WiFi或移动数据设置。", android.R.drawable.ic_dialog_alert, 5, null);
- } else {
- hideNotification();
- }
- }
- }
-
- public NetworkState getNetworkState() {
- if (connectivityManager != null) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- Network activeNetwork = connectivityManager.getActiveNetwork();
- if (activeNetwork != null) {
- NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(activeNetwork);
- if (capabilities != null) {
- if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
- return NetworkState.WIFI_CONNECTED;
- } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
- return NetworkState.MOBILE_CONNECTED;
- } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
- return NetworkState.ETHERNET_CONNECTED;
- }
- }
- }
- } else {
- // 兼容旧版本API
- android.net.NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
- if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
- int type = activeNetworkInfo.getType();
- if (type == ConnectivityManager.TYPE_WIFI) {
- return NetworkState.WIFI_CONNECTED;
- } else if (type == ConnectivityManager.TYPE_MOBILE) {
- return NetworkState.MOBILE_CONNECTED;
- } else if (type == ConnectivityManager.TYPE_ETHERNET) {
- return NetworkState.ETHERNET_CONNECTED;
- }
- }
- }
- }
- return NetworkState.NO_NETWORK;
- }
-
- public void showNotification(NotificationType type, String message, int iconResId, int durationSeconds) {
- showNotification(type, message, iconResId, durationSeconds, null);
- }
-
- public void showNotification(NotificationType type, String message, int iconResId, int durationSeconds, String soundPath) {
- if (isActivityShowing) {
- Log.d(TAG, "Notification activity is already showing");
- return;
- }
-
- if (!(context instanceof Activity)) {
- Log.w(TAG, "Context is not an Activity, cannot show activity");
- return;
- }
-
- Activity activity = (Activity) context;
- if (activity.isFinishing() || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed())) {
- Log.w(TAG, "Activity is not valid, cannot show activity");
- return;
- }
-
- activity.runOnUiThread(() -> {
- try {
- if (isActivityShowing) {
- Log.d(TAG, "Notification activity is already showing");
- return;
- }
-
- Intent intent = new Intent(activity, CommonNotificationActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.putExtra(CommonNotificationActivity.EXTRA_MESSAGE, message);
- intent.putExtra(CommonNotificationActivity.EXTRA_ICON, iconResId);
- intent.putExtra(CommonNotificationActivity.EXTRA_DURATION, durationSeconds);
- intent.putExtra(CommonNotificationActivity.EXTRA_TYPE, type.name());
- if (soundPath != null) {
- intent.putExtra(CommonNotificationActivity.EXTRA_SOUND_PATH, soundPath);
- }
- activity.startActivity(intent);
- isActivityShowing = true;
- Log.d(TAG, "Notification activity shown for " + durationSeconds + " seconds, type: " + type);
- } catch (Exception e) {
- Log.e(TAG, "Failed to show notification activity", e);
- }
- });
- }
-
- public void hideNotification() {
- // 通过发送广播通知CommonNotificationActivity关闭自身
- if (isActivityShowing) {
- try {
- Intent intent = new Intent(CommonNotificationActivity.ACTION_CLOSE_ACTIVITY);
- context.sendBroadcast(intent);
- isActivityShowing = false;
- Log.d(TAG, "Notification activity hidden");
- } catch (Exception e) {
- Log.e(TAG, "Failed to hide notification activity", e);
- }
- }
- }
-
- public boolean isActivityShowing() {
- return isActivityShowing;
- }
-
- public NetworkState getCurrentState() {
- return currentState;
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/ismart/ib86/feature/network/TestWiFiScanResult.java b/app/src/main/java/com/ismart/ib86/feature/network/TestWiFiScanResult.java
deleted file mode 100644
index 734923b..0000000
--- a/app/src/main/java/com/ismart/ib86/feature/network/TestWiFiScanResult.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.ismart.ib86.feature.network;
-
-import android.util.Log;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * 测试WiFi扫描结果发送逻辑
- */
-public class TestWiFiScanResult {
- private static final String TAG = "TestWiFiScanResult";
-
- /**
- * 测试格式化WiFi扫描结果
- */
- public static void testFormatScanResult() {
- Log.i(TAG, "=== 开始测试WiFi扫描结果格式化 ===");
-
- // 模拟WiFi扫描结果
- List mockSSIDs = Arrays.asList("1603", "1603-5G", "ismart_hw_2.4g");
- Log.i(TAG, "模拟WiFi扫描结果: " + mockSSIDs);
-
- // 创建ATCommandProcessor实例进行测试
- ATCommandProcessor processor = new ATCommandProcessor(null, null, null);
-
- // 调用格式化方法
- String result = null;
- try {
- // 使用反射调用私有方法
- java.lang.reflect.Method method = ATCommandProcessor.class.getDeclaredMethod("formatScanResult", List.class);
- method.setAccessible(true);
- result = (String) method.invoke(processor, mockSSIDs);
- } catch (Exception e) {
- Log.e(TAG, "调用formatScanResult方法时出错", e);
- }
-
- Log.i(TAG, "格式化结果: " + result);
-
- // 验证结果
- if (result != null && result.startsWith("AT+SSID=3,")) {
- Log.i(TAG, "✅ 格式化结果正确");
- } else {
- Log.e(TAG, "❌ 格式化结果不正确");
- }
-
- Log.i(TAG, "=== WiFi扫描结果格式化测试完成 ===");
- }
-
- /**
- * 测试完整的WiFi扫描结果发送流程
- */
- public static void testSendScanResult() {
- Log.i(TAG, "=== 开始测试WiFi扫描结果发送 ===");
-
- // 这个测试需要实际的BLE环境,所以只是模拟日志输出
- Log.i(TAG, "模拟WiFi扫描完成,找到3个网络: [1603, 1603-5G, ismart_hw_2.4g]");
- Log.i(TAG, "应该发送格式化结果: AT+SSID=3,1603,1603-5G,ismart_hw_2.4g");
- Log.i(TAG, "通过UUID 0xEA01 发送通知给小程序");
-
- Log.i(TAG, "=== WiFi扫描结果发送测试完成 ===");
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/ismart/ib86/feature/network/TestWiFiScanResultWithBSSID.java b/app/src/main/java/com/ismart/ib86/feature/network/TestWiFiScanResultWithBSSID.java
deleted file mode 100644
index c6aeb4f..0000000
--- a/app/src/main/java/com/ismart/ib86/feature/network/TestWiFiScanResultWithBSSID.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.ismart.ib86.feature.network;
-
-import android.util.Log;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * 测试WiFi扫描结果发送逻辑(包含BSSID)
- */
-public class TestWiFiScanResultWithBSSID {
- private static final String TAG = "TestWiFiScanResultWithBSSID";
-
- /**
- * 测试格式化WiFi扫描结果(包含BSSID)
- */
- public static void testFormatScanResultWithBSSID() {
- Log.i(TAG, "=== 开始测试WiFi扫描结果格式化(包含BSSID) ===");
-
- // 模拟WiFi扫描结果(包含BSSID信息)
- List mockNetworks = Arrays.asList(
- new WiFiNetworkInfo("1603", "e0:0c:e5:13:90:00", -87, 2437),
- new WiFiNetworkInfo("1603-5G", "c4:2b:44:f1:25:80", -60, 5745),
- new WiFiNetworkInfo("ismart_hw_2.4g", "c0:61:18:c9:53:2b", -95, 2412)
- );
- Log.i(TAG, "模拟WiFi扫描结果: " + mockNetworks);
-
- // 创建ATCommandProcessor实例进行测试
- ATCommandProcessor processor = new ATCommandProcessor(null, null, null);
-
- // 调用新的格式化方法
- String result = null;
- try {
- // 使用反射调用私有方法
- java.lang.reflect.Method method = ATCommandProcessor.class.getDeclaredMethod("formatScanResultWithBSSID", List.class);
- method.setAccessible(true);
- result = (String) method.invoke(processor, mockNetworks);
- } catch (Exception e) {
- Log.e(TAG, "调用formatScanResultWithBSSID方法时出错", e);
- }
-
- Log.i(TAG, "格式化结果(包含BSSID): " + result);
-
- // 验证结果
- if (result != null && result.startsWith("AT+SSID=3,") && result.contains(":")) {
- Log.i(TAG, "✅ 格式化结果(包含BSSID)正确");
- } else {
- Log.e(TAG, "❌ 格式化结果(包含BSSID)不正确");
- }
-
- Log.i(TAG, "=== WiFi扫描结果格式化测试(包含BSSID)完成 ===");
- }
-
- /**
- * 测试完整的WiFi扫描结果发送流程(包含BSSID)
- */
- public static void testSendScanResultWithBSSID() {
- Log.i(TAG, "=== 开始测试WiFi扫描结果发送(包含BSSID) ===");
-
- // 这个测试需要实际的BLE环境,所以只是模拟日志输出
- Log.i(TAG, "模拟WiFi扫描完成,找到3个网络:");
- Log.i(TAG, " [0] SSID: '1603-5G', BSSID: c4:2b:44:f1:25:80");
- Log.i(TAG, " [1] SSID: '1603', BSSID: e0:0c:e5:13:90:00");
- Log.i(TAG, " [2] SSID: 'ismart_hw_2.4g', BSSID: c0:61:18:c9:53:2b");
- Log.i(TAG, "应该发送格式化结果: AT+SSID=3,1603-5G:c4:2b:44:f1:25:80,1603:e0:0c:e5:13:90:00,ismart_hw_2.4g:c0:61:18:c9:53:2b");
- Log.i(TAG, "通过UUID 0xEA01 发送通知给小程序");
-
- Log.i(TAG, "=== WiFi扫描结果发送测试(包含BSSID)完成 ===");
- }
-}
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_notification.xml b/app/src/main/res/layout/dialog_notification.xml
new file mode 100644
index 0000000..4d8e9bd
--- /dev/null
+++ b/app/src/main/res/layout/dialog_notification.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..de661e9
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,12 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index b9e96e2..49dfd55 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,9 +1,11 @@
-
+
\ No newline at end of file