Compare commits
18 Commits
appbase
...
mymessagem
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a40dbcfb61 | ||
![]() |
4d344b299b | ||
![]() |
37b0867d34 | ||
![]() |
b505156211 | ||
![]() |
91b30fb576 | ||
![]() |
ab3ac72d54 | ||
![]() |
870e9a94fb | ||
![]() |
2421ecb943 | ||
![]() |
687fff7216 | ||
![]() |
3795cf8631 | ||
![]() |
b374f3117a | ||
![]() |
6d9adc124e | ||
![]() |
52f738b45b | ||
![]() |
9ece6778b7 | ||
![]() |
e13c8e7af0 | ||
![]() |
a4988b5b68 | ||
![]() |
5507126f6b | ||
![]() |
d381c29452 |
@@ -115,7 +115,6 @@
|
|||||||
# 本项目要实际运用需要注意以下几个步骤:
|
# 本项目要实际运用需要注意以下几个步骤:
|
||||||
# 在项目根目录下:
|
# 在项目根目录下:
|
||||||
## ★. 项目模块编译环境设置(必须),settings.gradle-demo 要复制为 settings.gradle,并取消相应项目模块的注释。
|
## ★. 项目模块编译环境设置(必须),settings.gradle-demo 要复制为 settings.gradle,并取消相应项目模块的注释。
|
||||||
## ★. 项目模块编译环境设置(必须) 在根目录拷贝 gradle.properties-androidx-demo 或者 gradle.properties-android-demo 文件为 gradle.properties。
|
|
||||||
## ★. 项目 Android SDK 编译环境设置(可选),local.properties-demo 要复制为 local.properties,并按需要设置 Android SDK 目录。
|
## ★. 项目 Android SDK 编译环境设置(可选),local.properties-demo 要复制为 local.properties,并按需要设置 Android SDK 目录。
|
||||||
## ★. 应用签名密钥 keystore 设置问题。一般调试编译只需用【Termux】cd 进 GenKeyStore 目录执行 $ bash gen_debug_keystore.sh 命令即可完成设置。
|
## ★. 应用签名密钥 keystore 设置问题。一般调试编译只需用【Termux】cd 进 GenKeyStore 目录执行 $ bash gen_debug_keystore.sh 命令即可完成设置。
|
||||||
## ☆. 应用 WiBoLL 签名密钥配置问题<非必须考虑>。设置时需要 clone 【keystore】模块源码并拷贝模块目录的 appkey.jks 与 appkey.keystore 到项目根目录即可。
|
## ☆. 应用 WiBoLL 签名密钥配置问题<非必须考虑>。设置时需要 clone 【keystore】模块源码并拷贝模块目录的 appkey.jks 与 appkey.keystore 到项目根目录即可。
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Sat Jun 28 12:59:51 HKT 2025
|
#Thu Jun 19 20:42:40 HKT 2025
|
||||||
stageCount=3
|
stageCount=2
|
||||||
libraryProject=libaes
|
libraryProject=libaes
|
||||||
baseVersion=15.9
|
baseVersion=15.9
|
||||||
publishVersion=15.9.2
|
publishVersion=15.9.1
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.9.3
|
baseBetaVersion=15.9.2
|
||||||
|
@@ -83,7 +83,7 @@ public class AboutActivity extends AppCompatActivity implements IWinBoLLActivity
|
|||||||
appInfo.setAppGitOwner("Studio");
|
appInfo.setAppGitOwner("Studio");
|
||||||
appInfo.setAppGitAPPBranch(szBranchName);
|
appInfo.setAppGitAPPBranch(szBranchName);
|
||||||
appInfo.setAppGitAPPSubProjectFolder(szBranchName);
|
appInfo.setAppGitAPPSubProjectFolder(szBranchName);
|
||||||
appInfo.setAppHomePage("https://discuz.winboll.cc/forum.php?mod=viewthread&tid=3&extra=page%3D1");
|
appInfo.setAppHomePage("https://discuz.winboll.cc/forum.php?mod=viewthread&tid=2&fromuid=1");
|
||||||
appInfo.setAppAPKName("AES");
|
appInfo.setAppAPKName("AES");
|
||||||
appInfo.setAppAPKFolderName("AES");
|
appInfo.setAppAPKFolderName("AES");
|
||||||
//appInfo.setIsAddDebugTools(false);
|
//appInfo.setIsAddDebugTools(false);
|
||||||
|
@@ -67,7 +67,7 @@ dependencies {
|
|||||||
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
|
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
|
||||||
//api 'androidx.fragment:fragment:1.1.0'
|
//api 'androidx.fragment:fragment:1.1.0'
|
||||||
|
|
||||||
api 'cc.winboll.studio:libaes:15.9.2'
|
api 'cc.winboll.studio:libaes:15.8.0'
|
||||||
api 'cc.winboll.studio:libapputils:15.8.4'
|
api 'cc.winboll.studio:libapputils:15.8.2'
|
||||||
api 'cc.winboll.studio:libappbase:15.8.4'
|
api 'cc.winboll.studio:libappbase:15.8.2'
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Sat Jun 28 05:02:54 GMT 2025
|
#Thu Jun 19 12:49:47 GMT 2025
|
||||||
stageCount=0
|
stageCount=0
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=15.0
|
baseVersion=15.0
|
||||||
publishVersion=15.0.0
|
publishVersion=15.0.0
|
||||||
buildCount=27
|
buildCount=26
|
||||||
baseBetaVersion=15.0.1
|
baseBetaVersion=15.0.1
|
||||||
|
@@ -30,7 +30,7 @@ android {
|
|||||||
// versionName 更新后需要手动设置
|
// versionName 更新后需要手动设置
|
||||||
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
|
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
|
||||||
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
|
||||||
versionName "15.9"
|
versionName "15.8"
|
||||||
if(true) {
|
if(true) {
|
||||||
versionName = genVersionName("${versionName}")
|
versionName = genVersionName("${versionName}")
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Sun Aug 31 23:37:38 HKT 2025
|
#Mon Jun 09 09:38:19 HKT 2025
|
||||||
stageCount=6
|
stageCount=9
|
||||||
libraryProject=libappbase
|
libraryProject=libappbase
|
||||||
baseVersion=15.9
|
baseVersion=15.8
|
||||||
publishVersion=15.9.5
|
publishVersion=15.8.8
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.9.6
|
baseBetaVersion=15.8.9
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
https://github.com/aJIEw/PhoneCallApp.git
|
https://github.com/aJIEw/PhoneCallApp.git
|
||||||
|
|
||||||
#### 介绍
|
#### 介绍
|
||||||
这是可以根据正则表达式匹配拦截骚扰电话的手机拨号应用。
|
通讯录与拨号
|
||||||
|
|
||||||
#### 软件架构
|
#### 软件架构
|
||||||
适配安卓应用 [AIDE Pro] 的 Gradle 编译结构。
|
适配安卓应用 [AIDE Pro] 的 Gradle 编译结构。
|
||||||
|
@@ -45,9 +45,9 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
api 'cc.winboll.studio:libaes:15.9.2'
|
api 'cc.winboll.studio:libaes:15.8.0'
|
||||||
api 'cc.winboll.studio:libapputils:15.8.4'
|
api 'cc.winboll.studio:libapputils:15.8.1'
|
||||||
api 'cc.winboll.studio:libappbase:15.8.4'
|
api 'cc.winboll.studio:libappbase:15.8.1'
|
||||||
|
|
||||||
// 权限请求框架:https://github.com/getActivity/XXPermissions
|
// 权限请求框架:https://github.com/getActivity/XXPermissions
|
||||||
api 'com.github.getActivity:XXPermissions:18.63'
|
api 'com.github.getActivity:XXPermissions:18.63'
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Thu Jul 17 09:57:24 HKT 2025
|
#Tue May 20 13:02:18 HKT 2025
|
||||||
stageCount=12
|
stageCount=3
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=15.3
|
baseVersion=15.3
|
||||||
publishVersion=15.3.11
|
publishVersion=15.3.2
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.3.12
|
baseBetaVersion=15.3.3
|
||||||
|
@@ -79,12 +79,12 @@ public class AboutActivity extends AppCompatActivity implements IWinBoLLActivity
|
|||||||
APPInfo appInfo = new APPInfo();
|
APPInfo appInfo = new APPInfo();
|
||||||
appInfo.setAppName("Contacts");
|
appInfo.setAppName("Contacts");
|
||||||
appInfo.setAppIcon(cc.winboll.studio.libaes.R.drawable.ic_winboll);
|
appInfo.setAppIcon(cc.winboll.studio.libaes.R.drawable.ic_winboll);
|
||||||
appInfo.setAppDescription("这是可以根据正则表达式匹配拦截骚扰电话的手机拨号应用。");
|
appInfo.setAppDescription("通讯录与拨号");
|
||||||
appInfo.setAppGitName("APPBase");
|
appInfo.setAppGitName("APP");
|
||||||
appInfo.setAppGitOwner("Studio");
|
appInfo.setAppGitOwner("Studio");
|
||||||
appInfo.setAppGitAPPBranch(szBranchName);
|
appInfo.setAppGitAPPBranch(szBranchName);
|
||||||
appInfo.setAppGitAPPSubProjectFolder(szBranchName);
|
appInfo.setAppGitAPPSubProjectFolder(szBranchName);
|
||||||
appInfo.setAppHomePage("https://discuz.winboll.cc/forum.php?mod=viewthread&tid=4&extra=page%3D1");
|
appInfo.setAppHomePage("https://www.winboll.cc/studio/details.php?app=Contacts");
|
||||||
appInfo.setAppAPKName("Contacts");
|
appInfo.setAppAPKName("Contacts");
|
||||||
appInfo.setAppAPKFolderName("Contacts");
|
appInfo.setAppAPKFolderName("Contacts");
|
||||||
return new AboutView(mContext, appInfo);
|
return new AboutView(mContext, appInfo);
|
||||||
|
@@ -198,9 +198,6 @@ public class SettingsActivity extends AppCompatActivity implements IWinBoLLActiv
|
|||||||
settingsModel.setDunTotalCount(Integer.parseInt(etDunTotalCount.getText().toString()));
|
settingsModel.setDunTotalCount(Integer.parseInt(etDunTotalCount.getText().toString()));
|
||||||
settingsModel.setDunResumeSecondCount(Integer.parseInt(etDunResumeSecondCount.getText().toString()));
|
settingsModel.setDunResumeSecondCount(Integer.parseInt(etDunResumeSecondCount.getText().toString()));
|
||||||
settingsModel.setDunResumeCount(Integer.parseInt(etDunResumeCount.getText().toString()));
|
settingsModel.setDunResumeCount(Integer.parseInt(etDunResumeCount.getText().toString()));
|
||||||
|
|
||||||
// 应用效果提示
|
|
||||||
ToastUtils.show((settingsModel.getDunTotalCount() == 1)?"电话骚扰防御力几乎为0。":String.format("以下设置将在连拨%d次后接通电话。", settingsModel.getDunTotalCount()));
|
|
||||||
}
|
}
|
||||||
settingsModel.setIsEnableDun(isEnableDun);
|
settingsModel.setIsEnableDun(isEnableDun);
|
||||||
Rules.getInstance(this).saveDun();
|
Rules.getInstance(this).saveDun();
|
||||||
@@ -210,7 +207,6 @@ public class SettingsActivity extends AppCompatActivity implements IWinBoLLActiv
|
|||||||
etDunTotalCount.setText(Integer.toString(settingsModel.getDunTotalCount()));
|
etDunTotalCount.setText(Integer.toString(settingsModel.getDunTotalCount()));
|
||||||
etDunResumeSecondCount.setText(Integer.toString(settingsModel.getDunResumeSecondCount()));
|
etDunResumeSecondCount.setText(Integer.toString(settingsModel.getDunResumeSecondCount()));
|
||||||
etDunResumeCount.setText(Integer.toString(settingsModel.getDunResumeCount()));
|
etDunResumeCount.setText(Integer.toString(settingsModel.getDunResumeCount()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateStreamVolumeTextView() {
|
void updateStreamVolumeTextView() {
|
||||||
@@ -247,9 +243,6 @@ public class SettingsActivity extends AppCompatActivity implements IWinBoLLActiv
|
|||||||
Rules.getInstance(this).resetDefaultBoBullToonURL();
|
Rules.getInstance(this).resetDefaultBoBullToonURL();
|
||||||
EditText etBoBullToonURL = findViewById(R.id.bobulltoonurl_et);
|
EditText etBoBullToonURL = findViewById(R.id.bobulltoonurl_et);
|
||||||
etBoBullToonURL.setText(Rules.getInstance(this).getBoBullToonURL());
|
etBoBullToonURL.setText(Rules.getInstance(this).getBoBullToonURL());
|
||||||
|
|
||||||
final TomCat tomCat = TomCat.getInstance(this);
|
|
||||||
tomCat.cleanBoBullToon();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDownloadBoBullToon(View view) {
|
public void onDownloadBoBullToon(View view) {
|
||||||
@@ -337,8 +330,4 @@ public class SettingsActivity extends AppCompatActivity implements IWinBoLLActiv
|
|||||||
public void onAbout(View view) {
|
public void onAbout(View view) {
|
||||||
App.getWinBoLLActivityManager().startWinBoLLActivity(this, AboutActivity.class);
|
App.getWinBoLLActivityManager().startWinBoLLActivity(this, AboutActivity.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onLogView(View view) {
|
|
||||||
App.getWinBoLLActivityManager().startLogActivity(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -5,18 +5,13 @@ package cc.winboll.studio.contacts.adapters;
|
|||||||
* @Date 2025/02/26 13:09:32
|
* @Date 2025/02/26 13:09:32
|
||||||
* @Describe CallLogAdapter
|
* @Describe CallLogAdapter
|
||||||
*/
|
*/
|
||||||
import android.content.ClipData;
|
|
||||||
import android.content.ClipboardManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.PopupMenu;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import cc.winboll.studio.contacts.R;
|
import cc.winboll.studio.contacts.R;
|
||||||
@@ -52,38 +47,6 @@ public class CallLogAdapter extends RecyclerView.Adapter<CallLogAdapter.CallLogV
|
|||||||
public void onBindViewHolder(@NonNull CallLogViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull CallLogViewHolder holder, int position) {
|
||||||
final CallLogModel callLog = callLogList.get(position);
|
final CallLogModel callLog = callLogList.get(position);
|
||||||
holder.phoneNumber.setText(callLog.getPhoneNumber() + "☎" + mContactUtils.getContactsName(callLog.getPhoneNumber()));
|
holder.phoneNumber.setText(callLog.getPhoneNumber() + "☎" + mContactUtils.getContactsName(callLog.getPhoneNumber()));
|
||||||
holder.phoneNumber.setOnLongClickListener(new View.OnLongClickListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onLongClick(View p1) {
|
|
||||||
// 弹出复制菜单
|
|
||||||
PopupMenu menu = new PopupMenu(mContext, holder.phoneNumber);
|
|
||||||
//加载菜单资源
|
|
||||||
menu.getMenuInflater().inflate(R.menu.toolbar_calllog_phonenumber, menu.getMenu());
|
|
||||||
//设置点击事件的响应
|
|
||||||
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onMenuItemClick(MenuItem menuItem) {
|
|
||||||
int nItemId = menuItem.getItemId();
|
|
||||||
if (nItemId == R.id.item_calllog_phonenumber_copy) {
|
|
||||||
// Gets a handle to the clipboard service.
|
|
||||||
ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
|
|
||||||
// Creates a new text clip to put on the clipboard
|
|
||||||
ClipData clip = ClipData.newPlainText("simple text", callLog.getPhoneNumber());
|
|
||||||
// Set the clipboard's primary clip.
|
|
||||||
clipboard.setPrimaryClip(clip);
|
|
||||||
Toast.makeText(mContext, "Copy to clipboard.", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//一定要调用show()来显示弹出式菜单
|
|
||||||
menu.show();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
holder.callStatus.setText(callLog.getCallStatus());
|
holder.callStatus.setText(callLog.getCallStatus());
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
|
||||||
holder.callDate.setText(dateFormat.format(callLog.getCallDate()));
|
holder.callDate.setText(dateFormat.format(callLog.getCallDate()));
|
||||||
|
@@ -5,25 +5,19 @@ package cc.winboll.studio.contacts.adapters;
|
|||||||
* @Date 2025/02/26 13:35:44
|
* @Date 2025/02/26 13:35:44
|
||||||
* @Describe ContactAdapter
|
* @Describe ContactAdapter
|
||||||
*/
|
*/
|
||||||
import android.content.ClipData;
|
|
||||||
import android.content.ClipboardManager;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.Button;
|
||||||
import android.widget.PopupMenu;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import cc.winboll.studio.contacts.R;
|
import cc.winboll.studio.contacts.R;
|
||||||
import cc.winboll.studio.contacts.beans.ContactModel;
|
import cc.winboll.studio.contacts.beans.ContactModel;
|
||||||
import cc.winboll.studio.libaes.views.AOHPCTCSeekBar;
|
|
||||||
import com.hjq.toast.ToastUtils;
|
import com.hjq.toast.ToastUtils;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import cc.winboll.studio.libaes.views.AOHPCTCSeekBar;
|
||||||
|
|
||||||
public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactViewHolder> {
|
public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactViewHolder> {
|
||||||
|
|
||||||
@@ -32,10 +26,8 @@ public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactV
|
|||||||
private static final int REQUEST_CALL_PHONE = 1;
|
private static final int REQUEST_CALL_PHONE = 1;
|
||||||
|
|
||||||
private List<ContactModel> contactList;
|
private List<ContactModel> contactList;
|
||||||
Context mContext;
|
|
||||||
|
|
||||||
public ContactAdapter(Context context, List<ContactModel> contactList) {
|
public ContactAdapter(List<ContactModel> contactList) {
|
||||||
mContext = context;
|
|
||||||
this.contactList = contactList;
|
this.contactList = contactList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,37 +41,6 @@ public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactV
|
|||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull ContactViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull ContactViewHolder holder, int position) {
|
||||||
final ContactModel contact = contactList.get(position);
|
final ContactModel contact = contactList.get(position);
|
||||||
holder.llPhoneNumberMain.setOnLongClickListener(new View.OnLongClickListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onLongClick(View p1) {
|
|
||||||
// 弹出复制菜单
|
|
||||||
PopupMenu menu = new PopupMenu(mContext, holder.llPhoneNumberMain);
|
|
||||||
//加载菜单资源
|
|
||||||
menu.getMenuInflater().inflate(R.menu.toolbar_contact_phonenumber, menu.getMenu());
|
|
||||||
//设置点击事件的响应
|
|
||||||
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onMenuItemClick(MenuItem menuItem) {
|
|
||||||
int nItemId = menuItem.getItemId();
|
|
||||||
if (nItemId == R.id.item_contact_phonenumber_copy) {
|
|
||||||
// Gets a handle to the clipboard service.
|
|
||||||
ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
|
|
||||||
// Creates a new text clip to put on the clipboard
|
|
||||||
ClipData clip = ClipData.newPlainText("simple text", contact.getNumber());
|
|
||||||
// Set the clipboard's primary clip.
|
|
||||||
clipboard.setPrimaryClip(clip);
|
|
||||||
Toast.makeText(mContext, "Copy to clipboard.", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//一定要调用show()来显示弹出式菜单
|
|
||||||
menu.show();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
holder.contactName.setText(contact.getName());
|
holder.contactName.setText(contact.getName());
|
||||||
holder.contactNumber.setText(contact.getNumber());
|
holder.contactNumber.setText(contact.getNumber());
|
||||||
|
|
||||||
@@ -108,14 +69,12 @@ public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactV
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class ContactViewHolder extends RecyclerView.ViewHolder {
|
public class ContactViewHolder extends RecyclerView.ViewHolder {
|
||||||
LinearLayout llPhoneNumberMain;
|
|
||||||
TextView contactName;
|
TextView contactName;
|
||||||
TextView contactNumber;
|
TextView contactNumber;
|
||||||
AOHPCTCSeekBar dialAOHPCTCSeekBar;
|
AOHPCTCSeekBar dialAOHPCTCSeekBar;
|
||||||
|
|
||||||
public ContactViewHolder(@NonNull View itemView) {
|
public ContactViewHolder(@NonNull View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
llPhoneNumberMain = itemView.findViewById(R.id.itemcontactLinearLayout1);
|
|
||||||
contactName = itemView.findViewById(R.id.contact_name);
|
contactName = itemView.findViewById(R.id.contact_name);
|
||||||
contactNumber = itemView.findViewById(R.id.contact_number);
|
contactNumber = itemView.findViewById(R.id.contact_number);
|
||||||
dialAOHPCTCSeekBar = itemView.findViewById(R.id.aohpctcseekbar_dial);
|
dialAOHPCTCSeekBar = itemView.findViewById(R.id.aohpctcseekbar_dial);
|
||||||
|
@@ -7,7 +7,6 @@ package cc.winboll.studio.contacts.adapters;
|
|||||||
*/
|
*/
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
@@ -21,7 +20,6 @@ import cc.winboll.studio.contacts.R;
|
|||||||
import cc.winboll.studio.contacts.beans.PhoneConnectRuleModel;
|
import cc.winboll.studio.contacts.beans.PhoneConnectRuleModel;
|
||||||
import cc.winboll.studio.contacts.dun.Rules;
|
import cc.winboll.studio.contacts.dun.Rules;
|
||||||
import cc.winboll.studio.contacts.views.LeftScrollView;
|
import cc.winboll.studio.contacts.views.LeftScrollView;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
|
||||||
import cc.winboll.studio.libappbase.dialogs.YesNoAlertDialog;
|
import cc.winboll.studio.libappbase.dialogs.YesNoAlertDialog;
|
||||||
import com.hjq.toast.ToastUtils;
|
import com.hjq.toast.ToastUtils;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -62,10 +60,6 @@ public class PhoneConnectRuleAdapter extends RecyclerView.Adapter<RecyclerView.V
|
|||||||
final SimpleViewHolder simpleViewHolder = (SimpleViewHolder) holder;
|
final SimpleViewHolder simpleViewHolder = (SimpleViewHolder) holder;
|
||||||
String szView = model.getRuleText().trim().equals("") ?"[NULL]": model.getRuleText();
|
String szView = model.getRuleText().trim().equals("") ?"[NULL]": model.getRuleText();
|
||||||
simpleViewHolder.tvRuleText.setText(szView);
|
simpleViewHolder.tvRuleText.setText(szView);
|
||||||
simpleViewHolder.checkBoxAllow.setChecked(model.isAllowConnection());
|
|
||||||
simpleViewHolder.checkBoxAllow.setEnabled(false);
|
|
||||||
simpleViewHolder.checkBoxEnable.setChecked(model.isEnable());
|
|
||||||
simpleViewHolder.checkBoxEnable.setEnabled(false);
|
|
||||||
simpleViewHolder.scrollView.setOnActionListener(new LeftScrollView.OnActionListener(){
|
simpleViewHolder.scrollView.setOnActionListener(new LeftScrollView.OnActionListener(){
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -221,22 +215,16 @@ public class PhoneConnectRuleAdapter extends RecyclerView.Adapter<RecyclerView.V
|
|||||||
|
|
||||||
private final LeftScrollView scrollView;
|
private final LeftScrollView scrollView;
|
||||||
private final TextView tvRuleText;
|
private final TextView tvRuleText;
|
||||||
CheckBox checkBoxAllow;
|
|
||||||
CheckBox checkBoxEnable;
|
|
||||||
|
|
||||||
|
|
||||||
public SimpleViewHolder(@NonNull ViewGroup parent, @NonNull View itemView) {
|
public SimpleViewHolder(@NonNull ViewGroup parent, @NonNull View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
scrollView = itemView.findViewById(R.id.scrollView);
|
scrollView = itemView.findViewById(R.id.scrollView);
|
||||||
LayoutInflater inflater = LayoutInflater.from(itemView.getContext());
|
//tvRuleText = itemView.findViewById(R.id.ruletext_tv);
|
||||||
View viewContent = inflater.inflate(R.layout.view_phone_connect_rule_simple_content, parent, false);
|
tvRuleText = new TextView(itemView.getContext());
|
||||||
tvRuleText = viewContent.findViewById(R.id.ruletext_tv);
|
|
||||||
checkBoxAllow = viewContent.findViewById(R.id.checkbox_allow);
|
|
||||||
checkBoxEnable = viewContent.findViewById(R.id.checkbox_enable);
|
|
||||||
//tvRuleText = new TextView(itemView.getContext());
|
|
||||||
scrollView.setContentWidth(parent.getWidth());
|
scrollView.setContentWidth(parent.getWidth());
|
||||||
//scrollView.setContentWidth(600);
|
//scrollView.setContentWidth(600);
|
||||||
scrollView.addContentLayout(viewContent);
|
scrollView.addContentLayout(tvRuleText);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -255,9 +243,5 @@ public class PhoneConnectRuleAdapter extends RecyclerView.Adapter<RecyclerView.V
|
|||||||
buttonConfirm = itemView.findViewById(R.id.button_confirm);
|
buttonConfirm = itemView.findViewById(R.id.button_confirm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCheckBoxTouchListener(CheckBox checkBox) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -123,7 +123,7 @@ public class TomCat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新新文件
|
// 更新新文件
|
||||||
if (downloadAndExtractZip(zipUrl, destinationFolder)) {
|
if(downloadAndExtractZip(zipUrl, destinationFolder)) {
|
||||||
LogUtils.d(TAG, "ZIP 文件下载并解压成功。");
|
LogUtils.d(TAG, "ZIP 文件下载并解压成功。");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -155,19 +155,6 @@ public class TomCat {
|
|||||||
return mContext.getExternalFilesDir(TAG);
|
return mContext.getExternalFilesDir(TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanBoBullToon() {
|
|
||||||
String destinationFolder = getWorkingFolder().getPath(); // 替换为实际的目标文件夹路径
|
|
||||||
// 删除旧文件
|
|
||||||
File fOldFolder = new File(destinationFolder);
|
|
||||||
if (fOldFolder.exists()) {
|
|
||||||
deleteFolderRecursive(fOldFolder);
|
|
||||||
fOldFolder.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
ToastUtils.show("已清空 BoBullToon 数据!");
|
|
||||||
LogUtils.d(TAG, "已清空 BoBullToon 数据");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean loadPhoneBoBullToon() {
|
public boolean loadPhoneBoBullToon() {
|
||||||
listPhoneBoBullToon.clear();
|
listPhoneBoBullToon.clear();
|
||||||
File fBoBullToon = new File(getWorkingFolder(), "bobulltoon");
|
File fBoBullToon = new File(getWorkingFolder(), "bobulltoon");
|
||||||
|
@@ -145,14 +145,6 @@ public class Rules {
|
|||||||
LogUtils.d(TAG, String.format("isDefend == %s\nisConnect == %s", isDefend, isConnect));
|
LogUtils.d(TAG, String.format("isDefend == %s\nisConnect == %s", isDefend, isConnect));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检验拨不通号码群
|
|
||||||
if (!isDefend && MainService.isPhoneInBoBullToon(phoneNumber)) {
|
|
||||||
LogUtils.d(TAG, String.format("PhoneNumber %s\n Is In BoBullToon", phoneNumber));
|
|
||||||
isDefend = true;
|
|
||||||
isConnect = false;
|
|
||||||
LogUtils.d(TAG, String.format("isDefend == %s\nisConnect == %s", isDefend, isConnect));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询通讯录是否有该联系人
|
// 查询通讯录是否有该联系人
|
||||||
boolean isPhoneInContacts = ContactUtils.getInstance(mContext).isPhoneInContacts(mContext, phoneNumber);
|
boolean isPhoneInContacts = ContactUtils.getInstance(mContext).isPhoneInContacts(mContext, phoneNumber);
|
||||||
if (!isDefend) {
|
if (!isDefend) {
|
||||||
@@ -166,6 +158,14 @@ public class Rules {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检验拨不通号码群
|
||||||
|
if (!isDefend && MainService.isPhoneInBoBullToon(phoneNumber)) {
|
||||||
|
LogUtils.d(TAG, String.format("PhoneNumber %s\n Is In BoBullToon", phoneNumber));
|
||||||
|
isDefend = true;
|
||||||
|
isConnect = false;
|
||||||
|
LogUtils.d(TAG, String.format("isDefend == %s\nisConnect == %s", isDefend, isConnect));
|
||||||
|
}
|
||||||
|
|
||||||
// 正则匹配规则名单校验
|
// 正则匹配规则名单校验
|
||||||
if (!isDefend) {
|
if (!isDefend) {
|
||||||
for (int i = 0; i < _PhoneConnectRuleModelList.size(); i++) {
|
for (int i = 0; i < _PhoneConnectRuleModelList.size(); i++) {
|
||||||
|
@@ -73,7 +73,7 @@ public class ContactsFragment extends Fragment {
|
|||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
recyclerView = view.findViewById(R.id.contacts_recycler_view);
|
recyclerView = view.findViewById(R.id.contacts_recycler_view);
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
contactAdapter = new ContactAdapter(getContext(), contactList);
|
contactAdapter = new ContactAdapter(contactList);
|
||||||
recyclerView.setAdapter(contactAdapter);
|
recyclerView.setAdapter(contactAdapter);
|
||||||
|
|
||||||
searchEditText = view.findViewById(R.id.search_edit_text);
|
searchEditText = view.findViewById(R.id.search_edit_text);
|
||||||
|
@@ -47,8 +47,8 @@ public class LeftScrollView extends HorizontalScrollView {
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addContentLayout(View viewContent) {
|
public void addContentLayout(TextView textView) {
|
||||||
contentLayout.addView(viewContent, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
|
contentLayout.addView(textView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContentWidth(int contentWidth) {
|
public void setContentWidth(int contentWidth) {
|
||||||
|
@@ -269,19 +269,6 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center_horizontal">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="<<==向左拉动列表项可编辑内容"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -300,12 +287,6 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="right">
|
android:gravity="right">
|
||||||
|
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="LogView"
|
|
||||||
android:onClick="onLogView"/>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@@ -15,10 +15,8 @@
|
|||||||
<Button
|
<Button
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Add Demo Rules(While size is 0) and Test"
|
android:text="Test Main"
|
||||||
android:onClick="onTestMain"
|
android:onClick="onTestMain"/>
|
||||||
android:textSize="10sp"
|
|
||||||
android:textAllCaps="false"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -45,8 +43,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Test Phone"
|
android:text="Test Phone"
|
||||||
android:onClick="onTestPhone"
|
android:onClick="onTestPhone"/>
|
||||||
android:textAllCaps="false"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@@ -9,8 +9,7 @@
|
|||||||
<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:id="@+id/itemcontactLinearLayout1">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/contact_number"
|
android:id="@+id/contact_number"
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
android:id="@+id/checkbox_allow"
|
android:id="@+id/checkbox_allow"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="连接"/>
|
android:text="允许连接"/>
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:id="@+id/checkbox_enable"
|
android:id="@+id/checkbox_enable"
|
||||||
|
@@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<HorizontalScrollView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:scrollbars="none"
|
||||||
|
android:id="@+id/scrollView">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<!-- 内容区域 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/content_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:background="@color/white">
|
||||||
|
<!-- 这里放置你的列表项内容 -->
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_view"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textSize="16sp"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/action_layout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:background="@color/lightgray">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/edit_btn"
|
||||||
|
android:layout_width="80dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="编辑"
|
||||||
|
android:background="@color/blue" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/delete_btn"
|
||||||
|
android:layout_width="80dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="删除"
|
||||||
|
android:background="@color/red" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</HorizontalScrollView>
|
@@ -1,35 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:gravity="center_vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Text"
|
|
||||||
android:layout_weight="1.0"
|
|
||||||
android:id="@+id/ruletext_tv"/>
|
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/checkbox_allow"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="连接"
|
|
||||||
android:clickable="false"
|
|
||||||
android:focusable="false"/>
|
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/checkbox_enable"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="启用"
|
|
||||||
android:clickable="false"
|
|
||||||
android:focusable="false"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/item_calllog_phonenumber_copy"
|
|
||||||
android:title="Copy"/>
|
|
||||||
|
|
||||||
</menu>
|
|
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/item_contact_phonenumber_copy"
|
|
||||||
android:title="Copy"/>
|
|
||||||
|
|
||||||
</menu>
|
|
@@ -2,6 +2,6 @@
|
|||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<string name="app_name">Contacts</string>
|
<string name="app_name">Contacts</string>
|
||||||
<string name="default_bobulltoon_url">https://gitea.winboll.cc/Studio/BoBullToon/archive/main.zip</string>
|
<string name="default_bobulltoon_url">http://10.8.0.12:3000/Studio/BoBullToon/archive/main.zip</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -21,8 +21,8 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
api 'cc.winboll.studio:libapputils:15.8.4'
|
api 'cc.winboll.studio:libapputils:15.8.2'
|
||||||
api 'cc.winboll.studio:libappbase:15.8.4'
|
api 'cc.winboll.studio:libappbase:15.8.2'
|
||||||
|
|
||||||
// 吐司类库
|
// 吐司类库
|
||||||
api 'com.github.getActivity:ToastUtils:10.5'
|
api 'com.github.getActivity:ToastUtils:10.5'
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Sat Jun 28 12:59:30 HKT 2025
|
#Thu Jun 19 20:42:26 HKT 2025
|
||||||
stageCount=3
|
stageCount=2
|
||||||
libraryProject=libaes
|
libraryProject=libaes
|
||||||
baseVersion=15.9
|
baseVersion=15.9
|
||||||
publishVersion=15.9.2
|
publishVersion=15.9.1
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.9.3
|
baseBetaVersion=15.9.2
|
||||||
|
@@ -107,7 +107,7 @@ public class AboutView extends LinearLayout {
|
|||||||
mszAppDescription = mAPPInfo.getAppDescription();
|
mszAppDescription = mAPPInfo.getAppDescription();
|
||||||
mnAppIcon = mAPPInfo.getAppIcon();
|
mnAppIcon = mAPPInfo.getAppIcon();
|
||||||
|
|
||||||
mszWinBoLLServerHost = GlobalApplication.isDebuging() ? "https://yun-preivew.winboll.cc": "https://yun.winboll.cc";
|
mszWinBoLLServerHost = GlobalApplication.isDebuging() ? "https://dev.winboll.cc": "https://www.winboll.cc";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mszAppVersionName = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName;
|
mszAppVersionName = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName;
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Mon Aug 18 03:56:26 HKT 2025
|
#Mon Jun 09 09:38:19 HKT 2025
|
||||||
stageCount=6
|
stageCount=9
|
||||||
libraryProject=libappbase
|
libraryProject=libappbase
|
||||||
baseVersion=15.9
|
baseVersion=15.8
|
||||||
publishVersion=15.9.5
|
publishVersion=15.8.8
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.9.6
|
baseBetaVersion=15.8.9
|
||||||
|
@@ -45,9 +45,9 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
api 'cc.winboll.studio:libaes:15.9.2'
|
api 'cc.winboll.studio:libaes:15.9.3'
|
||||||
api 'cc.winboll.studio:libapputils:15.8.4'
|
api 'cc.winboll.studio:libapputils:15.8.6'
|
||||||
api 'cc.winboll.studio:libappbase:15.8.4'
|
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'
|
||||||
api 'com.github.getActivity:ToastUtils:10.5'
|
api 'com.github.getActivity:ToastUtils:10.5'
|
||||||
@@ -55,6 +55,8 @@ dependencies {
|
|||||||
api 'org.jsoup:jsoup:1.13.1'
|
api 'org.jsoup:jsoup:1.13.1'
|
||||||
api 'com.squareup.okhttp3:okhttp:4.4.1'
|
api 'com.squareup.okhttp3:okhttp:4.4.1'
|
||||||
|
|
||||||
|
api 'com.belerweb:pinyin4j:2.5.1'
|
||||||
|
|
||||||
// 权限请求框架:https://github.com/getActivity/XXPermissions
|
// 权限请求框架:https://github.com/getActivity/XXPermissions
|
||||||
api 'com.github.getActivity:XXPermissions:18.63'
|
api 'com.github.getActivity:XXPermissions:18.63'
|
||||||
api 'com.baoyz.pullrefreshlayout:library:1.2.0'
|
api 'com.baoyz.pullrefreshlayout:library:1.2.0'
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Thu Jul 03 13:50:15 HKT 2025
|
#Sat Sep 06 01:57:20 HKT 2025
|
||||||
stageCount=2
|
stageCount=9
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=15.3
|
baseVersion=15.3
|
||||||
publishVersion=15.3.1
|
publishVersion=15.3.8
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.3.2
|
baseBetaVersion=15.3.9
|
||||||
|
@@ -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,166 +35,331 @@ 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;
|
||||||
EditText metTO;
|
private EditText metSMSBody;
|
||||||
EditText metSMSBody;
|
private SimpleAdapter mSimpleAdapter;
|
||||||
SimpleAdapter mSimpleAdapter;
|
private List<Map<String, Object>> mAdapterData = new ArrayList<Map<String, Object>>();
|
||||||
List<Map<String,Object>> mAdapterData = new ArrayList<>();
|
private ListView mlvContracts;
|
||||||
ListView mlvContracts;
|
private List<PhoneBean> mListPhoneBeanContracts;
|
||||||
List<PhoneBean> mListPhoneBeanContracts;
|
private Toolbar mToolbar;
|
||||||
Toolbar mToolbar;
|
private AOHPCTCSeekBar mAOHPCTCSeekBar;
|
||||||
AOHPCTCSeekBar mAOHPCTCSeekBar;
|
private RelativeLayout mrlContracts;
|
||||||
RelativeLayout mrlContracts;
|
|
||||||
|
|
||||||
@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);
|
||||||
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();
|
setListViewPrePositionByPhone();
|
||||||
// 设置搜索到的匹配位置
|
|
||||||
setListViewPrePosition();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
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);
|
||||||
|
|
||||||
// 初始化联系人栏目框
|
// 初始化联系人姓名显示和搜索栏
|
||||||
mrlContracts = findViewById(R.id.activitycomposesmsRelativeLayout1);
|
mtvTOName = (TextView) findViewById(R.id.activitycomposesmsTextView2);
|
||||||
//mrlContracts.setBackground(drawableFrame);
|
mrlContracts = (RelativeLayout) findViewById(R.id.activitycomposesmsRelativeLayout1);
|
||||||
|
metTONameSearch = (EditText) findViewById(R.id.activitycomposesmsEditText2);
|
||||||
|
|
||||||
// 初始化联系人列表
|
// 姓名搜索框文本变化监听
|
||||||
mlvContracts = findViewById(R.id.activitycomposesmsListView1);
|
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
|
||||||
metTO = findViewById(R.id.activitycomposesmsEditText1);
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
metTO.setText(mszPhoneTo);
|
// 无操作
|
||||||
metTO.addTextChangedListener(new TextWatcher() {
|
}
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
||||||
setListViewPrePosition();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
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);
|
||||||
|
mlvContracts.setChoiceMode(ListView.CHOICE_MODE_SINGLE); // 开启单选,与布局中一致
|
||||||
|
|
||||||
|
// 初始化号码输入框(核心:优化文本变化监听逻辑)
|
||||||
|
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 setListViewPrePosition() {
|
List<PhoneBean> allContacts = phoneUtil.getPhoneList();
|
||||||
int nPrePosition = getContractsDataPrePosition(metTO.getText().toString());
|
List<PhoneBean> matchedContacts = new ArrayList<PhoneBean>();
|
||||||
mlvContracts.setSelected(false);
|
|
||||||
mlvContracts.setSelection(nPrePosition);
|
// 遍历所有联系人,匹配包含输入号码的联系人
|
||||||
|
for (PhoneBean contact : allContacts) {
|
||||||
|
if (contact.getTelPhone().contains(inputPhone)
|
||||||
|
|| phoneUtil.isTheSamePhoneNumber(contact.getTelPhone(), inputPhone)) {
|
||||||
|
matchedContacts.add(contact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogUtils.d(TAG, "号码搜索:输入'" + inputPhone + "', 匹配" + matchedContacts.size() + "个结果");
|
||||||
|
|
||||||
|
// 用筛选结果更新列表(无结果则传入空列表)
|
||||||
|
initAdapter(matchedContacts.isEmpty() ? new ArrayList<PhoneBean>() : matchedContacts);
|
||||||
|
|
||||||
|
// 定位并选中匹配项(如果有)
|
||||||
|
if (!matchedContacts.isEmpty()) {
|
||||||
|
boolean isFound = false;
|
||||||
|
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 {
|
||||||
|
mtvTOName.setText(""); // 无结果时清空姓名显示
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// 根据姓名搜索联系人
|
||||||
// 返回搜索到的匹配位置
|
private void setListViewPrePositionByName() {
|
||||||
//
|
String searchName = metTONameSearch.getText().toString().trim();
|
||||||
int getContractsDataPrePosition(String szPhone) {
|
PhoneUtil phoneUtil = new PhoneUtil(this);
|
||||||
|
List<PhoneBean> matchedContacts = phoneUtil.getPhonesByName(searchName);
|
||||||
|
initAdapter(matchedContacts);
|
||||||
|
if (!matchedContacts.isEmpty()) {
|
||||||
|
// 选中第一个结果并设置样式
|
||||||
|
mlvContracts.setSelection(0);
|
||||||
|
mlvContracts.setItemChecked(0, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始定位号码对应的联系人
|
||||||
|
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++) {
|
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()) {
|
||||||
void initAdapter() {
|
return 0;
|
||||||
// 初始化联系人数据适配器
|
|
||||||
mAdapterData = new ArrayList<>();
|
|
||||||
// 读取联系人数据
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
// 绑定适配器与数据
|
for (int i = 0; i < mListPhoneBeanContracts.size(); i++) {
|
||||||
mSimpleAdapter = new SimpleAdapter(ComposeSMSActivity.this, mAdapterData, R.layout.listview_contracts
|
if (mListPhoneBeanContracts.get(i).getName().startsWith(szName)) {
|
||||||
, new String[]{MAP_NAME, MAP_PHONE}
|
return i;
|
||||||
, new int[]{R.id.listviewcontractsTextView1, R.id.listviewcontractsTextView2});
|
}
|
||||||
mSimpleAdapter.setDropDownViewResource(R.layout.listview_contracts);
|
}
|
||||||
mlvContracts.setAdapter(mSimpleAdapter);
|
return 0;
|
||||||
mlvContracts.setOnItemClickListener(new ListView.OnItemClickListener() {
|
}
|
||||||
|
|
||||||
@Override
|
// 初始化或更新列表适配器
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
private void initAdapter(List<PhoneBean> initData) {
|
||||||
metTO.setText(mAdapterData.get(position).get(MAP_PHONE).toString());
|
mAdapterData.clear(); // 清空旧数据
|
||||||
|
final PhoneUtil phoneUtil = new PhoneUtil(this);
|
||||||
|
|
||||||
}
|
// 确定数据源:传入的筛选数据或所有联系人
|
||||||
});
|
if (initData != null) {
|
||||||
|
mListPhoneBeanContracts = initData;
|
||||||
|
} else {
|
||||||
|
mListPhoneBeanContracts = phoneUtil.getPhoneList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换数据为SimpleAdapter所需格式
|
||||||
|
if (mListPhoneBeanContracts != null) {
|
||||||
|
for (PhoneBean bean : mListPhoneBeanContracts) {
|
||||||
|
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()) {
|
||||||
|
// 1. 主动设置当前项为选中状态
|
||||||
|
mlvContracts.setItemChecked(position, true);
|
||||||
|
// 2. 更新号码输入框和姓名显示
|
||||||
|
String phone = mAdapterData.get(position).get(MAP_PHONE).toString();
|
||||||
|
metTO.setText(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 {
|
||||||
|
// 数据更新时,先取消所有旧选中状态,再通知适配器刷新
|
||||||
|
mlvContracts.clearChoices();
|
||||||
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,11 +4,16 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewTreeObserver;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.AbsListView;
|
import android.widget.AbsListView;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ScrollView;
|
import android.widget.ScrollView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@@ -16,19 +21,17 @@ import android.widget.Toolbar;
|
|||||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
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.SMSActivity;
|
|
||||||
import cc.winboll.studio.mymessagemanager.adapters.SMSArrayAdapter;
|
import cc.winboll.studio.mymessagemanager.adapters.SMSArrayAdapter;
|
||||||
import cc.winboll.studio.mymessagemanager.utils.AddressUtils;
|
import cc.winboll.studio.mymessagemanager.utils.AddressUtils;
|
||||||
import cc.winboll.studio.mymessagemanager.utils.SMSUtil;
|
import cc.winboll.studio.mymessagemanager.utils.SMSUtil;
|
||||||
import cc.winboll.studio.mymessagemanager.utils.ViewUtil;
|
import cc.winboll.studio.mymessagemanager.utils.ViewUtil;
|
||||||
|
import cc.winboll.studio.mymessagemanager.views.BottomPositionFixedScrollView;
|
||||||
import cc.winboll.studio.mymessagemanager.views.SMSListViewForScrollView;
|
import cc.winboll.studio.mymessagemanager.views.SMSListViewForScrollView;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
public class SMSActivity extends BaseActivity {
|
public class SMSActivity extends BaseActivity {
|
||||||
public static String TAG = "SMSActivity";
|
public static String TAG = "SMSActivity";
|
||||||
|
|
||||||
public static final String ACTION_NOTIFY_SMS_CHANGED = "cc.winboll.studio.mymessagemanager.activitys.SMSActivity.ACTION_NOTIFY_SMS_CHANGED";
|
public static final String ACTION_NOTIFY_SMS_CHANGED = "cc.winboll.studio.mymessagemanager.activitys.SMSActivity.ACTION_NOTIFY_SMS_CHANGED";
|
||||||
|
|
||||||
public static final String EXTRA_PHONE = "Phone";
|
public static final String EXTRA_PHONE = "Phone";
|
||||||
final static int MSG_SET_FOCUS = 0;
|
final static int MSG_SET_FOCUS = 0;
|
||||||
|
|
||||||
@@ -36,10 +39,11 @@ public class SMSActivity extends BaseActivity {
|
|||||||
Toolbar mToolbar;
|
Toolbar mToolbar;
|
||||||
String mszPhoneTo;
|
String mszPhoneTo;
|
||||||
SMSArrayAdapter mSMSArrayAdapter;
|
SMSArrayAdapter mSMSArrayAdapter;
|
||||||
ScrollView mScrollView;
|
BottomPositionFixedScrollView mScrollView1;
|
||||||
EditText metSMSBody;
|
EditText metSMSBody;
|
||||||
SMSActivityBroadcastReceiver mSMSActivityBroadcastReceiver;
|
SMSActivityBroadcastReceiver mSMSActivityBroadcastReceiver;
|
||||||
Handler mSetFocusHandler;
|
Handler mSetFocusHandler;
|
||||||
|
private boolean isImeVisible = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -47,45 +51,90 @@ public class SMSActivity extends BaseActivity {
|
|||||||
setContentView(R.layout.activity_sms);
|
setContentView(R.layout.activity_sms);
|
||||||
|
|
||||||
initView();
|
initView();
|
||||||
mSetFocusHandler = new MyHandler(SMSActivity.this);
|
|
||||||
scrollScrollView();
|
scrollScrollView();
|
||||||
|
setupImeStatusListener();
|
||||||
|
|
||||||
// 每隔一定时间设置输入框获得焦点
|
// 新增:监听窗口加载完成,触发mScrollView1滚动到底部
|
||||||
//
|
setupScrollToBottomAfterWindowLoaded();
|
||||||
new Thread() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(1500);
|
|
||||||
} catch (InterruptedException e) {}
|
|
||||||
Message message = mSetFocusHandler.obtainMessage(MSG_SET_FOCUS);
|
|
||||||
mSetFocusHandler.sendMessage(message);
|
|
||||||
}
|
|
||||||
}}.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// 新增:窗口加载完成后让mScrollView1滚动到底部
|
||||||
// 设置输入框获得焦点的类
|
private void setupScrollToBottomAfterWindowLoaded() {
|
||||||
//
|
final View rootView = findViewById(android.R.id.content);
|
||||||
static class MyHandler extends Handler {
|
// 监听根布局绘制完成(窗口加载完成的标志)
|
||||||
WeakReference<SMSActivity> mActivity;
|
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||||
MyHandler(SMSActivity activity) {
|
@Override
|
||||||
mActivity = new WeakReference<SMSActivity>(activity);
|
public void onGlobalLayout() {
|
||||||
}
|
// 滚动到底部
|
||||||
public void handleMessage(Message msg) {
|
mScrollView1.post(new Runnable() {
|
||||||
SMSActivity theActivity = mActivity.get();
|
@Override
|
||||||
switch (msg.what) {
|
public void run() {
|
||||||
case MSG_SET_FOCUS:
|
mScrollView1.fullScroll(ScrollView.FOCUS_DOWN);
|
||||||
theActivity.metSMSBody.setFocusable(true);
|
}
|
||||||
theActivity.metSMSBody.requestFocus();
|
});
|
||||||
break;
|
|
||||||
default:
|
// 移除监听,避免重复触发
|
||||||
break;
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
}
|
rootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||||
super.handleMessage(msg);
|
} else {
|
||||||
}
|
rootView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupImeStatusListener() {
|
||||||
|
final View rootView = findViewById(android.R.id.content);
|
||||||
|
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||||
|
@Override
|
||||||
|
public void onGlobalLayout() {
|
||||||
|
int rootViewHeight = rootView.getHeight();
|
||||||
|
int screenHeight = getResources().getDisplayMetrics().heightPixels;
|
||||||
|
int imeThreshold = dp2px(200);
|
||||||
|
|
||||||
|
boolean currentImeVisible = (screenHeight - rootViewHeight) > imeThreshold;
|
||||||
|
|
||||||
|
if (currentImeVisible != isImeVisible) {
|
||||||
|
isImeVisible = currentImeVisible;
|
||||||
|
setupScrollView1Height();
|
||||||
|
if (!isImeVisible) {
|
||||||
|
metSMSBody.clearFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
|
rootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||||
|
} else {
|
||||||
|
rootView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||||
|
}
|
||||||
|
setupImeStatusListener();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private int dp2px(int dp) {
|
||||||
|
return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static class MyHandler extends Handler {
|
||||||
|
WeakReference<SMSActivity> mActivity;
|
||||||
|
MyHandler(SMSActivity activity) {
|
||||||
|
mActivity = new WeakReference<SMSActivity>(activity);
|
||||||
|
}
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
SMSActivity theActivity = mActivity.get();
|
||||||
|
switch (msg.what) {
|
||||||
|
case MSG_SET_FOCUS:
|
||||||
|
theActivity.metSMSBody.setFocusable(true);
|
||||||
|
theActivity.metSMSBody.requestFocus();
|
||||||
|
theActivity.setupScrollView1Height();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
super.handleMessage(msg);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
@@ -94,135 +143,130 @@ public class SMSActivity extends BaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void initView() {
|
void initView() {
|
||||||
// 发送端空号码退出
|
|
||||||
mszPhoneTo = getIntent().getStringExtra(EXTRA_PHONE);
|
mszPhoneTo = getIntent().getStringExtra(EXTRA_PHONE);
|
||||||
if (mszPhoneTo == null || mszPhoneTo.trim().equals("")) {
|
if (mszPhoneTo == null || mszPhoneTo.trim().equals("")) {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化标题栏
|
mToolbar = (Toolbar) findViewById(R.id.activitysmsASupportToolbar1);
|
||||||
mToolbar = findViewById(R.id.activitysmsASupportToolbar1);
|
|
||||||
mToolbar.setSubtitle(getString(R.string.activity_name_smsinphone) + " < Phone : " + AddressUtils.getFormattedAddress(mszPhoneTo) + " >");
|
mToolbar.setSubtitle(getString(R.string.activity_name_smsinphone) + " < Phone : " + AddressUtils.getFormattedAddress(mszPhoneTo) + " >");
|
||||||
setActionBar(mToolbar);
|
setActionBar(mToolbar);
|
||||||
|
|
||||||
// 初始化滚动窗口
|
mScrollView1 = (BottomPositionFixedScrollView) findViewById(R.id.activitysmsScrollView1);
|
||||||
mScrollView = findViewById(R.id.activitysmsinphoneScrollView1);
|
|
||||||
|
|
||||||
// 初始化发送消息框
|
metSMSBody = (EditText) findViewById(R.id.viewsmssendpart1EditText1);
|
||||||
//Drawable drawableFrame = AppCompatResources.getDrawable(this, R.drawable.bg_frame);
|
metSMSBody.setOnClickListener(new View.OnClickListener() {
|
||||||
metSMSBody = findViewById(R.id.viewsmssendpart1EditText1);
|
@Override
|
||||||
//metSMSBody.setBackground(drawableFrame);
|
public void onClick(View v) {
|
||||||
|
setupScrollView1Height();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
metSMSBody.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onFocusChange(View v, boolean hasFocus) {
|
||||||
|
setupScrollView1Height();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 初始化发送拉动控件
|
final AOHPCTCSeekBar aOHPCTCSeekBar = (AOHPCTCSeekBar) findViewById(R.id.viewsmssendpart1AOHPCTCSeekBar1);
|
||||||
final AOHPCTCSeekBar aOHPCTCSeekBar = findViewById(R.id.viewsmssendpart1AOHPCTCSeekBar1);
|
|
||||||
aOHPCTCSeekBar.setThumb(getDrawable(R.drawable.ic_message));
|
aOHPCTCSeekBar.setThumb(getDrawable(R.drawable.ic_message));
|
||||||
aOHPCTCSeekBar.setThumbOffset(20);
|
aOHPCTCSeekBar.setThumbOffset(20);
|
||||||
aOHPCTCSeekBar.setOnOHPCListener(
|
aOHPCTCSeekBar.setOnOHPCListener(new AOHPCTCSeekBar.OnOHPCListener() {
|
||||||
new AOHPCTCSeekBar.OnOHPCListener(){
|
@Override
|
||||||
@Override
|
public void onOHPCommit() {
|
||||||
public void onOHPCommit() {
|
sendSMS();
|
||||||
//Toast.makeText(getApplication(), "Send", Toast.LENGTH_SHORT).show();
|
}
|
||||||
sendSMS();
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化提示框
|
TextView tvAOHPCTCSeekBarMSG = (TextView) findViewById(R.id.viewsmssendpart1TextView1);
|
||||||
TextView tvAOHPCTCSeekBarMSG = findViewById(R.id.viewsmssendpart1TextView1);
|
|
||||||
tvAOHPCTCSeekBarMSG.setText(R.string.msg_100sendmsg);
|
tvAOHPCTCSeekBarMSG.setText(R.string.msg_100sendmsg);
|
||||||
|
|
||||||
mlvSMS = (SMSListViewForScrollView) findViewById(R.id.activitysmsinphoneListView1);
|
mlvSMS = (SMSListViewForScrollView) findViewById(R.id.activitysmsSMSListViewForScrollView1);
|
||||||
|
|
||||||
// 准备数据
|
|
||||||
mSMSArrayAdapter = new SMSArrayAdapter(SMSActivity.this, mszPhoneTo);
|
mSMSArrayAdapter = new SMSArrayAdapter(SMSActivity.this, mszPhoneTo);
|
||||||
mlvSMS.setAdapter(mSMSArrayAdapter);
|
mlvSMS.setAdapter(mSMSArrayAdapter);
|
||||||
|
|
||||||
// 设置短信列表滚动到底部就取消已发送的通知消息
|
|
||||||
//
|
|
||||||
mlvSMS.setOnScrollListener(new AbsListView.OnScrollListener() {
|
mlvSMS.setOnScrollListener(new AbsListView.OnScrollListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
public void onScrollStateChanged(AbsListView view, int scrollState) {}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
||||||
if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) {
|
if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) {
|
||||||
// 滑动到了底部
|
mSMSArrayAdapter.cancelMessageNotification();
|
||||||
mSMSArrayAdapter.cancelMessageNotification();
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
mSMSActivityBroadcastReceiver = new SMSActivityBroadcastReceiver();
|
mSMSActivityBroadcastReceiver = new SMSActivityBroadcastReceiver();
|
||||||
IntentFilter intentFilter = new IntentFilter();
|
IntentFilter intentFilter = new IntentFilter(ACTION_NOTIFY_SMS_CHANGED);
|
||||||
intentFilter.addAction(ACTION_NOTIFY_SMS_CHANGED);
|
|
||||||
LocalBroadcastManager.getInstance(this).registerReceiver(mSMSActivityBroadcastReceiver, intentFilter);
|
LocalBroadcastManager.getInstance(this).registerReceiver(mSMSActivityBroadcastReceiver, intentFilter);
|
||||||
|
|
||||||
/*SMSView mSMSView = findViewById(R.id.viewsmssendSMSView1);
|
|
||||||
mSMSView.setSMSType(SMSView.SMSType.SEND);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
private void setupScrollView1Height() {
|
||||||
// 更新信息列表
|
mScrollView1.postDelayed(new Runnable() {
|
||||||
//
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final ScrollView scrollView2 = (ScrollView) findViewById(R.id.activitysmsScrollView2);
|
||||||
|
final BottomPositionFixedScrollView scrollView1 = (BottomPositionFixedScrollView) findViewById(R.id.activitysmsScrollView1);
|
||||||
|
final View includeView = findViewById(R.id.activitysmsinclude1);
|
||||||
|
|
||||||
|
scrollView2.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int scrollView2Height = scrollView2.getHeight();
|
||||||
|
int includeHeight = includeView.getHeight();
|
||||||
|
int targetHeight = Math.max(scrollView2Height - includeHeight, 0);
|
||||||
|
|
||||||
|
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) scrollView1.getLayoutParams();
|
||||||
|
params.height = targetHeight;
|
||||||
|
scrollView1.setLayoutParams(params);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
public void updateSMSView() {
|
public void updateSMSView() {
|
||||||
mSMSArrayAdapter.reLoadSMSList(SMSActivity.this, mszPhoneTo);
|
mSMSArrayAdapter.reLoadSMSList(SMSActivity.this, mszPhoneTo);
|
||||||
mSMSArrayAdapter.notifyDataSetChanged();
|
mSMSArrayAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// 滚动消息文本框
|
|
||||||
//
|
|
||||||
void scrollScrollView() {
|
void scrollScrollView() {
|
||||||
|
ViewUtil.scrollScrollView(mScrollView1);
|
||||||
ViewUtil.scrollScrollView(mScrollView);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// 发送短信
|
|
||||||
//
|
|
||||||
void sendSMS() {
|
void sendSMS() {
|
||||||
// 空消息不发送
|
|
||||||
String szSMSBody = metSMSBody.getText().toString();
|
String szSMSBody = metSMSBody.getText().toString();
|
||||||
if (szSMSBody.equals("")) {
|
if (szSMSBody.equals("")) {
|
||||||
Toast.makeText(getApplication(), "没有消息内容可发送。", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getApplication(), "没有消息内容可发送。", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送短信
|
|
||||||
if (SMSUtil.sendMessageByInterface2(this, mszPhoneTo, szSMSBody)) {
|
if (SMSUtil.sendMessageByInterface2(this, mszPhoneTo, szSMSBody)) {
|
||||||
metSMSBody.setText("");
|
metSMSBody.setText("");
|
||||||
new Handler().postDelayed(new Runnable(){
|
metSMSBody.clearFocus();
|
||||||
@Override
|
new Handler().postDelayed(new Runnable() {
|
||||||
public void run() {
|
@Override
|
||||||
updateSMSView();
|
public void run() {
|
||||||
ViewUtil.scrollScrollView(mScrollView);
|
updateSMSView();
|
||||||
}
|
ViewUtil.scrollScrollView(mScrollView1);
|
||||||
}, 1000);
|
}
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SMSActivityBroadcastReceiver extends BroadcastReceiver {
|
class SMSActivityBroadcastReceiver extends BroadcastReceiver {
|
||||||
|
public SMSActivityBroadcastReceiver() {}
|
||||||
public SMSActivityBroadcastReceiver() {
|
|
||||||
//LogUtils.d(TAG, "SMSActivityBroadcastReceiver()");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
switch (intent.getAction()) {
|
if (ACTION_NOTIFY_SMS_CHANGED.equals(intent.getAction())) {
|
||||||
case ACTION_NOTIFY_SMS_CHANGED :
|
updateSMSView();
|
||||||
//Toast.makeText(context, "ACTION_NOTIFY_SMS_CHANGED", Toast.LENGTH_SHORT).show();
|
ViewUtil.scrollScrollView(mScrollView1);
|
||||||
updateSMSView();
|
} else {
|
||||||
ViewUtil.scrollScrollView(mScrollView);
|
throw new IllegalStateException("Unexpected value: " + intent.getAction());
|
||||||
//LogUtils.d(TAG, "ACTION_NOTIFY_SMS_CHANGED");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("Unexpected value: " + intent.getAction());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
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;
|
||||||
@@ -11,6 +11,7 @@ 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 java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -18,6 +19,11 @@ 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 {
|
||||||
|
|
||||||
@@ -38,28 +44,137 @@ public class PhoneUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 读取所有联系人
|
// 读取所有联系人
|
||||||
//
|
|
||||||
public List<PhoneBean> getPhoneList() {
|
public List<PhoneBean> getPhoneList() {
|
||||||
List<PhoneBean> listPhoneBean = new ArrayList<>();
|
List<PhoneBean> listPhoneBean = new ArrayList<>();
|
||||||
ContentResolver cr = mContext.getContentResolver();
|
ContentResolver cr = mContext.getContentResolver();
|
||||||
Cursor cursor = cr.query(mUriPhoneContent, new String[]{NUMBER, DISPLAY_NAME}, null, null, null);
|
Cursor cursor = cr.query(mUriPhoneContent, new String[]{NUMBER, DISPLAY_NAME}, null, null, null);
|
||||||
while (cursor.moveToNext()) {
|
if (cursor != null) {
|
||||||
PhoneBean phoneBean = new PhoneBean(cursor.getString(1), cursor.getString(0).replaceAll("\\s", ""));
|
while (cursor.moveToNext()) {
|
||||||
listPhoneBean.add(phoneBean);
|
// 去除号码中的空格
|
||||||
|
String phone = cursor.getString(0).replaceAll("\\s", "");
|
||||||
|
String name = cursor.getString(1);
|
||||||
|
PhoneBean phoneBean = new PhoneBean(name, phone);
|
||||||
|
listPhoneBean.add(phoneBean);
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
}
|
}
|
||||||
cursor.close();
|
|
||||||
|
|
||||||
|
// 按电话号码排序
|
||||||
Collections.sort(listPhoneBean, new Comparator<PhoneBean>() {
|
Collections.sort(listPhoneBean, new Comparator<PhoneBean>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(PhoneBean o1, PhoneBean o2) {
|
public int compare(PhoneBean o1, PhoneBean o2) {
|
||||||
return o1.getTelPhone().compareTo(o2.getTelPhone());
|
return o1.getTelPhone().compareTo(o2.getTelPhone());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return listPhoneBean;
|
return listPhoneBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据联系人名称查询号码(兼容拼音查询)
|
||||||
|
* @param keyword 搜索关键词(支持汉字、拼音、拼音首字母)
|
||||||
|
* @return 匹配的联系人列表(包含姓名和号码)
|
||||||
|
*/
|
||||||
|
public List<PhoneBean> getPhonesByName(String keyword) {
|
||||||
|
List<PhoneBean> result = new ArrayList<>();
|
||||||
|
if (keyword == null || keyword.trim().isEmpty()) {
|
||||||
|
return result; // 关键词为空,返回空列表
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有联系人
|
||||||
|
List<PhoneBean> allContacts = getPhoneList();
|
||||||
|
// 统一转为小写,忽略大小写
|
||||||
|
String keywordLower = keyword.trim().toLowerCase();
|
||||||
|
|
||||||
|
for (PhoneBean contact : allContacts) {
|
||||||
|
String name = contact.getName();
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 直接匹配姓名(包含关键词)
|
||||||
|
if (name.toLowerCase().contains(keywordLower)) {
|
||||||
|
result.add(contact);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 匹配姓名的全拼(包含关键词)
|
||||||
|
String namePinyin = getPinyin(name).toLowerCase();
|
||||||
|
if (namePinyin.contains(keywordLower)) {
|
||||||
|
result.add(contact);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 匹配姓名的拼音首字母(包含关键词)
|
||||||
|
String namePinyinFirstLetter = getPinyinFirstLetter(name).toLowerCase();
|
||||||
|
if (namePinyinFirstLetter.contains(keywordLower)) {
|
||||||
|
result.add(contact);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将汉字转为全拼(不带声调,小写)
|
||||||
|
* 例如:"张三" → "zhangsan"
|
||||||
|
*/
|
||||||
|
private String getPinyin(String chinese) {
|
||||||
|
StringBuilder pinyin = new StringBuilder();
|
||||||
|
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
|
||||||
|
format.setCaseType(HanyuPinyinCaseType.LOWERCASE); // 小写
|
||||||
|
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); // 不带声调
|
||||||
|
|
||||||
|
char[] chars = chinese.toCharArray();
|
||||||
|
for (char c : chars) {
|
||||||
|
// 如果是汉字,转换为拼音;否则直接拼接(如字母、数字、符号)
|
||||||
|
if (Character.toString(c).matches("[\\u4e00-\\u9fa5]")) {
|
||||||
|
try {
|
||||||
|
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
|
||||||
|
if (pinyinArray != null && pinyinArray.length > 0) {
|
||||||
|
pinyin.append(pinyinArray[0]); // 取第一个拼音(多音字默认取第一个)
|
||||||
|
}
|
||||||
|
} catch (BadHanyuPinyinOutputFormatCombination e) {
|
||||||
|
LogUtils.e(TAG, "拼音转换失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pinyin.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pinyin.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将汉字转为拼音首字母(小写)
|
||||||
|
* 例如:"张三" → "zs"
|
||||||
|
*/
|
||||||
|
private String getPinyinFirstLetter(String chinese) {
|
||||||
|
StringBuilder firstLetters = new StringBuilder();
|
||||||
|
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
|
||||||
|
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
|
||||||
|
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
|
||||||
|
|
||||||
|
char[] chars = chinese.toCharArray();
|
||||||
|
for (char c : chars) {
|
||||||
|
if (Character.toString(c).matches("[\\u4e00-\\u9fa5]")) {
|
||||||
|
try {
|
||||||
|
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
|
||||||
|
if (pinyinArray != null && pinyinArray.length > 0) {
|
||||||
|
// 取拼音首字母(如"zhang" → "z")
|
||||||
|
firstLetters.append(pinyinArray[0].charAt(0));
|
||||||
|
}
|
||||||
|
} catch (BadHanyuPinyinOutputFormatCombination e) {
|
||||||
|
LogUtils.e(TAG, "拼音首字母转换失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 非汉字直接拼接首字符(如"李3" → "l3")
|
||||||
|
firstLetters.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return firstLetters.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isPhoneInContacts(String szPhone) {
|
public boolean isPhoneInContacts(String szPhone) {
|
||||||
List<PhoneBean> listPhoneDto = getPhoneList();
|
List<PhoneBean> listPhoneDto = getPhoneList();
|
||||||
LogUtils.d(TAG, String.format("isPhoneInContacts(...) listPhoneDto.size() %d", listPhoneDto.size()));
|
LogUtils.d(TAG, String.format("isPhoneInContacts(...) listPhoneDto.size() %d", listPhoneDto.size()));
|
||||||
@@ -71,22 +186,36 @@ public class PhoneUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isTheSamePhoneNumber(String szNum1, String szNum2) {
|
public String getNameByPhone(String szPhone) {
|
||||||
//LogUtils.d(TAG, String.format("szNum1 %s\nszNum2 %s", szNum1, szNum2));
|
if (szPhone == null || szPhone.equals("")) {
|
||||||
if(szNum1.equals(szNum2)) {
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PhoneBean> listPhoneDto = getPhoneList();
|
||||||
|
LogUtils.d(TAG, String.format("getNameByPhone(...) listPhoneDto.size() %d", listPhoneDto.size()));
|
||||||
|
for (int i = 0; i < listPhoneDto.size(); i++) {
|
||||||
|
if (isTheSamePhoneNumber(listPhoneDto.get(i).getTelPhone(), szPhone)) {
|
||||||
|
return listPhoneDto.get(i).getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTheSamePhoneNumber(String szNum1, String szNum2) {
|
||||||
|
if (szNum1.equals(szNum2)) {
|
||||||
LogUtils.d(TAG, "szNum1.equals(szNum2)");
|
LogUtils.d(TAG, "szNum1.equals(szNum2)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UnitAreaUtils.getInstance(mContext).isCurrentUnitAreaNumber(szNum1)) {
|
if (UnitAreaUtils.getInstance(mContext).isCurrentUnitAreaNumber(szNum1)) {
|
||||||
if(szNum1.equals(UnitAreaUtils.getInstance(mContext).genCurrentUnitAreaNumber(szNum2))) {
|
if (szNum1.equals(UnitAreaUtils.getInstance(mContext).genCurrentUnitAreaNumber(szNum2))) {
|
||||||
LogUtils.d(TAG, "szNum1.equals(UnitAreaUtils.genCurrentUnitAreaNumber(szNum2))");
|
LogUtils.d(TAG, "szNum1.equals(UnitAreaUtils.genCurrentUnitAreaNumber(szNum2))");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UnitAreaUtils.getInstance(mContext).isCurrentUnitAreaNumber(szNum2)) {
|
if (UnitAreaUtils.getInstance(mContext).isCurrentUnitAreaNumber(szNum2)) {
|
||||||
if(szNum2.equals(UnitAreaUtils.getInstance(mContext).genCurrentUnitAreaNumber(szNum1))) {
|
if (szNum2.equals(UnitAreaUtils.getInstance(mContext).genCurrentUnitAreaNumber(szNum1))) {
|
||||||
LogUtils.d(TAG, "szNum2.equals(UnitAreaUtils.genCurrentUnitAreaNumber(szNum1))");
|
LogUtils.d(TAG, "szNum2.equals(UnitAreaUtils.genCurrentUnitAreaNumber(szNum1))");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -96,23 +225,16 @@ public class PhoneUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// 检验电话号码是否是数字
|
// 检验电话号码是否是数字
|
||||||
//
|
|
||||||
public static boolean isPhoneByDigit(String szPhone) {
|
public static boolean isPhoneByDigit(String szPhone) {
|
||||||
if(!RegexPPiUtils.isPPiOK(szPhone)) {
|
if (!RegexPPiUtils.isPPiOK(szPhone)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//String text = "这里是一些任意的文本内容";
|
|
||||||
String regex = "[+]?\\d+";
|
String regex = "[+]?\\d+";
|
||||||
Pattern pattern = Pattern.compile(regex);
|
Pattern pattern = Pattern.compile(regex);
|
||||||
Matcher matcher = pattern.matcher(szPhone);
|
Matcher matcher = pattern.matcher(szPhone);
|
||||||
LogUtils.d(TAG, String.format("matcher.matches() : %s", matcher.matches()));
|
LogUtils.d(TAG, String.format("matcher.matches() : %s", matcher.matches()));
|
||||||
/*if (matcher.matches()) {
|
|
||||||
System.out.println("文本满足该正则表达式模式");
|
|
||||||
} else {
|
|
||||||
System.out.println("文本不满足该正则表达式模式");
|
|
||||||
}*/
|
|
||||||
return matcher.matches();
|
return matcher.matches();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -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;
|
||||||
|
@@ -29,8 +29,14 @@ public class UnitAreaUtils {
|
|||||||
|
|
||||||
public boolean isCurrentUnitAreaNumber(String szPhoneNumer) {
|
public boolean isCurrentUnitAreaNumber(String szPhoneNumer) {
|
||||||
String szUnitArea = getUnitArea();
|
String szUnitArea = getUnitArea();
|
||||||
LogUtils.d(TAG, String.format("szPhoneNumer.substring(1,3) %s", szPhoneNumer.substring(1,3)));
|
try {
|
||||||
return szPhoneNumer.substring(1,3).equals(szUnitArea);
|
String szPhoneNumerUnitArea = szPhoneNumer.substring(1, 3);
|
||||||
|
LogUtils.d(TAG, String.format("szPhoneNumerUnitArea %s", szPhoneNumerUnitArea));
|
||||||
|
return szPhoneNumerUnitArea.equals(szUnitArea);
|
||||||
|
} catch (StringIndexOutOfBoundsException e) {
|
||||||
|
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String genCurrentUnitAreaNumber(String szPhoneNumer) {
|
public String genCurrentUnitAreaNumber(String szPhoneNumer) {
|
||||||
|
@@ -0,0 +1,125 @@
|
|||||||
|
package cc.winboll.studio.mymessagemanager.views;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen&豆包大模型<zhangsken@188.com>
|
||||||
|
* @Date 2025/08/23 00:39
|
||||||
|
* @Describe 多级拉动响应自定义控件
|
||||||
|
*/
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.ViewTreeObserver;
|
||||||
|
import android.widget.ScrollView;
|
||||||
|
|
||||||
|
public class BottomPositionFixedScrollView extends ScrollView {
|
||||||
|
public static final String TAG = "BottomPositionFixedScrollView";
|
||||||
|
// 记录底部对应的内容绝对位置(即底部位置在内容中的y坐标,该位置需始终保持在视图底部)
|
||||||
|
private int mBottomContentY = 0;
|
||||||
|
// 标记是否是首次布局(避免初始加载误触发)
|
||||||
|
private boolean isFirstLayout = true;
|
||||||
|
|
||||||
|
public BottomPositionFixedScrollView(Context context) {
|
||||||
|
super(context);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BottomPositionFixedScrollView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BottomPositionFixedScrollView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
// 监听布局变化(高度改变时触发)
|
||||||
|
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||||
|
@Override
|
||||||
|
public void onGlobalLayout() {
|
||||||
|
if (isFirstLayout) {
|
||||||
|
isFirstLayout = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 布局变化后,恢复底部位置
|
||||||
|
restoreBottomPosition();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重写滚动事件,记录“底部对应的内容绝对位置”
|
||||||
|
* (即当前视图底部边缘对应的内容y坐标,该坐标需始终保持在视图底部)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
|
||||||
|
super.onScrollChanged(l, t, oldl, oldt);
|
||||||
|
if (getChildCount() == 0) {
|
||||||
|
mBottomContentY = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内容总高度
|
||||||
|
int contentHeight = getChildAt(0).getMeasuredHeight();
|
||||||
|
// 视图可视高度(自身高度)
|
||||||
|
int scrollViewHeight = getMeasuredHeight();
|
||||||
|
// 当前视图底部边缘对应的内容y坐标 = 顶部滚动距离(t) + 可视高度
|
||||||
|
// (该坐标就是“底部内容的绝对位置”,需始终保持在视图底部)
|
||||||
|
mBottomContentY = t + scrollViewHeight;
|
||||||
|
|
||||||
|
// 避免超过内容总高度(比如内容不足一屏时,底部最多到内容底部)
|
||||||
|
if (mBottomContentY > contentHeight) {
|
||||||
|
mBottomContentY = contentHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复底部位置:让原记录的“底部内容绝对位置”仍保持在视图底部
|
||||||
|
*/
|
||||||
|
private void restoreBottomPosition() {
|
||||||
|
if (getChildCount() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新的内容总高度
|
||||||
|
int newContentHeight = getChildAt(0).getMeasuredHeight();
|
||||||
|
// 新的视图可视高度
|
||||||
|
int newScrollViewHeight = getMeasuredHeight();
|
||||||
|
|
||||||
|
// 目标:让原mBottomContentY(底部内容绝对位置)仍位于视图底部
|
||||||
|
// 此时需要的顶部滚动距离 = mBottomContentY - 新的可视高度
|
||||||
|
int targetScrollY = mBottomContentY - newScrollViewHeight;
|
||||||
|
|
||||||
|
// 边界修正:
|
||||||
|
// 1. 不能小于0(避免滚动到负数位置)
|
||||||
|
// 2. 不能大于“最大可滚动距离”(内容高度 - 可视高度,避免超出内容范围)
|
||||||
|
int maxScrollY = Math.max(newContentHeight - newScrollViewHeight, 0);
|
||||||
|
targetScrollY = Math.max(targetScrollY, 0);
|
||||||
|
targetScrollY = Math.min(targetScrollY, maxScrollY);
|
||||||
|
|
||||||
|
// 滚动到目标位置,保持底部内容位置不变
|
||||||
|
smoothScrollTo(0, targetScrollY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 外部手动设置底部内容绝对位置(可选)
|
||||||
|
*/
|
||||||
|
public void setBottomContentY(int bottomContentY) {
|
||||||
|
if (getChildCount() == 0) {
|
||||||
|
mBottomContentY = bottomContentY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 限制不超过内容总高度
|
||||||
|
int contentHeight = getChildAt(0).getMeasuredHeight();
|
||||||
|
mBottomContentY = Math.min(bottomContentY, contentHeight);
|
||||||
|
restoreBottomPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前底部内容绝对位置(可选)
|
||||||
|
*/
|
||||||
|
public int getBottomContentY() {
|
||||||
|
return mBottomContentY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -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>
|
@@ -1,71 +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">
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:orientation="horizontal"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:text="SMS TO : "
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/activitycomposesmsTextView1"
|
android:id="@+id/activitycomposesmsLinearLayout1"
|
||||||
android:layout_alignParentLeft="true"
|
android:gravity="center_vertical"
|
||||||
android:layout_marginLeft="10dp"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_centerVertical="true"/>
|
android:layout_marginRight="10dp"
|
||||||
|
android:layout_marginLeft="10dp"
|
||||||
|
android:layout_alignParentLeft="true">
|
||||||
|
|
||||||
<EditText
|
<TextView
|
||||||
android:layout_toRightOf="@id/activitycomposesmsTextView1"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="phone"
|
android:text="(拼音搜索):"/>
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:id="@+id/activitycomposesmsEditText1"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_marginRight="10dp"
|
|
||||||
android:layout_centerVertical="true"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
<EditText
|
||||||
|
android:layout_width="80dp"
|
||||||
|
android:ems="10"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/activitycomposesmsEditText2"/>
|
||||||
|
|
||||||
</LinearLayout>
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_toRightOf="@id/activitycomposesmsEditText2"
|
||||||
|
android:id="@+id/activitycomposesmsTextView2"
|
||||||
|
android:layout_weight="1.0"/>
|
||||||
|
|
||||||
<RelativeLayout
|
</LinearLayout>
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:padding="10dp"
|
|
||||||
android:layout_weight="1.0">
|
|
||||||
|
|
||||||
<ListView
|
<LinearLayout
|
||||||
android:layout_alignParentTop="true"
|
android:orientation="horizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_below="@id/activitycomposesmsLinearLayout1"
|
||||||
android:layout_height="wrap_content"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_above="@+id/activitycomposesmsinclude1"
|
android:layout_marginRight="10dp"
|
||||||
android:id="@+id/activitycomposesmsListView1"/>
|
android:layout_marginLeft="10dp"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
<include
|
<TextView
|
||||||
layout="@layout/view_smssend"
|
android:layout_width="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="match_parent"
|
android:text="(SMS TO) :"
|
||||||
android:layout_height="wrap_content"
|
android:id="@+id/activitycomposesmsTextView1"/>
|
||||||
android:id="@+id/activitycomposesmsinclude1"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
<EditText
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:inputType="phone"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ems="10"
|
||||||
|
android:id="@+id/activitycomposesmsEditText1"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:layout_weight="1.0">
|
||||||
|
|
||||||
|
<!-- 关键修改:添加 listSelector 属性,关联选中样式 -->
|
||||||
|
<ListView
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_above="@+id/activitycomposesmsinclude1"
|
||||||
|
android:id="@+id/activitycomposesmsListView1"
|
||||||
|
android:listSelector="@drawable/listview_item_selector"
|
||||||
|
android:choiceMode="singleChoice"/> <!-- 开启单选模式,确保选中状态唯一 -->
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/view_smssend"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/activitycomposesmsinclude1"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="60dp"
|
android:layout_height="60dp"
|
||||||
android:padding="10dp"
|
android:padding="10dp"
|
||||||
android:text="@string/text_onlyreceivecontacts"
|
android:text="@string/text_norulesreceivecontacts"
|
||||||
android:id="@+id/activitymainSwitchView2"/>
|
android:id="@+id/activitymainSwitchView2"/>
|
||||||
|
|
||||||
<cc.winboll.studio.mymessagemanager.views.ConfirmSwitchView
|
<cc.winboll.studio.mymessagemanager.views.ConfirmSwitchView
|
||||||
|
@@ -10,36 +10,40 @@
|
|||||||
android:layout_height="@dimen/toolbar_height"
|
android:layout_height="@dimen/toolbar_height"
|
||||||
android:id="@+id/activitysmsASupportToolbar1"/>
|
android:id="@+id/activitysmsASupportToolbar1"/>
|
||||||
|
|
||||||
<RelativeLayout
|
<ScrollView
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="0dp"
|
||||||
android:paddingBottom="10dp">
|
android:layout_weight="1.0"
|
||||||
|
android:id="@+id/activitysmsScrollView2">
|
||||||
|
|
||||||
<ScrollView
|
<LinearLayout
|
||||||
android:layout_alignParentTop="true"
|
android:orientation="vertical"
|
||||||
android:layout_above="@+id/activitysmsinclude1"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="match_parent"
|
||||||
android:id="@+id/activitysmsinphoneScrollView1"
|
android:id="@+id/activitysmsLinearLayout1">
|
||||||
android:layout_weight="1.0"
|
|
||||||
android:isScrollContainer="false">
|
|
||||||
|
|
||||||
<cc.winboll.studio.mymessagemanager.views.SMSListViewForScrollView
|
<cc.winboll.studio.mymessagemanager.views.BottomPositionFixedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="520dp"
|
||||||
|
android:isScrollContainer="false"
|
||||||
|
android:id="@+id/activitysmsScrollView1">
|
||||||
|
|
||||||
|
<cc.winboll.studio.mymessagemanager.views.SMSListViewForScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/activitysmsSMSListViewForScrollView1"/>
|
||||||
|
|
||||||
|
</cc.winboll.studio.mymessagemanager.views.BottomPositionFixedScrollView>
|
||||||
|
|
||||||
|
<include
|
||||||
|
layout="@layout/view_smssend"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/activitysmsinphoneListView1"/>
|
android:id="@+id/activitysmsinclude1"/>
|
||||||
|
|
||||||
</ScrollView>
|
</LinearLayout>
|
||||||
|
|
||||||
<include
|
</ScrollView>
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
layout="@layout/view_smssend"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/activitysmsinclude1"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@@ -7,6 +7,18 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="10dp">
|
android:padding="10dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:id="@+id/viewsmssendpart1TextView1"/>
|
||||||
|
|
||||||
|
<cc.winboll.studio.libaes.views.AOHPCTCSeekBar
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/viewsmssendpart1AOHPCTCSeekBar1"/>
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="vertical"
|
||||||
android:maxHeight="150dp"
|
android:maxHeight="150dp"
|
||||||
@@ -17,17 +29,6 @@
|
|||||||
android:id="@+id/viewsmssendpart1EditText1"
|
android:id="@+id/viewsmssendpart1EditText1"
|
||||||
android:background="@drawable/bg_frame"/>
|
android:background="@drawable/bg_frame"/>
|
||||||
|
|
||||||
<cc.winboll.studio.libaes.views.AOHPCTCSeekBar
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/viewsmssendpart1AOHPCTCSeekBar1"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textSize="20sp"
|
|
||||||
android:id="@+id/viewsmssendpart1TextView1"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
<string name="text_item_rule_clean">清理设置</string>
|
<string name="text_item_rule_clean">清理设置</string>
|
||||||
<string name="text_sendsms">发送短信</string>
|
<string name="text_sendsms">发送短信</string>
|
||||||
<string name="text_mainservice">短信服务管理总开关</string>
|
<string name="text_mainservice">短信服务管理总开关</string>
|
||||||
<string name="text_onlyreceivecontacts">只接收联系人短信</string>
|
<string name="text_norulesreceivecontacts">无限制接收联系人短信</string>
|
||||||
<string name="text_usingtts">使用TTS语音播报</string>
|
<string name="text_usingtts">使用TTS语音播报</string>
|
||||||
<string name="text_usingttsrule">使用TTS语音自定义规则</string>
|
<string name="text_usingttsrule">使用TTS语音自定义规则</string>
|
||||||
<string name="text_iamhere">短信管理服务已启动。</string>
|
<string name="text_iamhere">短信管理服务已启动。</string>
|
||||||
@@ -41,6 +41,6 @@
|
|||||||
<string name="text_appsettings">应用设置</string>
|
<string name="text_appsettings">应用设置</string>
|
||||||
<string name="text_ttsplaydelaytimes">TTS播放延迟时间(秒):</string>
|
<string name="text_ttsplaydelaytimes">TTS播放延迟时间(秒):</string>
|
||||||
<string name="msg_newsms">接收到新的消息。</string>
|
<string name="msg_newsms">接收到新的消息。</string>
|
||||||
<string name="msg_100sendmsg">>>>拉图标动到 100% 以发送信息。>>></string>
|
<string name="msg_100sendmsg">>>>拉动到100%可发信息>>></string>
|
||||||
<string name="msg_100applysettings">>>>拉图标动到 100% 应用设置。>>></string>
|
<string name="msg_100applysettings">>>>拉动到100%可应用设置>>></string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -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>
|
||||||
@@ -24,4 +27,8 @@
|
|||||||
<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>
|
||||||
|
@@ -34,7 +34,7 @@
|
|||||||
<string name="text_item_rule_clean">Clean Setting</string>
|
<string name="text_item_rule_clean">Clean Setting</string>
|
||||||
<string name="text_sendsms">Send SMS</string>
|
<string name="text_sendsms">Send SMS</string>
|
||||||
<string name="text_mainservice">Main Service</string>
|
<string name="text_mainservice">Main Service</string>
|
||||||
<string name="text_onlyreceivecontacts">Only Receive Contacts</string>
|
<string name="text_norulesreceivecontacts">No rules Receive Contacts</string>
|
||||||
<string name="text_usingtts">Using TTS</string>
|
<string name="text_usingtts">Using TTS</string>
|
||||||
<string name="text_usingttsrule">Using TTS Rule</string>
|
<string name="text_usingttsrule">Using TTS Rule</string>
|
||||||
<string name="text_iamhere">The main service is start.</string>
|
<string name="text_iamhere">The main service is start.</string>
|
||||||
|
Reference in New Issue
Block a user