From bf3e9bdc911885b7c7e82363043dba49187c81b2 Mon Sep 17 00:00:00 2001 From: ZhanGSKen Date: Mon, 3 Mar 2025 17:37:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=91=E7=9B=BE=E9=98=B2=E5=BE=A1=E4=BD=93?= =?UTF-8?q?=E7=B3=BB=E6=88=90=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contacts/build.properties | 4 +- .../contacts/activities/SettingsActivity.java | 73 +++++++++- .../studio/contacts/beans/SettingsModel.java | 135 ++++++++++++++++++ .../studio/contacts/bobulltoon/TomCat.java | 27 ++++ .../cc/winboll/studio/contacts/dun/Rules.java | 134 ++++++++++++++--- .../studio/contacts/services/MainService.java | 32 ++++- .../studio/contacts/views/DuInfoTextView.java | 68 +++++++++ .../src/main/res/layout/activity_settings.xml | 97 ++++++++++++- 8 files changed, 542 insertions(+), 28 deletions(-) create mode 100644 contacts/src/main/java/cc/winboll/studio/contacts/beans/SettingsModel.java create mode 100644 contacts/src/main/java/cc/winboll/studio/contacts/views/DuInfoTextView.java diff --git a/contacts/build.properties b/contacts/build.properties index 77c83d6..9a1c136 100644 --- a/contacts/build.properties +++ b/contacts/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Sun Mar 02 18:48:57 HKT 2025 +#Mon Mar 03 09:35:08 GMT 2025 stageCount=6 libraryProject= baseVersion=1.0 publishVersion=1.0.5 -buildCount=0 +buildCount=41 baseBetaVersion=1.0.6 diff --git a/contacts/src/main/java/cc/winboll/studio/contacts/activities/SettingsActivity.java b/contacts/src/main/java/cc/winboll/studio/contacts/activities/SettingsActivity.java index f60dde8..62fb1f1 100644 --- a/contacts/src/main/java/cc/winboll/studio/contacts/activities/SettingsActivity.java +++ b/contacts/src/main/java/cc/winboll/studio/contacts/activities/SettingsActivity.java @@ -37,6 +37,9 @@ import cc.winboll.studio.libappbase.bean.APPInfo; import com.hjq.toast.ToastUtils; import java.lang.reflect.Field; import java.util.List; +import cc.winboll.studio.contacts.beans.SettingsModel; +import cc.winboll.studio.contacts.views.DuInfoTextView; +import cc.winboll.studio.libappbase.LogUtils; public class SettingsActivity extends AppCompatActivity implements IWinBollActivity { @@ -49,11 +52,21 @@ public class SettingsActivity extends AppCompatActivity implements IWinBollActiv int mnStreamMaxVolume; int mnStreamVolume; Switch mswMainService; + static DuInfoTextView _DuInfoTextView; + + // 云盾防御层数量 + EditText etDunTotalCount; + // 防御层恢复时间间隔(秒钟) + EditText etDunResumeSecondCount; + // 每次恢复防御层数 + EditText etDunResumeCount; + // 是否启用云盾 + Switch swIsEnableDun; private RecyclerView recyclerView; private PhoneConnectRuleAdapter adapter; private List ruleList; - + @Override public APPInfo getAppInfo() { return null; @@ -104,13 +117,14 @@ public class SettingsActivity extends AppCompatActivity implements IWinBollActiv mswMainService.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View arg0) { + LogUtils.d(TAG, "mswMainService onClick"); // TODO: Implement this method if (mswMainService.isChecked()) { //ToastUtils.show("Is Checked"); - MainService.startMainService(SettingsActivity.this); + MainService.startMainServiceAndSaveStatus(SettingsActivity.this); } else { //ToastUtils.show("Not Checked"); - MainService.stopMainService(SettingsActivity.this); + MainService.stopMainServiceAndSaveStatus(SettingsActivity.this); } } }); @@ -156,15 +170,58 @@ public class SettingsActivity extends AppCompatActivity implements IWinBollActiv // 当停止拖动SeekBar时的操作 } }); - - + + recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); ruleList = Rules.getInstance(this).getPhoneBlacRuleBeanList(); - + adapter = new PhoneConnectRuleAdapter(this, ruleList); recyclerView.setAdapter(adapter); + + // 设置参数云盾 + _DuInfoTextView = findViewById(R.id.tv_DunInfo); + etDunTotalCount = findViewById(R.id.et_DunTotalCount); + etDunResumeSecondCount = findViewById(R.id.et_DunResumeSecondCount); + etDunResumeCount = findViewById(R.id.et_DunResumeCount); + swIsEnableDun = findViewById(R.id.sw_IsEnableDun); + SettingsModel settingsModel = Rules.getInstance(this).getSettingsModel(); + + etDunTotalCount.setText(Integer.toString(settingsModel.getDunTotalCount())); + etDunResumeSecondCount.setText(Integer.toString(settingsModel.getDunResumeSecondCount())); + etDunResumeCount.setText(Integer.toString(settingsModel.getDunResumeCount())); + swIsEnableDun.setChecked(settingsModel.isEnableDun()); + + boolean isEnableDun = settingsModel.isEnableDun(); + etDunTotalCount.setEnabled(!isEnableDun); + etDunResumeSecondCount.setEnabled(!isEnableDun); + etDunResumeCount.setEnabled(!isEnableDun); + + } + + public static void notifyDunInfoUpdate() { + if (_DuInfoTextView != null) { + _DuInfoTextView.notifyInfoUpdate(); + } + } + + public void onSW_IsEnableDun(View view) { + LogUtils.d(TAG, "onSW_IsEnableDun"); + boolean isEnableDun = swIsEnableDun.isChecked(); + etDunTotalCount.setEnabled(!isEnableDun); + etDunResumeSecondCount.setEnabled(!isEnableDun); + etDunResumeCount.setEnabled(!isEnableDun); + + SettingsModel settingsModel = Rules.getInstance(this).getSettingsModel(); + if (isEnableDun) { + settingsModel.setDunTotalCount(Integer.parseInt(etDunTotalCount.getText().toString())); + settingsModel.setDunResumeSecondCount(Integer.parseInt(etDunResumeSecondCount.getText().toString())); + settingsModel.setDunResumeCount(Integer.parseInt(etDunResumeCount.getText().toString())); + } + settingsModel.setIsEnableDun(isEnableDun); + Rules.getInstance(this).saveDun(); + Rules.getInstance(this).reload(); } void updateStreamVolumeTextView() { @@ -198,10 +255,14 @@ public class SettingsActivity extends AppCompatActivity implements IWinBollActiv public void run() { if (tomCat.downloadBoBullToon()) { ToastUtils.show("BoBullToon downlaod OK!"); + MainService.restartMainService(SettingsActivity.this); + Rules.getInstance(SettingsActivity.this).reload(); } } }).start(); } + + public void onSearchBoBullToonPhone(View view) { TomCat tomCat = TomCat.getInstance(this); diff --git a/contacts/src/main/java/cc/winboll/studio/contacts/beans/SettingsModel.java b/contacts/src/main/java/cc/winboll/studio/contacts/beans/SettingsModel.java new file mode 100644 index 0000000..2f0fc1e --- /dev/null +++ b/contacts/src/main/java/cc/winboll/studio/contacts/beans/SettingsModel.java @@ -0,0 +1,135 @@ +package cc.winboll.studio.contacts.beans; + +/** + * @Author ZhanGSKen@AliYun.Com + * @Date 2025/03/02 19:51:40 + * @Describe SettingsModel + */ +import android.util.JsonReader; +import android.util.JsonWriter; +import cc.winboll.studio.libappbase.BaseBean; +import java.io.IOException; + +public class SettingsModel extends BaseBean { + + public static final String TAG = "SettingsModel"; + + // 云盾防御层数量 + int dunTotalCount; + // 当前云盾防御层 + int dunCurrentCount; + // 防御层恢复时间间隔(秒钟) + int dunResumeSecondCount; + // 每次恢复防御层数 + int dunResumeCount; + // 是否启用云盾 + boolean isEnableDun; + + public SettingsModel() { + this.dunTotalCount = 6; + this.dunCurrentCount = 6; + this.dunResumeSecondCount = 60; + this.dunResumeCount = 1; + this.isEnableDun = false; + } + + public SettingsModel(int dunTotalCount, int dunCurrentCount, int dunResumeSecondCount, int dunResumeCount, boolean isEnableDun) { + this.dunTotalCount = dunTotalCount; + this.dunCurrentCount = dunCurrentCount; + this.dunResumeSecondCount = dunResumeSecondCount; + this.dunResumeCount = dunResumeCount; + this.isEnableDun = isEnableDun; + } + + public void setDunTotalCount(int dunTotalCount) { + this.dunTotalCount = dunTotalCount; + } + + public int getDunTotalCount() { + return dunTotalCount; + } + + public void setDunCurrentCount(int dunCurrentCount) { + this.dunCurrentCount = dunCurrentCount; + } + + public int getDunCurrentCount() { + return dunCurrentCount; + } + + public void setDunResumeSecondCount(int dunResumeSecondCount) { + this.dunResumeSecondCount = dunResumeSecondCount; + } + + public int getDunResumeSecondCount() { + return dunResumeSecondCount; + } + + public void setDunResumeCount(int dunResumeCount) { + this.dunResumeCount = dunResumeCount; + } + + public int getDunResumeCount() { + return dunResumeCount; + } + + public void setIsEnableDun(boolean isEnableDun) { + this.isEnableDun = isEnableDun; + } + + public boolean isEnableDun() { + return isEnableDun; + } + + + + @Override + public String getName() { + return SettingsModel.class.getName(); + } + + @Override + public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException { + super.writeThisToJsonWriter(jsonWriter); + jsonWriter.name("dunTotalCount").value(getDunTotalCount()); + jsonWriter.name("dunCurrentCount").value(getDunCurrentCount()); + jsonWriter.name("dunResumeSecondCount").value(getDunResumeSecondCount()); + jsonWriter.name("dunResumeCount").value(getDunResumeCount()); + jsonWriter.name("isEnableDun").value(isEnableDun()); + + } + + @Override + public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException { + if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else { + if (name.equals("dunTotalCount")) { + setDunTotalCount(jsonReader.nextInt()); + } else if (name.equals("dunCurrentCount")) { + setDunCurrentCount(jsonReader.nextInt()); + } else if (name.equals("dunResumeSecondCount")) { + setDunResumeSecondCount(jsonReader.nextInt()); + } else if (name.equals("dunResumeCount")) { + setDunResumeCount(jsonReader.nextInt()); + } else if (name.equals("isEnableDun")) { + setIsEnableDun(jsonReader.nextBoolean()); + } else { + return false; + } + } + return true; + } + + @Override + public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException { + jsonReader.beginObject(); + while (jsonReader.hasNext()) { + String name = jsonReader.nextName(); + if (!initObjectsFromJsonReader(jsonReader, name)) { + jsonReader.skipValue(); + } + } + // 结束 JSON 对象 + jsonReader.endObject(); + return this; + } +} diff --git a/contacts/src/main/java/cc/winboll/studio/contacts/bobulltoon/TomCat.java b/contacts/src/main/java/cc/winboll/studio/contacts/bobulltoon/TomCat.java index 81affee..c126fe9 100644 --- a/contacts/src/main/java/cc/winboll/studio/contacts/bobulltoon/TomCat.java +++ b/contacts/src/main/java/cc/winboll/studio/contacts/bobulltoon/TomCat.java @@ -87,6 +87,7 @@ public class TomCat { // 删除临时 ZIP 文件 tempZipFile.delete(); + LogUtils.d(TAG, "已更新 BoBullToon 数据"); } } @@ -94,6 +95,15 @@ public class TomCat { String zipUrl = "https://gitea.winboll.cc//Studio/BoBullToon/archive/main.zip"; // 替换为实际的 ZIP 文件 URL String destinationFolder = getWorkingFolder().getPath(); // 替换为实际的目标文件夹路径 try { + // 删除旧文件 + File fOldFolder = new File(destinationFolder); + if(fOldFolder.exists()) { + deleteFolderRecursive(fOldFolder); + fOldFolder.mkdirs(); + LogUtils.d(TAG, "已清空 BoBullToon 数据"); + } + + // 更新新文件 downloadAndExtractZip(zipUrl, destinationFolder); LogUtils.d(TAG, "ZIP 文件下载并解压成功。"); return true; @@ -102,6 +112,23 @@ public class TomCat { } return false; } + + // 递归删除文件夹及其内容的方法 + public static void deleteFolderRecursive(File file) { + // 判断是否为文件夹 + if (file.isDirectory()) { + // 列出文件夹中的所有文件和子文件夹 + File[] files = file.listFiles(); + if (files!= null) { + // 遍历并递归删除每个文件和子文件夹 + for (File f : files) { + deleteFolderRecursive(f); + } + } + } + // 删除文件或空文件夹 + file.delete(); + } File getWorkingFolder() { return mContext.getExternalFilesDir(TAG); diff --git a/contacts/src/main/java/cc/winboll/studio/contacts/dun/Rules.java b/contacts/src/main/java/cc/winboll/studio/contacts/dun/Rules.java index cc729db..9ca0e68 100644 --- a/contacts/src/main/java/cc/winboll/studio/contacts/dun/Rules.java +++ b/contacts/src/main/java/cc/winboll/studio/contacts/dun/Rules.java @@ -6,11 +6,17 @@ package cc.winboll.studio.contacts.dun; * @Describe 云盾防御规则 */ import android.content.Context; +import android.media.AudioManager; +import cc.winboll.studio.contacts.activities.SettingsActivity; import cc.winboll.studio.contacts.beans.PhoneConnectRuleModel; +import cc.winboll.studio.contacts.beans.RingTongBean; +import cc.winboll.studio.contacts.beans.SettingsModel; import cc.winboll.studio.contacts.services.MainService; import cc.winboll.studio.contacts.utils.RegexPPiUtils; import cc.winboll.studio.libappbase.LogUtils; import java.util.ArrayList; +import java.util.Timer; +import java.util.TimerTask; import java.util.regex.Pattern; public class Rules { @@ -20,11 +26,13 @@ public class Rules { ArrayList _PhoneConnectRuleModelList; static volatile Rules _Rules; Context mContext; + SettingsModel mSettingsModel; + Timer mDunResumeTimer; Rules(Context context) { mContext = context; _PhoneConnectRuleModelList = new ArrayList(); - loadRules(); + reload(); } public static synchronized Rules getInstance(Context context) { @@ -34,6 +42,34 @@ public class Rules { return _Rules; } + public void reload() { + loadRules(); + loadDun(); + setDunResumTimer(); + } + + public void setDunResumTimer() { + if (mDunResumeTimer != null) { + mDunResumeTimer.cancel(); + } + + // 盾牌恢复定时器 + mDunResumeTimer = new Timer(); + mDunResumeTimer.schedule(new TimerTask() { + @Override + public void run() { + if (mSettingsModel.getDunCurrentCount() != mSettingsModel.getDunTotalCount()) { + int newDunCount = mSettingsModel.getDunCurrentCount() + mSettingsModel.getDunResumeCount(); + // 保证盾值在[0,DunTotalCount]之内其他值一律重置为 DunTotalCount。 + newDunCount = (newDunCount > mSettingsModel.getDunTotalCount()) ?mSettingsModel.getDunTotalCount(): newDunCount; + mSettingsModel.setDunCurrentCount(newDunCount); + saveDun(); + SettingsActivity.notifyDunInfoUpdate(); + } + } + }, 1000, mSettingsModel.getDunResumeSecondCount() * 1000); + } + public void loadRules() { _PhoneConnectRuleModelList.clear(); PhoneConnectRuleModel.loadBeanList(mContext, _PhoneConnectRuleModelList, PhoneConnectRuleModel.class); @@ -43,31 +79,93 @@ public class Rules { PhoneConnectRuleModel.saveBeanList(mContext, _PhoneConnectRuleModelList, PhoneConnectRuleModel.class); } - public boolean isAllowed(String phoneNumber) { - // 正则运算预防针 - if (!RegexPPiUtils.isPPiOK(phoneNumber)) { - LogUtils.d(TAG, "RegexPPiUtils.isPPiOK return false."); - return false; + public void loadDun() { + mSettingsModel = SettingsModel.loadBean(mContext, SettingsModel.class); + if (mSettingsModel == null) { + mSettingsModel = new SettingsModel(); + SettingsModel.saveBean(mContext, mSettingsModel); } + } + + public void saveDun() { + LogUtils.d(TAG, String.format("saveDun() isEnableDun : %s", mSettingsModel.isEnableDun())); + SettingsModel.saveBean(mContext, mSettingsModel); + } + + public boolean isAllowed(String phoneNumber) { + // 没有启用云盾,默认允许接通任何电话 + if (!mSettingsModel.isEnableDun()) { + LogUtils.d(TAG, "没有启用云盾,默认允许接通任何电话"); + return true; + } + + // + // 以下是云盾防御体系 + boolean isDefend = false; // 盾牌是否生效 + boolean isConnect = true; // 防御结果是否连接 + + // 如果盾值小于1,则解除防御 + if (!isDefend && mSettingsModel.getDunCurrentCount() < 1) { + // 盾层为1以下,防御解除 + LogUtils.d(TAG, "盾层为1以下,防御解除"); + isDefend = true; + isConnect = true; + } + + // 正则运算预防针 + if (!isDefend && !RegexPPiUtils.isPPiOK(phoneNumber)) { + LogUtils.d(TAG, "RegexPPiUtils.isPPiOK return false."); + isDefend = true; + isConnect = false; + } + // 检验拨不通号码群 - if (MainService.isPhoneInBoBullToon(phoneNumber)) { + if (!isDefend && MainService.isPhoneInBoBullToon(phoneNumber)) { LogUtils.d(TAG, String.format("PhoneNumber %s\n Is In BoBullToon", phoneNumber)); - return false; + isDefend = true; + isConnect = false; } // 正则匹配规则名单校验 - for (int i = 0; i < _PhoneConnectRuleModelList.size(); i++) { - if (_PhoneConnectRuleModelList.get(i).isEnable()) { - String regex = _PhoneConnectRuleModelList.get(i).getRuleText(); - if (Pattern.matches(regex, phoneNumber)) { - LogUtils.d(TAG, String.format("phoneNumber :%s \nisAllowConnection %s By Rule : %s", phoneNumber, _PhoneConnectRuleModelList.get(i).isAllowConnection(), _PhoneConnectRuleModelList.get(i))); - return _PhoneConnectRuleModelList.get(i).isAllowConnection(); + if (!isDefend) { + for (int i = 0; i < _PhoneConnectRuleModelList.size(); i++) { + if (_PhoneConnectRuleModelList.get(i).isEnable()) { + String regex = _PhoneConnectRuleModelList.get(i).getRuleText(); + if (Pattern.matches(regex, phoneNumber)) { + LogUtils.d(TAG, String.format("phoneNumber :%s \nisAllowConnection %s By Rule : %s", phoneNumber, _PhoneConnectRuleModelList.get(i).isAllowConnection(), _PhoneConnectRuleModelList.get(i))); + isDefend = true; + isConnect = _PhoneConnectRuleModelList.get(i).isAllowConnection(); + break; + } } } } - // 其他默认接收 - return true; + if (isConnect) { + // 如果防御结果为连接,则恢复防御盾牌最大值层数 + mSettingsModel.setDunCurrentCount(mSettingsModel.getDunTotalCount()); + saveDun(); + SettingsActivity.notifyDunInfoUpdate(); + } else if (isDefend) { + // 如果触发了以上某个防御模块, + // 就减少防御盾牌层数。 + // 每校验一次规则,云盾防御层数减1 + // 当云盾防御层数为0时,再次进行以下程序段则恢复满值防御。 + int newDunCount = mSettingsModel.getDunCurrentCount() - 1; + + // 保证盾值在[0,DunTotalCount]之内其他值一律重置为 DunTotalCount。 + if (newDunCount < 0 || newDunCount > mSettingsModel.getDunTotalCount()) { + mSettingsModel.setDunCurrentCount(mSettingsModel.getDunTotalCount()); + } else { + mSettingsModel.setDunCurrentCount(newDunCount); + } + + saveDun(); + SettingsActivity.notifyDunInfoUpdate(); + } + + // 返回校验结果 + return isConnect; } public void add(String szPhoneConnectRule, boolean isAllowConnection, boolean isEnable) { @@ -77,4 +175,8 @@ public class Rules { public ArrayList getPhoneBlacRuleBeanList() { return _PhoneConnectRuleModelList; } + + public SettingsModel getSettingsModel() { + return mSettingsModel; + } } diff --git a/contacts/src/main/java/cc/winboll/studio/contacts/services/MainService.java b/contacts/src/main/java/cc/winboll/studio/contacts/services/MainService.java index 5c1eb9d..a4ebf56 100644 --- a/contacts/src/main/java/cc/winboll/studio/contacts/services/MainService.java +++ b/contacts/src/main/java/cc/winboll/studio/contacts/services/MainService.java @@ -142,7 +142,7 @@ public class MainService extends Service { mMainReceiver.registerAction(this); } - Rules.getInstance(this); + Rules.getInstance(this).loadRules(); startPhoneCallListener(); @@ -273,14 +273,40 @@ public class MainService extends Service { public static void stopMainService(Context context) { LogUtils.d(TAG, "stopMainService"); + context.stopService(new Intent(context, MainService.class)); + } + + public static void startMainService(Context context) { + LogUtils.d(TAG, "startMainService"); + context.startService(new Intent(context, MainService.class)); + } + + public static void restartMainService(Context context) { + LogUtils.d(TAG, "restartMainService"); + + MainServiceBean bean = MainServiceBean.loadBean(context, MainServiceBean.class); + if (bean != null && bean.isEnable()) { + context.stopService(new Intent(context, MainService.class)); +// try { +// Thread.sleep(1000); +// } catch (InterruptedException e) { +// LogUtils.d(TAG, e, Thread.currentThread().getStackTrace()); +// } + context.startService(new Intent(context, MainService.class)); + LogUtils.d(TAG, "已重启 MainService"); + } + } + + public static void stopMainServiceAndSaveStatus(Context context) { + LogUtils.d(TAG, "stopMainServiceAndSaveStatus"); MainServiceBean bean = new MainServiceBean(); bean.setIsEnable(false); MainServiceBean.saveBean(context, bean); context.stopService(new Intent(context, MainService.class)); } - public static void startMainService(Context context) { - LogUtils.d(TAG, "startMainService"); + public static void startMainServiceAndSaveStatus(Context context) { + LogUtils.d(TAG, "startMainServiceAndSaveStatus"); MainServiceBean bean = new MainServiceBean(); bean.setIsEnable(true); MainServiceBean.saveBean(context, bean); diff --git a/contacts/src/main/java/cc/winboll/studio/contacts/views/DuInfoTextView.java b/contacts/src/main/java/cc/winboll/studio/contacts/views/DuInfoTextView.java new file mode 100644 index 0000000..62d968c --- /dev/null +++ b/contacts/src/main/java/cc/winboll/studio/contacts/views/DuInfoTextView.java @@ -0,0 +1,68 @@ +package cc.winboll.studio.contacts.views; + +/** + * @Author ZhanGSKen@AliYun.Com + * @Date 2025/03/02 21:11:03 + * @Describe 云盾防御信息 + */ +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.widget.TextView; +import cc.winboll.studio.contacts.beans.SettingsModel; +import cc.winboll.studio.contacts.dun.Rules; +import cc.winboll.studio.libappbase.LogUtils; + +public class DuInfoTextView extends TextView { + + public static final String TAG = "DuInfoTextView"; + + public static final int MSG_NOTIFY_INFO_UPDATE = 0; + + Context mContext; + + public DuInfoTextView(android.content.Context context) { + super(context); + } + + public DuInfoTextView(android.content.Context context, android.util.AttributeSet attrs) { + super(context, attrs); + initView(context); + } + + public DuInfoTextView(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public DuInfoTextView(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + void initView(android.content.Context context) { + mContext = context; + updateInfo(); + } + + void updateInfo() { + LogUtils.d(TAG, "updateInfo()"); + SettingsModel settingsModel = Rules.getInstance(mContext).getSettingsModel(); + String info = String.format("(云盾防御值【%d/%d】)", settingsModel.getDunCurrentCount(), settingsModel.getDunTotalCount()); + setText(info); + } + + Handler mHandler = new Handler(){ + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + if(msg.what == MSG_NOTIFY_INFO_UPDATE) { + updateInfo(); + } + } + + }; + + public void notifyInfoUpdate() { + LogUtils.d(TAG, "notifyInfoUpdate()"); + mHandler.sendMessage(mHandler.obtainMessage(MSG_NOTIFY_INFO_UPDATE)); + } +} diff --git a/contacts/src/main/res/layout/activity_settings.xml b/contacts/src/main/res/layout/activity_settings.xml index c5a7085..f120c8b 100644 --- a/contacts/src/main/res/layout/activity_settings.xml +++ b/contacts/src/main/res/layout/activity_settings.xml @@ -33,7 +33,102 @@ android:layout_height="wrap_content" android:text="主要服务" android:id="@+id/sw_mainservice" - android:layout_margin="10dp"/> + android:layout_margin="5dp"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +