更新联系人查询与短信发送框,在搜索到空数据时的显示逻辑。

This commit is contained in:
ZhanGSKen
2025-08-30 21:15:01 +08:00
parent 6d9adc124e
commit b374f3117a
3 changed files with 243 additions and 208 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Sat Aug 30 11:42:36 HKT 2025 #Sat Aug 30 13:11:45 GMT 2025
stageCount=5 stageCount=5
libraryProject= libraryProject=
baseVersion=15.3 baseVersion=15.3
publishVersion=15.3.4 publishVersion=15.3.4
buildCount=0 buildCount=4
baseBetaVersion=15.3.5 baseBetaVersion=15.3.5

View File

@@ -1,5 +1,10 @@
package cc.winboll.studio.mymessagemanager.activitys; package cc.winboll.studio.mymessagemanager.activitys;
/**
* @Author ZhanGSKen&豆包大模型<zhangsken@188.com>
* @Date 2025/08/30 14:32
* @Describe 联系人查询与短信发送窗口
*/
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
@@ -11,13 +16,17 @@ import android.widget.RelativeLayout;
import android.widget.SimpleAdapter; import android.widget.SimpleAdapter;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toolbar; import android.widget.Toolbar;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import cc.winboll.studio.libaes.views.AOHPCTCSeekBar; import cc.winboll.studio.libaes.views.AOHPCTCSeekBar;
import cc.winboll.studio.mymessagemanager.R; import cc.winboll.studio.mymessagemanager.R;
import cc.winboll.studio.mymessagemanager.activitys.ComposeSMSActivity;
import cc.winboll.studio.mymessagemanager.beans.PhoneBean; import cc.winboll.studio.mymessagemanager.beans.PhoneBean;
import cc.winboll.studio.mymessagemanager.utils.PhoneUtil; import cc.winboll.studio.mymessagemanager.utils.PhoneUtil;
import cc.winboll.studio.mymessagemanager.utils.SMSUtil; import cc.winboll.studio.mymessagemanager.utils.SMSUtil;
import com.hjq.toast.ToastUtils; import com.hjq.toast.ToastUtils;
import cc.winboll.studio.libappbase.LogUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -26,255 +35,282 @@ import java.util.Map;
public class ComposeSMSActivity extends BaseActivity { public class ComposeSMSActivity extends BaseActivity {
public static String TAG = "ComposeSMSActivity"; public static String TAG = "ComposeSMSActivity";
public static String EXTRA_SMSBODY = "sms_body"; public static String EXTRA_SMSBODY = "sms_body";
private static final String MAP_NAME = "NAME";
private static final String MAP_PHONE = "PHONE";
static String MAP_NAME = "NAME"; private String mszSMSBody;
static String MAP_PHONE = "PHONE"; private String mszScheme;
private String mszPhoneTo;
String mszSMSBody; private TextView mtvTOName;
String mszScheme; private EditText metTONameSearch;
String mszPhoneTo; private EditText metTO;
TextView mtvTOName; private EditText metSMSBody;
EditText metTONameSearch; private SimpleAdapter mSimpleAdapter;
EditText metTO; private List<Map<String, Object>> mAdapterData = new ArrayList<Map<String, Object>>();
EditText metSMSBody; private ListView mlvContracts;
SimpleAdapter mSimpleAdapter; private List<PhoneBean> mListPhoneBeanContracts;
List<Map<String,Object>> mAdapterData = new ArrayList<>(); private Toolbar mToolbar;
ListView mlvContracts; private AOHPCTCSeekBar mAOHPCTCSeekBar;
List<PhoneBean> mListPhoneBeanContracts; private RelativeLayout mrlContracts;
Toolbar mToolbar;
AOHPCTCSeekBar mAOHPCTCSeekBar;
RelativeLayout mrlContracts;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_composesms); setContentView(R.layout.activity_composesms);
mszSMSBody = getIntent().getStringExtra(EXTRA_SMSBODY);
mszScheme = getIntent().getData().getScheme(); // 初始化Intent数据增加空判断避免NullPointerException
mszPhoneTo = getIntent().getData().getSchemeSpecificPart(); Intent intent = getIntent();
if (!mszScheme.equals("smsto")) { if (intent != null) {
// 其他方式未支持就退出 mszSMSBody = intent.getStringExtra(EXTRA_SMSBODY);
finish(); if (intent.getData() != null) {
mszScheme = intent.getData().getScheme();
mszPhoneTo = intent.getData().getSchemeSpecificPart();
}
} }
// 初始化视图
// 校验启动方式非smsto则退出
if (mszScheme == null || !"smsto".equals(mszScheme)) {
ToastUtils.show("不支持的启动方式");
finish();
return;
}
initView(); initView();
// 设置适配器 initAdapter(null); // 初始加载所有联系人
initAdapter(null);
// 设置搜索到的匹配位置
setListViewPrePositionByPhone(); setListViewPrePositionByPhone();
} }
// private void initView() {
// 初始化视图
//
void initView() {
//Drawable drawableFrame = AppCompatResources.getDrawable(this, R.drawable.bg_frame);
// 初始化标题栏 // 初始化标题栏
mToolbar = findViewById(R.id.activitycomposesmsASupportToolbar1); mToolbar = (Toolbar) findViewById(R.id.activitycomposesmsASupportToolbar1);
mToolbar.setSubtitle(getString(R.string.activity_name_composesms)); mToolbar.setSubtitle(getString(R.string.activity_name_composesms));
setActionBar(mToolbar); setActionBar(mToolbar);
// 初始化联系人栏目框 // 初始化联系人姓名显示和搜索
mtvTOName = findViewById(R.id.activitycomposesmsTextView2); mtvTOName = (TextView) findViewById(R.id.activitycomposesmsTextView2);
mrlContracts = findViewById(R.id.activitycomposesmsRelativeLayout1); mrlContracts = (RelativeLayout) findViewById(R.id.activitycomposesmsRelativeLayout1);
//mrlContracts.setBackground(drawableFrame); metTONameSearch = (EditText) findViewById(R.id.activitycomposesmsEditText2);
metTONameSearch = findViewById(R.id.activitycomposesmsEditText2);
metTONameSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
metTO.setText("");
setListViewPrePositionByName();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override // 姓名搜索框文本变化监听
public void afterTextChanged(Editable s) { metTONameSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
metTO.setText(""); // 清空号码输入框,避免冲突
String input = s == null ? "" : s.toString().trim();
if (input.isEmpty()) {
initAdapter(null); // 空搜索时显示所有联系人
} else {
setListViewPrePositionByName(); // 按姓名搜索
}
}
} @Override
}); public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// 无操作
}
// 初始化联系人列表 @Override
mlvContracts = findViewById(R.id.activitycomposesmsListView1); public void afterTextChanged(Editable s) {
// 无操作
// 初始化联系人输入框 }
metTO = findViewById(R.id.activitycomposesmsEditText1);
metTO.setText(mszPhoneTo);
metTO.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mtvTOName.setText("");
//重新加载数据
initAdapter(null);
setListViewPrePositionByPhone();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
// 初始化发送拉动控件
mAOHPCTCSeekBar = findViewById(R.id.viewsmssendpart1AOHPCTCSeekBar1);
mAOHPCTCSeekBar.setThumb(getDrawable(R.drawable.ic_message));
mAOHPCTCSeekBar.setThumbOffset(20);
mAOHPCTCSeekBar.setOnOHPCListener(new AOHPCTCSeekBar.OnOHPCListener() {
@Override
public void onOHPCommit() {
// 空号码不发送
mszPhoneTo = metTO.getText().toString();
if (mszPhoneTo.trim().equals("")) {
ToastUtils.show("没有设置接收号码。");
return;
}
// 空消息不发送
mszSMSBody = metSMSBody.getText().toString();
if (mszSMSBody.equals("")) {
ToastUtils.show("没有消息内容可发送。");
return;
}
// 发送消息
if (SMSUtil.sendMessageByInterface2(ComposeSMSActivity.this, mszPhoneTo, mszSMSBody)) {
ComposeSMSActivity.this.finish();
}
}
}); });
// 初始化提示框 // 初始化联系人列表
TextView tvAOHPCTCSeekBarMSG = findViewById(R.id.viewsmssendpart1TextView1); mlvContracts = (ListView) findViewById(R.id.activitycomposesmsListView1);
// 初始化号码输入框(核心:优化文本变化监听逻辑)
metTO = (EditText) findViewById(R.id.activitycomposesmsEditText1);
if (mszPhoneTo != null) {
metTO.setText(mszPhoneTo);
}
metTO.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mtvTOName.setText(""); // 清空姓名显示
String inputPhone = s == null ? "" : s.toString().trim();
if (inputPhone.isEmpty()) {
// 输入为空时,显示所有联系人
initAdapter(null);
} else {
// 输入非空时,按号码搜索并更新列表(无结果则清空)
filterListByPhone(inputPhone);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// 无操作
}
@Override
public void afterTextChanged(Editable s) {
// 无操作
}
});
// 初始化发送控件
mAOHPCTCSeekBar = (AOHPCTCSeekBar) findViewById(R.id.viewsmssendpart1AOHPCTCSeekBar1);
Drawable thumbDrawable = getResources().getDrawable(R.drawable.ic_message); // Java 7兼容写法
mAOHPCTCSeekBar.setThumb(thumbDrawable);
mAOHPCTCSeekBar.setThumbOffset(20);
mAOHPCTCSeekBar.setOnOHPCListener(new AOHPCTCSeekBar.OnOHPCListener() {
@Override
public void onOHPCommit() {
sendSMS();
}
});
// 初始化短信内容输入框
TextView tvAOHPCTCSeekBarMSG = (TextView) findViewById(R.id.viewsmssendpart1TextView1);
tvAOHPCTCSeekBarMSG.setText(R.string.msg_100sendmsg); tvAOHPCTCSeekBarMSG.setText(R.string.msg_100sendmsg);
metSMSBody = (EditText) findViewById(R.id.viewsmssendpart1EditText1);
// 初始化发送消息框 if (mszSMSBody != null) {
metSMSBody = findViewById(R.id.viewsmssendpart1EditText1); metSMSBody.setText(mszSMSBody);
//metSMSBody.setBackground(drawableFrame); }
metSMSBody.setText(mszSMSBody);
} }
// // 核心优化:根据输入号码筛选列表(无结果则显示空列表)
// 设置号码搜索到的匹配位置 private void filterListByPhone(String inputPhone) {
// PhoneUtil phoneUtil = new PhoneUtil(this);
void setListViewPrePositionByPhone() { List<PhoneBean> allContacts = phoneUtil.getPhoneList();
int nPrePosition = getContractsDataPrePositionByPhone(metTO.getText().toString()); List<PhoneBean> matchedContacts = new ArrayList<PhoneBean>();
PhoneUtil phoneUtils = new PhoneUtil(this); // 遍历所有联系人,匹配包含输入号码的联系人
mtvTOName.setText(phoneUtils.getNameByPhone(metTO.getText().toString())); for (PhoneBean contact : allContacts) {
if (contact.getTelPhone().contains(inputPhone)
|| phoneUtil.isTheSamePhoneNumber(contact.getTelPhone(), inputPhone)) {
matchedContacts.add(contact);
}
}
mlvContracts.setSelected(false); LogUtils.d(TAG, "号码搜索:输入'" + inputPhone + "', 匹配" + matchedContacts.size() + "个结果");
mlvContracts.setSelection(nPrePosition);
// 用筛选结果更新列表(无结果则传入空列表)
initAdapter(matchedContacts.isEmpty() ? new ArrayList<PhoneBean>() : matchedContacts);
// 定位到第一个匹配项(如果有)
if (!matchedContacts.isEmpty()) {
mlvContracts.setSelection(0);
mtvTOName.setText(matchedContacts.get(0).getName());
} else {
mtvTOName.setText(""); // 无结果时清空姓名显示
}
} }
// 根据姓名搜索联系人
// private void setListViewPrePositionByName() {
// 设置名称搜索到的匹配位置 String searchName = metTONameSearch.getText().toString().trim();
// PhoneUtil phoneUtil = new PhoneUtil(this);
void setListViewPrePositionByName() { List<PhoneBean> matchedContacts = phoneUtil.getPhonesByName(searchName);
PhoneUtil phoneUtils = new PhoneUtil(this); initAdapter(matchedContacts);
List<PhoneBean> newPhoneData = phoneUtils.getPhonesByName(metTONameSearch.getText().toString()); if (!matchedContacts.isEmpty()) {
// 重新绑定数据 mlvContracts.setSelection(0);
initAdapter(newPhoneData); }
mlvContracts.setSelected(false);
} }
// // 初始定位号码对应的联系人
// 返回搜索到的匹配位置 private void setListViewPrePositionByPhone() {
// String inputPhone = metTO.getText().toString().trim();
int getContractsDataPrePositionByPhone(String szPhone) { if (inputPhone.isEmpty()) {
return;
}
filterListByPhone(inputPhone); // 复用筛选逻辑
}
// 获取号码匹配的位置(兼容旧逻辑)
private int getContractsDataPrePositionByPhone(String szPhone) {
if (mListPhoneBeanContracts == null || mListPhoneBeanContracts.isEmpty()) {
return 0;
}
for (int i = 0; i < mListPhoneBeanContracts.size(); i++) { for (int i = 0; i < mListPhoneBeanContracts.size(); i++) {
if (mListPhoneBeanContracts.get(i).getTelPhone().compareTo(szPhone) > -1) { PhoneBean bean = mListPhoneBeanContracts.get(i);
if (bean.getTelPhone().compareTo(szPhone) >= 0) {
return i; return i;
} }
} }
return 0; return 0;
} }
// 获取姓名匹配的位置(兼容旧逻辑)
// private int getContractsDataPrePositionByName(String szName) {
// 返回搜索到的匹配位置 if (mListPhoneBeanContracts == null || mListPhoneBeanContracts.isEmpty()) {
// return 0;
int getContractsDataPrePositionByName(String szName) { }
for (int i = 0; i < mListPhoneBeanContracts.size(); i++) { for (int i = 0; i < mListPhoneBeanContracts.size(); i++) {
if (mListPhoneBeanContracts.get(i).getName().startsWith(szName)) { if (mListPhoneBeanContracts.get(i).getName().startsWith(szName)) {
return i; return i;
} }
} }
return 0; return 0;
} }
// // 初始化或更新列表适配器
// 初始化适配器 private void initAdapter(List<PhoneBean> initData) {
// mAdapterData.clear(); // 清空旧数据
/*void initAdapter() { final PhoneUtil phoneUtil = new PhoneUtil(this);
// 初始化联系人数据适配器
mAdapterData = new ArrayList<>();
// 读取联系人数据
final PhoneUtil phoneUtils = new PhoneUtil(this);
mListPhoneBeanContracts = phoneUtils.getPhoneList();
// 映射联系人数据给适配器数据对象
for (int i = 0;i < mListPhoneBeanContracts.size();i++) {
Map<String,Object> map =new HashMap<>();
map.put(MAP_NAME, mListPhoneBeanContracts.get(i).getName());
map.put(MAP_PHONE, mListPhoneBeanContracts.get(i).getTelPhone());
mAdapterData.add(map);
}
// 绑定适配器与数据
mSimpleAdapter = new SimpleAdapter(ComposeSMSActivity.this, mAdapterData, R.layout.listview_contracts
, new String[]{MAP_NAME, MAP_PHONE}
, new int[]{R.id.listviewcontractsTextView1, R.id.listviewcontractsTextView2});
mSimpleAdapter.setDropDownViewResource(R.layout.listview_contracts);
mlvContracts.setAdapter(mSimpleAdapter);
mlvContracts.setOnItemClickListener(new ListView.OnItemClickListener() {
@Override // 确定数据源:传入的筛选数据或所有联系人
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
metTO.setText(mAdapterData.get(position).get(MAP_PHONE).toString());
mListPhoneBeanContracts = phoneUtils.getPhoneList();
mtvTOName.setText(phoneUtils.getNameByPhone(metTO.getText().toString()));
}
});
}*/
void initAdapter(List<PhoneBean> initData) {
// 初始化联系人数据适配器
mAdapterData = new ArrayList<>();
final PhoneUtil phoneUtils = new PhoneUtil(this);
if (initData != null) { if (initData != null) {
mListPhoneBeanContracts = initData; mListPhoneBeanContracts = initData;
} else { } else {
// 读取联系人数据 mListPhoneBeanContracts = phoneUtil.getPhoneList();
mListPhoneBeanContracts = phoneUtils.getPhoneList();
}
// 映射联系人数据给适配器数据对象
for (int i = 0;i < mListPhoneBeanContracts.size();i++) {
Map<String,Object> map =new HashMap<>();
map.put(MAP_NAME, mListPhoneBeanContracts.get(i).getName());
map.put(MAP_PHONE, mListPhoneBeanContracts.get(i).getTelPhone());
mAdapterData.add(map);
} }
// 绑定适配器与数据
mSimpleAdapter = new SimpleAdapter(ComposeSMSActivity.this, mAdapterData, R.layout.listview_contracts
, new String[]{MAP_NAME, MAP_PHONE}
, new int[]{R.id.listviewcontractsTextView1, R.id.listviewcontractsTextView2});
mSimpleAdapter.setDropDownViewResource(R.layout.listview_contracts);
mlvContracts.setAdapter(mSimpleAdapter);
mlvContracts.setOnItemClickListener(new ListView.OnItemClickListener() {
@Override // 转换数据为SimpleAdapter所需格式
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (mListPhoneBeanContracts != null) {
metTO.setText(mAdapterData.get(position).get(MAP_PHONE).toString()); for (PhoneBean bean : mListPhoneBeanContracts) {
mtvTOName.setText(phoneUtils.getNameByPhone(metTO.getText().toString())); Map<String, Object> map = new HashMap<String, Object>();
} map.put(MAP_NAME, bean.getName());
}); map.put(MAP_PHONE, bean.getTelPhone());
mAdapterData.add(map);
}
}
// 初始化或更新适配器
if (mSimpleAdapter == null) {
mSimpleAdapter = new SimpleAdapter(
ComposeSMSActivity.this,
mAdapterData,
R.layout.listview_contracts,
new String[]{MAP_NAME, MAP_PHONE},
new int[]{R.id.listviewcontractsTextView1, R.id.listviewcontractsTextView2}
);
mSimpleAdapter.setDropDownViewResource(R.layout.listview_contracts);
mlvContracts.setAdapter(mSimpleAdapter);
// 列表项点击事件
mlvContracts.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position < mAdapterData.size()) {
String phone = mAdapterData.get(position).get(MAP_PHONE).toString();
metTO.setText(phone);
mtvTOName.setText(phoneUtil.getNameByPhone(phone));
}
}
});
} else {
mSimpleAdapter.notifyDataSetChanged(); // 数据更新时通知适配器
}
}
// 发送短信逻辑
private void sendSMS() {
String phoneTo = metTO.getText().toString().trim();
if (phoneTo.isEmpty()) {
ToastUtils.show("没有设置接收号码。");
return;
}
String smsBody = metSMSBody.getText().toString().trim();
if (smsBody.isEmpty()) {
ToastUtils.show("没有消息内容可发送。");
return;
}
if (SMSUtil.sendMessageByInterface2(ComposeSMSActivity.this, phoneTo, smsBody)) {
finish();
}
} }
} }

View File

@@ -1,11 +1,10 @@
package cc.winboll.studio.mymessagemanager.utils; package cc.winboll.studio.mymessagemanager.utils;
/** /**
* @Author ZhanGSKen<zhangsken@188.com> * @Author ZhanGSKen&豆包大模型<zhangsken@188.com>
* @Date 2024/07/19 14:30:57 * @Date 2025/08/30 14:32
* @Describe 手机联系人工具类 * @Describe 手机联系人工具类
*/ */
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
@@ -202,7 +201,7 @@ public class PhoneUtil {
return ""; return "";
} }
boolean isTheSamePhoneNumber(String szNum1, String szNum2) { public boolean isTheSamePhoneNumber(String szNum1, String szNum2) {
if (szNum1.equals(szNum2)) { if (szNum1.equals(szNum2)) {
LogUtils.d(TAG, "szNum1.equals(szNum2)"); LogUtils.d(TAG, "szNum1.equals(szNum2)");
return true; return true;