diff --git a/contacts/build.properties b/contacts/build.properties index 6edebb5..08d3cee 100644 --- a/contacts/build.properties +++ b/contacts/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Sun Jul 19 04:13:23 CST 2026 +#Sun Jul 19 05:01:46 CST 2026 stageCount=11 libraryProject= baseVersion=15.20 publishVersion=15.20.10 -buildCount=12 +buildCount=17 baseBetaVersion=15.20.11 diff --git a/contacts/src/main/java/cc/winboll/studio/contacts/MainActivity.java b/contacts/src/main/java/cc/winboll/studio/contacts/MainActivity.java index c71e647..c3dc0ae 100644 --- a/contacts/src/main/java/cc/winboll/studio/contacts/MainActivity.java +++ b/contacts/src/main/java/cc/winboll/studio/contacts/MainActivity.java @@ -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; diff --git a/contacts/src/main/java/cc/winboll/studio/contacts/fragments/DunQueryFragment.java b/contacts/src/main/java/cc/winboll/studio/contacts/fragments/DunQueryFragment.java new file mode 100644 index 0000000..07f1ce7 --- /dev/null +++ b/contacts/src/main/java/cc/winboll/studio/contacts/fragments/DunQueryFragment.java @@ -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 + * @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: 懒加载初始化完成"); + } +} diff --git a/contacts/src/main/java/cc/winboll/studio/contacts/fragments/LogFragment.java b/contacts/src/main/java/cc/winboll/studio/contacts/fragments/LogFragment.java deleted file mode 100644 index 625e327..0000000 --- a/contacts/src/main/java/cc/winboll/studio/contacts/fragments/LogFragment.java +++ /dev/null @@ -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&豆包大模型 - * @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正常启动"); - } -} - diff --git a/contacts/src/main/java/cc/winboll/studio/contacts/views/DunQueryView.java b/contacts/src/main/java/cc/winboll/studio/contacts/views/DunQueryView.java new file mode 100644 index 0000000..99f85e2 --- /dev/null +++ b/contacts/src/main/java/cc/winboll/studio/contacts/views/DunQueryView.java @@ -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 + * @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 + " 被拦截"); + } + } +} diff --git a/contacts/src/main/res/layout/activity_settings.xml b/contacts/src/main/res/layout/activity_settings.xml index 3096b34..64c73f6 100644 --- a/contacts/src/main/res/layout/activity_settings.xml +++ b/contacts/src/main/res/layout/activity_settings.xml @@ -58,7 +58,6 @@ android:id="@+id/tv_DunInfo"/> - - + + + diff --git a/contacts/src/main/res/layout/view_dun_query.xml b/contacts/src/main/res/layout/view_dun_query.xml new file mode 100644 index 0000000..f4b5574 --- /dev/null +++ b/contacts/src/main/res/layout/view_dun_query.xml @@ -0,0 +1,38 @@ + + + + + + + + + +