Merge remote-tracking branch 'origin/mymessagemanager' into appbase

This commit is contained in:
ZhanGSKen
2025-09-10 02:02:24 +08:00
9 changed files with 179 additions and 142 deletions

View File

@@ -46,7 +46,7 @@ android {
dependencies { dependencies {
api fileTree(dir: 'libs', include: ['*.jar']) api fileTree(dir: 'libs', include: ['*.jar'])
api 'cc.winboll.studio:libaes:15.9.3' api 'cc.winboll.studio:libaes:15.9.3'
api 'cc.winboll.studio:libapputils:15.8.5' api 'cc.winboll.studio:libapputils:15.8.6'
api 'cc.winboll.studio:libappbase:15.9.5' api 'cc.winboll.studio:libappbase:15.9.5'
api 'io.github.medyo:android-about-page:2.0.0' api 'io.github.medyo:android-about-page:2.0.0'

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Sun Aug 31 06:13:45 CST 2025 #Sat Sep 06 01:57:20 HKT 2025
stageCount=7 stageCount=9
libraryProject= libraryProject=
baseVersion=15.3 baseVersion=15.3
publishVersion=15.3.6 publishVersion=15.3.8
buildCount=0 buildCount=0
baseBetaVersion=15.3.7 baseBetaVersion=15.3.9

View File

@@ -57,6 +57,7 @@ public class ComposeSMSActivity extends BaseActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
LogUtils.d(TAG, "onCreate");
setContentView(R.layout.activity_composesms); setContentView(R.layout.activity_composesms);
// 初始化Intent数据增加空判断避免NullPointerException // 初始化Intent数据增加空判断避免NullPointerException
@@ -116,8 +117,9 @@ public class ComposeSMSActivity extends BaseActivity {
} }
}); });
// 初始化联系人列表 // 初始化联系人列表(关键:设置单选模式,确保选中状态生效)
mlvContracts = (ListView) findViewById(R.id.activitycomposesmsListView1); mlvContracts = (ListView) findViewById(R.id.activitycomposesmsListView1);
mlvContracts.setChoiceMode(ListView.CHOICE_MODE_SINGLE); // 开启单选,与布局中一致
// 初始化号码输入框(核心:优化文本变化监听逻辑) // 初始化号码输入框(核心:优化文本变化监听逻辑)
metTO = (EditText) findViewById(R.id.activitycomposesmsEditText1); metTO = (EditText) findViewById(R.id.activitycomposesmsEditText1);
@@ -171,7 +173,7 @@ public class ComposeSMSActivity extends BaseActivity {
} }
} }
// 核心优化:根据输入号码筛选列表(无结果则显示空列表) // 核心优化:根据输入号码筛选列表(无结果则显示空列表,优化选中逻辑
private void filterListByPhone(String inputPhone) { private void filterListByPhone(String inputPhone) {
PhoneUtil phoneUtil = new PhoneUtil(this); PhoneUtil phoneUtil = new PhoneUtil(this);
List<PhoneBean> allContacts = phoneUtil.getPhoneList(); List<PhoneBean> allContacts = phoneUtil.getPhoneList();
@@ -179,7 +181,7 @@ public class ComposeSMSActivity extends BaseActivity {
// 遍历所有联系人,匹配包含输入号码的联系人 // 遍历所有联系人,匹配包含输入号码的联系人
for (PhoneBean contact : allContacts) { for (PhoneBean contact : allContacts) {
if (contact.getTelPhone().contains(inputPhone) if (contact.getTelPhone().contains(inputPhone)
|| phoneUtil.isTheSamePhoneNumber(contact.getTelPhone(), inputPhone)) { || phoneUtil.isTheSamePhoneNumber(contact.getTelPhone(), inputPhone)) {
matchedContacts.add(contact); matchedContacts.add(contact);
} }
@@ -190,10 +192,29 @@ public class ComposeSMSActivity extends BaseActivity {
// 用筛选结果更新列表(无结果则传入空列表) // 用筛选结果更新列表(无结果则传入空列表)
initAdapter(matchedContacts.isEmpty() ? new ArrayList<PhoneBean>() : matchedContacts); initAdapter(matchedContacts.isEmpty() ? new ArrayList<PhoneBean>() : matchedContacts);
// 定位到第一个匹配项(如果有) // 定位并选中匹配项(如果有)
if (!matchedContacts.isEmpty()) { if (!matchedContacts.isEmpty()) {
mlvContracts.setSelection(0); boolean isFound = false;
mtvTOName.setText(matchedContacts.get(0).getName()); for (int i = 0; i < matchedContacts.size(); i++) {
PhoneBean item = matchedContacts.get(i);
// 精确匹配号码(兼容区域码格式)
if (phoneUtil.isTheSamePhoneNumber(item.getTelPhone(), inputPhone)) {
mtvTOName.setText(item.getName());
// 关键:先滚动到目标位置,再设置选中状态
mlvContracts.setSelection(i);
// 主动设置选中(确保样式生效,兼容部分系统)
mlvContracts.setItemChecked(i, true);
LogUtils.d(TAG, String.format("%s 匹配 %s选中位置%d", inputPhone, item.getTelPhone(), i));
isFound = true;
break;
}
}
// 若未精确匹配,选中第一个结果
/*if (!isFound) {
mlvContracts.setSelection(0);
mlvContracts.setItemChecked(0, true);
mtvTOName.setText(matchedContacts.get(0).getName());
}*/
} else { } else {
mtvTOName.setText(""); // 无结果时清空姓名显示 mtvTOName.setText(""); // 无结果时清空姓名显示
} }
@@ -206,7 +227,9 @@ public class ComposeSMSActivity extends BaseActivity {
List<PhoneBean> matchedContacts = phoneUtil.getPhonesByName(searchName); List<PhoneBean> matchedContacts = phoneUtil.getPhonesByName(searchName);
initAdapter(matchedContacts); initAdapter(matchedContacts);
if (!matchedContacts.isEmpty()) { if (!matchedContacts.isEmpty()) {
// 选中第一个结果并设置样式
mlvContracts.setSelection(0); mlvContracts.setSelection(0);
mlvContracts.setItemChecked(0, true);
} }
} }
@@ -246,7 +269,7 @@ public class ComposeSMSActivity extends BaseActivity {
return 0; return 0;
} }
// 初始化或更新列表适配器 // 初始化或更新列表适配器
private void initAdapter(List<PhoneBean> initData) { private void initAdapter(List<PhoneBean> initData) {
mAdapterData.clear(); // 清空旧数据 mAdapterData.clear(); // 清空旧数据
final PhoneUtil phoneUtil = new PhoneUtil(this); final PhoneUtil phoneUtil = new PhoneUtil(this);
@@ -280,19 +303,45 @@ public class ComposeSMSActivity extends BaseActivity {
mSimpleAdapter.setDropDownViewResource(R.layout.listview_contracts); mSimpleAdapter.setDropDownViewResource(R.layout.listview_contracts);
mlvContracts.setAdapter(mSimpleAdapter); mlvContracts.setAdapter(mSimpleAdapter);
// 列表项点击事件 // 列表项点击事件:点击时主动设置选中状态,确保样式突显
mlvContracts.setOnItemClickListener(new AdapterView.OnItemClickListener() { mlvContracts.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position < mAdapterData.size()) { if (position < mAdapterData.size()) {
// 1. 主动设置当前项为选中状态
mlvContracts.setItemChecked(position, true);
// 2. 更新号码输入框和姓名显示
String phone = mAdapterData.get(position).get(MAP_PHONE).toString(); String phone = mAdapterData.get(position).get(MAP_PHONE).toString();
metTO.setText(phone); metTO.setText(phone);
mtvTOName.setText(phoneUtil.getNameByPhone(phone)); mtvTOName.setText(phoneUtil.getNameByPhone(phone));
// 3. 滚动到点击位置(确保可见)
mlvContracts.setSelection(position);
} }
} }
}); });
// 列表项选中状态变化监听(可选,增强选中反馈)
mlvContracts.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// 选中时可添加额外反馈(如改变文本颜色,可选)
if (view != null) {
TextView tvName = (TextView) view.findViewById(R.id.listviewcontractsTextView1);
TextView tvPhone = (TextView) view.findViewById(R.id.listviewcontractsTextView2);
if (tvName != null) tvName.setTextColor(getResources().getColor(R.color.white));
if (tvPhone != null) tvPhone.setTextColor(getResources().getColor(R.color.white));
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// 未选中时无操作
}
});
} else { } else {
mSimpleAdapter.notifyDataSetChanged(); // 数据更新时通知适配器 // 数据更新时,先取消所有旧选中状态,再通知适配器刷新
mlvContracts.clearChoices();
mSimpleAdapter.notifyDataSetChanged();
} }
} }

View File

@@ -11,19 +11,19 @@ import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.provider.ContactsContract; import android.provider.ContactsContract;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libapputils.utils.RegexPPiUtils;
import cc.winboll.studio.mymessagemanager.beans.PhoneBean; import cc.winboll.studio.mymessagemanager.beans.PhoneBean;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
public class PhoneUtil { public class PhoneUtil {

View File

@@ -1,32 +0,0 @@
package cc.winboll.studio.mymessagemanager.utils;
/**
* @Author ZhanGSKen<zhangsken@188.com>
* @Date 2024/12/09 19:00:21
* @Describe .* 前置预防针
regex pointer preventive injection
简称 RegexPPi
*/
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexPPiUtils {
public static final String TAG = "RegexPPiUtils";
//
// 检验文本是否满足适合正则表达式模式计算
//
public static boolean isPPiOK(String text) {
//String text = "这里是一些任意的文本内容";
String regex = ".*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
/*if (matcher.matches()) {
System.out.println("文本满足该正则表达式模式");
} else {
System.out.println("文本不满足该正则表达式模式");
}*/
return matcher.matches();
}
}

View File

@@ -8,6 +8,7 @@ package cc.winboll.studio.mymessagemanager.utils;
import android.content.Context; import android.content.Context;
import android.util.JsonReader; import android.util.JsonReader;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libapputils.utils.RegexPPiUtils;
import cc.winboll.studio.mymessagemanager.beans.SMSAcceptRuleBean; import cc.winboll.studio.mymessagemanager.beans.SMSAcceptRuleBean;
import cc.winboll.studio.mymessagemanager.beans.SMSAcceptRuleBean_V1; import cc.winboll.studio.mymessagemanager.beans.SMSAcceptRuleBean_V1;
import java.io.IOException; import java.io.IOException;

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 选中状态:深灰色背景(可根据需求调整颜色) -->
<item android:state_selected="true" android:drawable="@color/list_item_selected"/>
<!-- 按压状态:浅灰色背景 -->
<item android:state_pressed="true" android:drawable="@color/list_item_pressed"/>
<!-- 默认状态:透明背景 -->
<item android:drawable="@android:color/transparent"/>
</selector>

View File

@@ -1,109 +1,112 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<cc.winboll.studio.libaes.views.AToolbar <cc.winboll.studio.libaes.views.AToolbar
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height" android:layout_height="@dimen/toolbar_height"
android:id="@+id/activitycomposesmsASupportToolbar1"/> android:id="@+id/activitycomposesmsASupportToolbar1"/>
<LinearLayout <LinearLayout
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_frame"> android:background="@drawable/bg_frame">
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/activitycomposesmsRelativeLayout1"> android:id="@+id/activitycomposesmsRelativeLayout1">
<LinearLayout <LinearLayout
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/activitycomposesmsLinearLayout1" android:id="@+id/activitycomposesmsLinearLayout1"
android:gravity="center_vertical" android:gravity="center_vertical"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_marginRight="10dp" android:layout_marginRight="10dp"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
android:layout_alignParentLeft="true"> android:layout_alignParentLeft="true">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="(拼音搜索):"/> android:text="(拼音搜索):"/>
<EditText <EditText
android:layout_width="80dp" android:layout_width="80dp"
android:ems="10" android:ems="10"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/activitycomposesmsEditText2"/> android:id="@+id/activitycomposesmsEditText2"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_toRightOf="@id/activitycomposesmsEditText2" android:layout_toRightOf="@id/activitycomposesmsEditText2"
android:id="@+id/activitycomposesmsTextView2" android:id="@+id/activitycomposesmsTextView2"
android:layout_weight="1.0"/> android:layout_weight="1.0"/>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:orientation="horizontal" android:orientation="horizontal"
android:layout_below="@id/activitycomposesmsLinearLayout1" android:layout_below="@id/activitycomposesmsLinearLayout1"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_marginRight="10dp" android:layout_marginRight="10dp"
android:layout_marginLeft="10dp" android:layout_marginLeft="10dp"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical"> android:gravity="center_vertical">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="(SMS TO) :" android:text="(SMS TO) :"
android:id="@+id/activitycomposesmsTextView1"/> android:id="@+id/activitycomposesmsTextView1"/>
<EditText <EditText
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:inputType="phone" android:inputType="phone"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ems="10" android:ems="10"
android:id="@+id/activitycomposesmsEditText1"/> android:id="@+id/activitycomposesmsEditText1"/>
</LinearLayout> </LinearLayout>
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:padding="10dp" android:padding="10dp"
android:layout_weight="1.0"> android:layout_weight="1.0">
<ListView <!-- 关键修改:添加 listSelector 属性,关联选中样式 -->
android:layout_alignParentTop="true" <ListView
android:layout_width="match_parent" android:layout_alignParentTop="true"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:layout_above="@+id/activitycomposesmsinclude1" android:layout_height="wrap_content"
android:id="@+id/activitycomposesmsListView1"/> android:layout_above="@+id/activitycomposesmsinclude1"
android:id="@+id/activitycomposesmsListView1"
android:listSelector="@drawable/listview_item_selector"
android:choiceMode="singleChoice"/> <!-- 开启单选模式,确保选中状态唯一 -->
<include <include
layout="@layout/view_smssend" layout="@layout/view_smssend"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/activitycomposesmsinclude1"/> android:id="@+id/activitycomposesmsinclude1"/>
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>

View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="white">#FFFFFFFF</color>
<color name="colorSMSSendColor">#FFDCDA3D</color> <color name="colorSMSSendColor">#FFDCDA3D</color>
<color name="colorSMSInboxColor">#FF3DDC84</color> <color name="colorSMSInboxColor">#FF3DDC84</color>
<color name="colorTTSRuleViewBackgroundColor">#FFDCDA3D</color> <color name="colorTTSRuleViewBackgroundColor">#FFDCDA3D</color>
@@ -7,11 +10,11 @@
<color name="colorSMSSendColorDepth">#FFA28BFF</color> <color name="colorSMSSendColorDepth">#FFA28BFF</color>
<color name="colorSMSInboxColorDepth">#FF8BAEFF</color> <color name="colorSMSInboxColorDepth">#FF8BAEFF</color>
<color name="colorTTSRuleViewBackgroundColorDepth">#FFA28BFF</color> <color name="colorTTSRuleViewBackgroundColorDepth">#FFA28BFF</color>
<color name="colorSMSSendColorSky">#FFFFEB8C</color> <color name="colorSMSSendColorSky">#FFFFEB8C</color>
<color name="colorSMSInboxColorSky">#FF8CD9FF</color> <color name="colorSMSInboxColorSky">#FF8CD9FF</color>
<color name="colorTTSRuleViewBackgroundColorSky">#FFFFEB8C</color> <color name="colorTTSRuleViewBackgroundColorSky">#FFFFEB8C</color>
<color name="colorSMSSendColorGolden">#FF78BDFF</color> <color name="colorSMSSendColorGolden">#FF78BDFF</color>
<color name="colorSMSInboxColorGolden">#FFFFED78</color> <color name="colorSMSInboxColorGolden">#FFFFED78</color>
<color name="colorTTSRuleViewBackgroundColorGolden">#FF78BDFF</color> <color name="colorTTSRuleViewBackgroundColorGolden">#FF78BDFF</color>
@@ -19,9 +22,13 @@
<color name="colorSMSSendColorMemor">#FF5AEB53</color> <color name="colorSMSSendColorMemor">#FF5AEB53</color>
<color name="colorSMSInboxColorMemor">#FFE653EB</color> <color name="colorSMSInboxColorMemor">#FFE653EB</color>
<color name="colorTTSRuleViewBackgroundColorMemor">#FF5AEB53</color> <color name="colorTTSRuleViewBackgroundColorMemor">#FF5AEB53</color>
<color name="colorSMSSendColorTao">#FFB4B4B4</color> <color name="colorSMSSendColorTao">#FFB4B4B4</color>
<color name="colorSMSInboxColorTao">#FFD9D9D9</color> <color name="colorSMSInboxColorTao">#FFD9D9D9</color>
<color name="colorTTSRuleViewBackgroundColorTao">#FFB4B4B4</color> <color name="colorTTSRuleViewBackgroundColorTao">#FFB4B4B4</color>
<!-- 列表项选中颜色(深灰) -->
<color name="list_item_selected">#FF696969</color>
<!-- 列表项按压颜色(浅灰) -->
<color name="list_item_pressed">#FFE0E0E0</color>
</resources> </resources>