From b374f3117a5feb2c2aa32a68e4e118e5fee45476 Mon Sep 17 00:00:00 2001 From: ZhanGSKen Date: Sat, 30 Aug 2025 21:15:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=81=94=E7=B3=BB=E4=BA=BA?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E4=B8=8E=E7=9F=AD=E4=BF=A1=E5=8F=91=E9=80=81?= =?UTF-8?q?=E6=A1=86=EF=BC=8C=E5=9C=A8=E6=90=9C=E7=B4=A2=E5=88=B0=E7=A9=BA?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=97=B6=E7=9A=84=E6=98=BE=E7=A4=BA=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mymessagemanager/build.properties | 4 +- .../activitys/ComposeSMSActivity.java | 440 ++++++++++-------- .../mymessagemanager/utils/PhoneUtil.java | 7 +- 3 files changed, 243 insertions(+), 208 deletions(-) diff --git a/mymessagemanager/build.properties b/mymessagemanager/build.properties index c81b523b..fe062c97 100644 --- a/mymessagemanager/build.properties +++ b/mymessagemanager/build.properties @@ -1,8 +1,8 @@ #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 libraryProject= baseVersion=15.3 publishVersion=15.3.4 -buildCount=0 +buildCount=4 baseBetaVersion=15.3.5 diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/activitys/ComposeSMSActivity.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/activitys/ComposeSMSActivity.java index 4ee64882..5229fd5f 100644 --- a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/activitys/ComposeSMSActivity.java +++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/activitys/ComposeSMSActivity.java @@ -1,5 +1,10 @@ package cc.winboll.studio.mymessagemanager.activitys; +/** + * @Author ZhanGSKen&豆包大模型 + * @Date 2025/08/30 14:32 + * @Describe 联系人查询与短信发送窗口 + */ import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; @@ -11,13 +16,17 @@ import android.widget.RelativeLayout; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toolbar; +import android.content.Intent; +import android.graphics.drawable.Drawable; + import cc.winboll.studio.libaes.views.AOHPCTCSeekBar; 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.utils.PhoneUtil; import cc.winboll.studio.mymessagemanager.utils.SMSUtil; import com.hjq.toast.ToastUtils; +import cc.winboll.studio.libappbase.LogUtils; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -26,255 +35,282 @@ import java.util.Map; public class ComposeSMSActivity extends BaseActivity { public static String TAG = "ComposeSMSActivity"; - 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"; - static String MAP_PHONE = "PHONE"; - - String mszSMSBody; - String mszScheme; - String mszPhoneTo; - TextView mtvTOName; - EditText metTONameSearch; - EditText metTO; - EditText metSMSBody; - SimpleAdapter mSimpleAdapter; - List> mAdapterData = new ArrayList<>(); - ListView mlvContracts; - List mListPhoneBeanContracts; - Toolbar mToolbar; - AOHPCTCSeekBar mAOHPCTCSeekBar; - RelativeLayout mrlContracts; + private String mszSMSBody; + private String mszScheme; + private String mszPhoneTo; + private TextView mtvTOName; + private EditText metTONameSearch; + private EditText metTO; + private EditText metSMSBody; + private SimpleAdapter mSimpleAdapter; + private List> mAdapterData = new ArrayList>(); + private ListView mlvContracts; + private List mListPhoneBeanContracts; + private Toolbar mToolbar; + private AOHPCTCSeekBar mAOHPCTCSeekBar; + private RelativeLayout mrlContracts; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_composesms); - mszSMSBody = getIntent().getStringExtra(EXTRA_SMSBODY); - mszScheme = getIntent().getData().getScheme(); - mszPhoneTo = getIntent().getData().getSchemeSpecificPart(); - if (!mszScheme.equals("smsto")) { - // 其他方式未支持就退出 - finish(); + + // 初始化Intent数据(增加空判断,避免NullPointerException) + Intent intent = getIntent(); + if (intent != null) { + mszSMSBody = intent.getStringExtra(EXTRA_SMSBODY); + if (intent.getData() != null) { + mszScheme = intent.getData().getScheme(); + mszPhoneTo = intent.getData().getSchemeSpecificPart(); + } } - // 初始化视图 + + // 校验启动方式,非smsto则退出 + if (mszScheme == null || !"smsto".equals(mszScheme)) { + ToastUtils.show("不支持的启动方式"); + finish(); + return; + } + initView(); - // 设置适配器 - initAdapter(null); - // 设置搜索到的匹配位置 + initAdapter(null); // 初始加载所有联系人 setListViewPrePositionByPhone(); } - // - // 初始化视图 - // - void initView() { - //Drawable drawableFrame = AppCompatResources.getDrawable(this, R.drawable.bg_frame); - + private void initView() { // 初始化标题栏 - mToolbar = findViewById(R.id.activitycomposesmsASupportToolbar1); + mToolbar = (Toolbar) findViewById(R.id.activitycomposesmsASupportToolbar1); mToolbar.setSubtitle(getString(R.string.activity_name_composesms)); setActionBar(mToolbar); - // 初始化联系人栏目框 - mtvTOName = findViewById(R.id.activitycomposesmsTextView2); - mrlContracts = findViewById(R.id.activitycomposesmsRelativeLayout1); - //mrlContracts.setBackground(drawableFrame); - 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) { - } + // 初始化联系人姓名显示和搜索栏 + mtvTOName = (TextView) findViewById(R.id.activitycomposesmsTextView2); + mrlContracts = (RelativeLayout) findViewById(R.id.activitycomposesmsRelativeLayout1); + metTONameSearch = (EditText) findViewById(R.id.activitycomposesmsEditText2); - @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) { + // 无操作 + } - // 初始化联系人列表 - mlvContracts = findViewById(R.id.activitycomposesmsListView1); - - // 初始化联系人输入框 - 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(); - } - } + @Override + public void afterTextChanged(Editable s) { + // 无操作 + } }); - // 初始化提示框 - 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); - - // 初始化发送消息框 - metSMSBody = findViewById(R.id.viewsmssendpart1EditText1); - //metSMSBody.setBackground(drawableFrame); - metSMSBody.setText(mszSMSBody); + metSMSBody = (EditText) findViewById(R.id.viewsmssendpart1EditText1); + if (mszSMSBody != null) { + metSMSBody.setText(mszSMSBody); + } } - // - // 设置号码搜索到的匹配位置 - // - void setListViewPrePositionByPhone() { - int nPrePosition = getContractsDataPrePositionByPhone(metTO.getText().toString()); + // 核心优化:根据输入号码筛选列表(无结果则显示空列表) + private void filterListByPhone(String inputPhone) { + PhoneUtil phoneUtil = new PhoneUtil(this); + List allContacts = phoneUtil.getPhoneList(); + List matchedContacts = new ArrayList(); - 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); - mlvContracts.setSelection(nPrePosition); + LogUtils.d(TAG, "号码搜索:输入'" + inputPhone + "', 匹配" + matchedContacts.size() + "个结果"); + + // 用筛选结果更新列表(无结果则传入空列表) + initAdapter(matchedContacts.isEmpty() ? new ArrayList() : matchedContacts); + + // 定位到第一个匹配项(如果有) + if (!matchedContacts.isEmpty()) { + mlvContracts.setSelection(0); + mtvTOName.setText(matchedContacts.get(0).getName()); + } else { + mtvTOName.setText(""); // 无结果时清空姓名显示 + } } - - // - // 设置名称搜索到的匹配位置 - // - void setListViewPrePositionByName() { - PhoneUtil phoneUtils = new PhoneUtil(this); - List newPhoneData = phoneUtils.getPhonesByName(metTONameSearch.getText().toString()); - // 重新绑定数据 - initAdapter(newPhoneData); - mlvContracts.setSelected(false); + // 根据姓名搜索联系人 + private void setListViewPrePositionByName() { + String searchName = metTONameSearch.getText().toString().trim(); + PhoneUtil phoneUtil = new PhoneUtil(this); + List matchedContacts = phoneUtil.getPhonesByName(searchName); + initAdapter(matchedContacts); + if (!matchedContacts.isEmpty()) { + mlvContracts.setSelection(0); + } } - // - // 返回搜索到的匹配位置 - // - int getContractsDataPrePositionByPhone(String szPhone) { + // 初始定位号码对应的联系人 + private void setListViewPrePositionByPhone() { + String inputPhone = metTO.getText().toString().trim(); + 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++) { - if (mListPhoneBeanContracts.get(i).getTelPhone().compareTo(szPhone) > -1) { + PhoneBean bean = mListPhoneBeanContracts.get(i); + if (bean.getTelPhone().compareTo(szPhone) >= 0) { return i; } - } return 0; } - - // - // 返回搜索到的匹配位置 - // - int getContractsDataPrePositionByName(String szName) { + // 获取姓名匹配的位置(兼容旧逻辑) + private int getContractsDataPrePositionByName(String szName) { + if (mListPhoneBeanContracts == null || mListPhoneBeanContracts.isEmpty()) { + return 0; + } for (int i = 0; i < mListPhoneBeanContracts.size(); i++) { if (mListPhoneBeanContracts.get(i).getName().startsWith(szName)) { return i; } - } return 0; } - // - // 初始化适配器 - // - /*void initAdapter() { - // 初始化联系人数据适配器 - mAdapterData = new ArrayList<>(); - // 读取联系人数据 - final PhoneUtil phoneUtils = new PhoneUtil(this); - mListPhoneBeanContracts = phoneUtils.getPhoneList(); - // 映射联系人数据给适配器数据对象 - for (int i = 0;i < mListPhoneBeanContracts.size();i++) { - Map 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() { + // 初始化或更新列表适配器 + private void initAdapter(List initData) { + mAdapterData.clear(); // 清空旧数据 + final PhoneUtil phoneUtil = new PhoneUtil(this); - @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 initData) { - // 初始化联系人数据适配器 - mAdapterData = new ArrayList<>(); - final PhoneUtil phoneUtils = new PhoneUtil(this); + // 确定数据源:传入的筛选数据或所有联系人 if (initData != null) { - mListPhoneBeanContracts = initData; - } else { - // 读取联系人数据 - mListPhoneBeanContracts = phoneUtils.getPhoneList(); - } - - // 映射联系人数据给适配器数据对象 - for (int i = 0;i < mListPhoneBeanContracts.size();i++) { - Map map =new HashMap<>(); - map.put(MAP_NAME, mListPhoneBeanContracts.get(i).getName()); - map.put(MAP_PHONE, mListPhoneBeanContracts.get(i).getTelPhone()); - mAdapterData.add(map); + mListPhoneBeanContracts = initData; + } else { + mListPhoneBeanContracts = phoneUtil.getPhoneList(); } - // 绑定适配器与数据 - 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()); - mtvTOName.setText(phoneUtils.getNameByPhone(metTO.getText().toString())); - } - }); + // 转换数据为SimpleAdapter所需格式 + if (mListPhoneBeanContracts != null) { + for (PhoneBean bean : mListPhoneBeanContracts) { + Map map = new HashMap(); + 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(); + } } } + diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/utils/PhoneUtil.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/utils/PhoneUtil.java index 5b48db15..d36ce2c5 100644 --- a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/utils/PhoneUtil.java +++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/utils/PhoneUtil.java @@ -1,11 +1,10 @@ package cc.winboll.studio.mymessagemanager.utils; /** - * @Author ZhanGSKen - * @Date 2024/07/19 14:30:57 + * @Author ZhanGSKen&豆包大模型 + * @Date 2025/08/30 14:32 * @Describe 手机联系人工具类 */ - import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; @@ -202,7 +201,7 @@ public class PhoneUtil { return ""; } - boolean isTheSamePhoneNumber(String szNum1, String szNum2) { + public boolean isTheSamePhoneNumber(String szNum1, String szNum2) { if (szNum1.equals(szNum2)) { LogUtils.d(TAG, "szNum1.equals(szNum2)"); return true;