mirror of
https://gitea.winboll.cc/ZhanGSKen/MyWinBoLL.git
synced 2026-08-14 13:37:11 +08:00
feat: 新增云盾查询Fragment替换日志Fragment
- 新增 DunQueryFragment 和 DunQueryView 控件 - 主界面第三个标签页从应用日志改为云盾查询 - 移除 LogFragment 及相关布局文件 - 移除 SettingsActivity 中的 DunQueryView 控件
This commit is contained in:
@@ -31,14 +31,13 @@ import cc.winboll.studio.contacts.activities.WinBollActivity;
|
||||
import cc.winboll.studio.contacts.dun.Rules;
|
||||
import cc.winboll.studio.contacts.fragments.CallLogFragment;
|
||||
import cc.winboll.studio.contacts.fragments.ContactsFragment;
|
||||
import cc.winboll.studio.contacts.fragments.LogFragment;
|
||||
import cc.winboll.studio.contacts.fragments.DunQueryFragment;
|
||||
import cc.winboll.studio.contacts.model.MainServiceBean;
|
||||
import cc.winboll.studio.contacts.services.MainService;
|
||||
import cc.winboll.studio.contacts.utils.PermissionUtils;
|
||||
import cc.winboll.studio.contacts.views.DunTemperatureView;
|
||||
import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.LogView;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -75,7 +74,6 @@ public final class MainActivity extends WinBollActivity implements IWinBoLLActiv
|
||||
private final String[] REQUIRED_PERMISSIONS = PermissionUtils.BASE_PERMISSIONS;
|
||||
|
||||
// ====================== 4. UI控件成员区 ======================
|
||||
private LogView mLogView;
|
||||
private Toolbar mToolbar;
|
||||
private CheckBox cbMainService;
|
||||
private TabLayout tabLayout;
|
||||
@@ -320,10 +318,10 @@ public final class MainActivity extends WinBollActivity implements IWinBoLLActiv
|
||||
// 添加Fragment实例(仅创建对象,不初始化业务逻辑)
|
||||
fragmentList.add(CallLogFragment.newInstance(0));
|
||||
fragmentList.add(ContactsFragment.newInstance(1));
|
||||
fragmentList.add(LogFragment.newInstance(2));
|
||||
fragmentList.add(DunQueryFragment.newInstance(2));
|
||||
tabTitleList.add("通话记录");
|
||||
tabTitleList.add("联系人");
|
||||
tabTitleList.add("应用日志");
|
||||
tabTitleList.add("云盾查询");
|
||||
|
||||
// 初始化懒加载标记数组(默认均未初始化)
|
||||
int fragmentCount = fragmentList.size();
|
||||
@@ -367,8 +365,8 @@ public final class MainActivity extends WinBollActivity implements IWinBoLLActiv
|
||||
((CallLogFragment) targetFragment).initData();
|
||||
} else if (targetFragment instanceof ContactsFragment) {
|
||||
((ContactsFragment) targetFragment).initData();
|
||||
} else if (targetFragment instanceof LogFragment) {
|
||||
((LogFragment) targetFragment).initData();
|
||||
} else if (targetFragment instanceof DunQueryFragment) {
|
||||
((DunQueryFragment) targetFragment).initData();
|
||||
}
|
||||
// 标记为已初始化
|
||||
isFragmentInit[position] = true;
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package cc.winboll.studio.contacts.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import cc.winboll.studio.contacts.R;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||
* @Date 2026/07/19
|
||||
* @Describe 云盾查询区域视图(支持懒加载,仅切换到当前页才加载)
|
||||
*/
|
||||
public class DunQueryFragment extends Fragment {
|
||||
|
||||
public static final String TAG = "DunQueryFragment";
|
||||
private static final String ARG_PAGE = "ARG_PAGE";
|
||||
|
||||
private int mPage;
|
||||
private boolean isViewInitialized = false;
|
||||
private boolean isLazyInitCompleted = false;
|
||||
|
||||
public static DunQueryFragment newInstance(int page) {
|
||||
LogUtils.d(TAG, "newInstance: 创建云盾查询Fragment实例,页码=" + page);
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_PAGE, page);
|
||||
DunQueryFragment fragment = new DunQueryFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
LogUtils.d(TAG, "onCreate: Fragment创建开始");
|
||||
if (getArguments() != null) {
|
||||
mPage = getArguments().getInt(ARG_PAGE);
|
||||
LogUtils.d(TAG, "onCreate: 读取页面参数,mPage=" + mPage);
|
||||
}
|
||||
LogUtils.d(TAG, "onCreate: Fragment创建完成");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
LogUtils.d(TAG, "onCreateView: 加载Fragment布局");
|
||||
View view = inflater.inflate(R.layout.fragment_dun_query, container, false);
|
||||
isViewInitialized = true;
|
||||
LogUtils.d(TAG, "onCreateView: Fragment布局加载完成");
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
LogUtils.d(TAG, "onDestroy: Fragment开始销毁");
|
||||
isViewInitialized = false;
|
||||
isLazyInitCompleted = false;
|
||||
LogUtils.d(TAG, "onDestroy: Fragment销毁完成");
|
||||
}
|
||||
|
||||
public void initData() {
|
||||
if (isLazyInitCompleted || !isViewInitialized || getContext() == null) {
|
||||
LogUtils.d(TAG, "initData: 懒加载已完成/视图未就绪,跳过");
|
||||
return;
|
||||
}
|
||||
LogUtils.d(TAG, "initData: 开始懒加载初始化");
|
||||
isLazyInitCompleted = true;
|
||||
LogUtils.d(TAG, "initData: 懒加载初始化完成");
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
package cc.winboll.studio.contacts.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import cc.winboll.studio.contacts.R;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.libappbase.LogView;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Date 2025/02/20 12:58:15
|
||||
* @Describe 应用日志区域视图(支持懒加载,仅切换到当前页才启动日志)
|
||||
*/
|
||||
public class LogFragment extends Fragment {
|
||||
|
||||
// ====================== 常量定义区 ======================
|
||||
public static final String TAG = "LogFragment";
|
||||
private static final String ARG_PAGE = "ARG_PAGE";
|
||||
|
||||
// ====================== 页面参数区 ======================
|
||||
private int mPage;
|
||||
|
||||
// ====================== UI控件区 ======================
|
||||
private LogView mLogView;
|
||||
|
||||
// ====================== 懒加载标记区 ======================
|
||||
private boolean isViewInitialized = false; // 视图控件绑定完成标记
|
||||
private boolean isLazyInitCompleted = false; // 懒加载总流程完成标记
|
||||
private boolean isLogViewStarted = false; // LogView启动状态标记
|
||||
|
||||
// ====================== 实例化函数区 ======================
|
||||
public static LogFragment newInstance(int page) {
|
||||
LogUtils.d(TAG, "newInstance: 创建日志Fragment实例,页码=" + page);
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_PAGE, page);
|
||||
LogFragment fragment = new LogFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
// ====================== 生命周期函数区 ======================
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
LogUtils.d(TAG, "onCreate: Fragment创建开始");
|
||||
if (getArguments() != null) {
|
||||
mPage = getArguments().getInt(ARG_PAGE);
|
||||
LogUtils.d(TAG, "onCreate: 读取页面参数,mPage=" + mPage);
|
||||
}
|
||||
LogUtils.d(TAG, "onCreate: Fragment创建完成");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
LogUtils.d(TAG, "onCreateView: 加载Fragment布局");
|
||||
View view = inflater.inflate(R.layout.fragment_log, container, false);
|
||||
// Java7 适配:添加强制类型转换,仅初始化LogView控件(不启动)
|
||||
mLogView = (LogView) view.findViewById(R.id.logview);
|
||||
LogUtils.d(TAG, "onCreateView: LogView控件初始化完成(未启动)");
|
||||
// 标记视图控件绑定完成
|
||||
isViewInitialized = true;
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
LogUtils.d(TAG, "onResume: Fragment进入前台");
|
||||
// 已完成懒加载 → 仅重启LogView(切回页面时恢复日志显示)
|
||||
if (isLazyInitCompleted && mLogView != null && !isLogViewStarted) {
|
||||
mLogView.start();
|
||||
isLogViewStarted = true;
|
||||
LogUtils.d(TAG, "onResume: LogView已重启,恢复日志显示");
|
||||
}
|
||||
// 未完成懒加载 → 不操作(等待MainActivity调用initData触发)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
LogUtils.d(TAG, "onDestroy: Fragment开始销毁");
|
||||
if (mLogView != null) {
|
||||
// 若LogView有停止方法,必须调用(避免后台持续占用资源,根据实际API调整)
|
||||
// mLogView.stop(); // 关键:释放LogView资源,防止内存泄漏
|
||||
LogUtils.d(TAG, "onDestroy: LogView资源已释放");
|
||||
}
|
||||
// 重置所有标记,避免重建时状态异常
|
||||
mLogView = null;
|
||||
isViewInitialized = false;
|
||||
isLazyInitCompleted = false;
|
||||
isLogViewStarted = false;
|
||||
LogUtils.d(TAG, "onDestroy: Fragment销毁完成");
|
||||
}
|
||||
|
||||
// ====================== 懒加载核心方法(供MainActivity调用) ======================
|
||||
public void initData() {
|
||||
// 双重防护:避免重复初始化(标记+视图就绪+控件非空)
|
||||
if (isLazyInitCompleted || !isViewInitialized || mLogView == null || getContext() == null) {
|
||||
LogUtils.d(TAG, "initData: 懒加载已完成/视图未就绪,跳过");
|
||||
return;
|
||||
}
|
||||
LogUtils.d(TAG, "initData: 开始懒加载初始化,启动LogView");
|
||||
// 核心:启动LogView(原onCreateView中的start逻辑迁移至此)
|
||||
mLogView.start();
|
||||
isLogViewStarted = true;
|
||||
// 标记懒加载总流程完成(仅执行一次)
|
||||
isLazyInitCompleted = true;
|
||||
LogUtils.d(TAG, "initData: 懒加载初始化完成,LogView正常启动");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
package cc.winboll.studio.contacts.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import cc.winboll.studio.contacts.R;
|
||||
import cc.winboll.studio.contacts.dun.Rules;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen<zhangsken@qq.com>
|
||||
* @Date 2026/07/19
|
||||
* @Describe 云盾拦截查询视图控件:实时查询电话号码的云盾拦截状态
|
||||
*/
|
||||
public class DunQueryView extends LinearLayout {
|
||||
|
||||
private static final String TAG = "DunQueryView";
|
||||
|
||||
private Context mContext;
|
||||
private EditText mEtPhone;
|
||||
private TextView mTvResult;
|
||||
|
||||
public DunQueryView(Context context) {
|
||||
super(context);
|
||||
initView(context);
|
||||
}
|
||||
|
||||
public DunQueryView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initView(context);
|
||||
}
|
||||
|
||||
public DunQueryView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initView(context);
|
||||
}
|
||||
|
||||
private void initView(Context context) {
|
||||
LogUtils.d(TAG, "initView: 初始化云盾查询视图");
|
||||
this.mContext = context;
|
||||
setOrientation(VERTICAL);
|
||||
LayoutInflater.from(context).inflate(R.layout.view_dun_query, this, true);
|
||||
initViews();
|
||||
initListeners();
|
||||
LogUtils.d(TAG, "initView: 云盾查询视图初始化完成");
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
mEtPhone = (EditText) findViewById(R.id.et_dun_query_phone);
|
||||
mTvResult = (TextView) findViewById(R.id.tv_dun_query_result);
|
||||
}
|
||||
|
||||
private void initListeners() {
|
||||
mEtPhone.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
queryDunStatus(s.toString().trim());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void queryDunStatus(String phoneNumber) {
|
||||
if (phoneNumber.isEmpty()) {
|
||||
mTvResult.setText("请输入电话号码");
|
||||
mTvResult.setTextColor(mContext.getResources().getColor(R.color.gray_500));
|
||||
LogUtils.d(TAG, "queryDunStatus: 输入为空,显示默认提示");
|
||||
return;
|
||||
}
|
||||
|
||||
Rules rules = Rules.getInstance(mContext);
|
||||
if (rules == null) {
|
||||
mTvResult.setText("云盾规则未初始化");
|
||||
mTvResult.setTextColor(mContext.getResources().getColor(R.color.gray_500));
|
||||
LogUtils.e(TAG, "queryDunStatus: Rules实例获取失败");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isAllowed = rules.isAllowed(phoneNumber, true);
|
||||
if (isAllowed) {
|
||||
mTvResult.setText("允许接通");
|
||||
mTvResult.setTextColor(mContext.getResources().getColor(R.color.green_normal));
|
||||
LogUtils.d(TAG, "queryDunStatus: 号码" + phoneNumber + " 允许接通");
|
||||
} else {
|
||||
mTvResult.setText("拦截");
|
||||
mTvResult.setTextColor(mContext.getResources().getColor(R.color.red_normal));
|
||||
LogUtils.d(TAG, "queryDunStatus: 号码" + phoneNumber + " 被拦截");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,6 @@
|
||||
android:id="@+id/tv_DunInfo"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
|
||||
+5
-5
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<cc.winboll.studio.libappbase.LogView
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/logview"/>
|
||||
|
||||
<cc.winboll.studio.contacts.views.DunQueryView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:padding="12dp"
|
||||
android:background="@drawable/recycler_view_border">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="云盾拦截查询"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/red_normal"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_dun_query_phone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="输入电话号码查询拦截状态"
|
||||
android:inputType="phone"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_dun_query_result"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="请输入电话号码"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/gray_500"/>
|
||||
|
||||
</LinearLayout>
|
||||
Reference in New Issue
Block a user