+ * @Date 2024/07/19 14:30:57
+ * @Describe Uri 资源管理工具类
+ */
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.MediaStore;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class UriUtil {
+
+ public static final String TAG = "UriUtil";
+
+ //
+ // 获取真实路径
+ //
+ // @param context
+ //
+ public static String getFileFromUri(Context context, Uri uri) {
+ if (uri == null) {
+ return null;
+ }
+ switch (uri.getScheme()) {
+ case ContentResolver.SCHEME_CONTENT:
+ //Android7.0之后的uri content:// URI
+ return getFilePathFromContentUri(context, uri);
+ case ContentResolver.SCHEME_FILE:
+ default:
+ //Android7.0之前的uri file://
+ return new File(uri.getPath()).getAbsolutePath();
+ }
+ }
+
+ //
+ // 从uri获取path
+ //
+ // @param uri content://media/external/file/109009
+ //
+ // FileProvider适配
+ // content://com.tencent.mobileqq.fileprovider/external_files/storage/emulated/0/Tencent/QQfile_recv/
+ // content://com.tencent.mm.external.fileprovider/external/tencent/MicroMsg/Download/
+ //
+ private static String getFilePathFromContentUri(Context context, Uri uri) {
+ if (null == uri) return null;
+ String data = null;
+
+ String[] filePathColumn = {MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DISPLAY_NAME};
+ Cursor cursor = context.getContentResolver().query(uri, filePathColumn, null, null, null);
+ if (null != cursor) {
+ if (cursor.moveToFirst()) {
+ int index = cursor.getColumnIndex(MediaStore.MediaColumns.DATA);
+ if (index > -1) {
+ data = cursor.getString(index);
+ } else {
+ int nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
+ String fileName = cursor.getString(nameIndex);
+ data = getPathFromInputStreamUri(context, uri, fileName);
+ }
+ }
+ cursor.close();
+ }
+ return data;
+ }
+
+ //
+ // 用流拷贝文件一份到自己APP私有目录下
+ //
+ // @param context
+ // @param uri
+ // @param fileName
+ //
+ private static String getPathFromInputStreamUri(Context context, Uri uri, String fileName) {
+ InputStream inputStream = null;
+ String filePath = null;
+
+ if (uri.getAuthority() != null) {
+ try {
+ inputStream = context.getContentResolver().openInputStream(uri);
+ File file = createTemporalFileFrom(context, inputStream, fileName);
+ filePath = file.getPath();
+
+ } catch (Exception e) {
+ } finally {
+ try {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ return filePath;
+ }
+
+ private static File createTemporalFileFrom(Context context, InputStream inputStream, String fileName)
+ throws IOException {
+ File targetFile = null;
+ if (inputStream != null) {
+ int read;
+ byte[] buffer = new byte[8 * 1024];
+ //自己定义拷贝文件路径
+ targetFile = new File(context.getExternalCacheDir(), fileName);
+ if (targetFile.exists()) {
+ targetFile.delete();
+ }
+ OutputStream outputStream = new FileOutputStream(targetFile);
+
+ while ((read = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, read);
+ }
+ outputStream.flush();
+
+ try {
+ outputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return targetFile;
+ }
+}
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/utils/UserVisionSystemProtectModeUtil.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/utils/UserVisionSystemProtectModeUtil.java
new file mode 100644
index 0000000..e91ea2f
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/utils/UserVisionSystemProtectModeUtil.java
@@ -0,0 +1,53 @@
+package cc.winboll.studio.mymessagemanager.utils;
+
+/**
+ * @Author ZhanGSKen
+ * @Date 2024/07/24 16:20:13
+ * @Describe 用户视觉系统保护模式工具集
+ */
+import java.util.Random;
+
+public class UserVisionSystemProtectModeUtil {
+
+ public static final String TAG = "UserVisionSystemProtectModeUtil";
+
+ public static final String PreviewShuffleSMS(String szSMSText, String szRefuseChars, String szReplaceChars) {
+ String szPreview;
+ // 将字符串转换为字符数组
+ char[] charArray = szSMSText.toCharArray();
+ // 打乱字符数组
+ shuffleArray(charArray);
+ // 构建新的字符串并打印
+ szPreview = new String(charArray);
+ szPreview = useProtectedCharsRule(szPreview, szRefuseChars, szReplaceChars);
+ return szPreview;
+ }
+
+ //
+ // 打乱字符数组的方法
+ //
+ // @param array 要被打乱的字符数组
+ //
+ public static void shuffleArray(char[] array) {
+ // 创建随机数生成器
+ Random random = new Random();
+ for (int i = array.length - 1; i > 0; i--) {
+ // 生成一个随机索引j,范围在0到i之间(包括i)
+ int j = random.nextInt(i + 1);
+
+ // 交换array[i]和array[j]的位置
+ char temp = array[i];
+ array[i] = array[j];
+ array[j] = temp;
+ }
+ }
+
+ public static String useProtectedCharsRule(String szContent, String szRefuseChars, String szReplaceChars) {
+ // 正则表达式模式 (寻找 szProtectChars 其中一个字符)
+ String pattern = "[" + szRefuseChars + "]";
+
+ // 替换模式后的字符串
+ String szProtectedContent = szContent.replaceAll(pattern, szReplaceChars);
+ return szProtectedContent;
+ }
+}
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/utils/ViewUtil.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/utils/ViewUtil.java
new file mode 100644
index 0000000..72f8d00
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/utils/ViewUtil.java
@@ -0,0 +1,20 @@
+package cc.winboll.studio.mymessagemanager.utils;
+
+/**
+ * @Author ZhanGSKen
+ * @Date 2024/07/19 14:30:57
+ * @Describe Uri 视图元素工具类
+ */
+import android.widget.ScrollView;
+
+public class ViewUtil {
+
+ public static void scrollScrollView(final ScrollView scrollView) {
+ scrollView.post(new Runnable() {
+ @Override
+ public void run() {
+ scrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ }
+}
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/BottomPositionFixedScrollView.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/BottomPositionFixedScrollView.java
new file mode 100644
index 0000000..56ae783
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/BottomPositionFixedScrollView.java
@@ -0,0 +1,125 @@
+package cc.winboll.studio.mymessagemanager.views;
+
+/**
+ * @Author ZhanGSKen&豆包大模型
+ * @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;
+ }
+}
+
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/ConfirmSwitchView.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/ConfirmSwitchView.java
new file mode 100644
index 0000000..fc7c19a
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/ConfirmSwitchView.java
@@ -0,0 +1,78 @@
+package cc.winboll.studio.mymessagemanager.views;
+
+/**
+ * @Author ZhanGSKen
+ * @Date 2023/07/25 13:37:55
+ */
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Switch;
+import cc.winboll.studio.libaes.dialogs.YesNoAlertDialog;
+import cc.winboll.studio.libappbase.LogUtils;
+
+public class ConfirmSwitchView extends Switch {
+
+ public static final String TAG = "SwitchView";
+
+ Context mContext;
+
+ public ConfirmSwitchView(Context context) {
+ super(context);
+ initView(context);
+ }
+
+ public ConfirmSwitchView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initView(context);
+ }
+
+ public ConfirmSwitchView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initView(context);
+ }
+
+ public ConfirmSwitchView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ initView(context);
+ }
+
+ void initView(Context context) {
+ mContext = context;
+ TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.textColorPrimary});
+ ColorStateList csl = a.getColorStateList(0);
+ if (csl != null) setTextColor(csl);
+ a.recycle();
+ }
+
+ @Override
+ public void setOnClickListener(final View.OnClickListener l) {
+ super.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ final boolean isChecked = isChecked();
+ StringBuilder sbMessage = new StringBuilder("请确定[");
+ sbMessage.append(isChecked ?"开启": "关闭");
+ sbMessage.append("]操作。");
+ // 在这里添加您的点击事件响应逻辑
+ YesNoAlertDialog.show(mContext, getText().toString(), sbMessage.toString(), new YesNoAlertDialog.OnDialogResultListener(){
+ @Override
+ public void onYes() {
+ LogUtils.d(TAG, "onYes");
+ setChecked(isChecked);
+ }
+ @Override
+ public void onNo() {
+ LogUtils.d(TAG, "onNo");
+ setChecked(!isChecked);
+ }
+ });
+ //Toast.makeText(getContext(), "Switch clicked", Toast.LENGTH_SHORT).show();
+ // 确保调用了父类的onClick()方法
+ l.onClick(v);
+ }
+ });
+ }
+}
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/DateAgoTextView.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/DateAgoTextView.java
new file mode 100644
index 0000000..e813885
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/DateAgoTextView.java
@@ -0,0 +1,32 @@
+package cc.winboll.studio.mymessagemanager.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import androidx.appcompat.widget.AppCompatTextView;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+public class DateAgoTextView extends AppCompatTextView {
+ long mnDate;
+
+ public DateAgoTextView(Context context) {
+ super(context);
+ }
+
+ public DateAgoTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public DateAgoTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public void setDate(long nDate) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat(
+ "yyyy-MM-dd HH:mm:ss", Locale.getDefault());
+ Date d = new Date(nDate);
+
+ setText(dateFormat.format(d));
+ }
+}
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/DraggableView.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/DraggableView.java
new file mode 100644
index 0000000..61d87bf
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/DraggableView.java
@@ -0,0 +1,190 @@
+package cc.winboll.studio.mymessagemanager.views;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.ViewTreeObserver;
+import android.widget.FrameLayout;
+import cc.winboll.studio.mymessagemanager.R;
+
+public class DraggableView extends FrameLayout {
+ // SP配置常量(新增尺寸保存键)
+ private static final String SP_NAME = "TTS_FLOAT_DRAG_CONFIG";
+ private static final String KEY_LEFT = "drag_view_left";
+ private static final String KEY_TOP = "drag_view_top";
+ private static final String KEY_WIDTH = "drag_view_width"; // 新增:保存布局宽度
+ private static final String KEY_HEIGHT = "drag_view_height"; // 新增:保存布局高度
+
+ // 位置/尺寸变量
+ private int viewLeft;
+ private int viewTop;
+ private int viewWidth;
+ private int viewHeight;
+ private int screenWidth;
+ private int screenHeight;
+ // 拖动相关
+ private float downX;
+ private float downY;
+ private boolean isDragging = false;
+
+ // 构造方法
+ public DraggableView(Context context) {
+ super(context);
+ init();
+ }
+
+ public DraggableView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public DraggableView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ private void init() {
+ LayoutInflater.from(getContext()).inflate(R.layout.view_tts_back, this, true);
+ DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
+ screenWidth = metrics.widthPixels;
+ screenHeight = metrics.heightPixels;
+
+ getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ ViewTreeObserver currentVto = getViewTreeObserver();
+ if (currentVto.isAlive()) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ currentVto.removeOnGlobalLayoutListener(this);
+ } else {
+ currentVto.removeGlobalOnLayoutListener(this);
+ }
+ }
+ // 获取布局实际宽高
+ viewWidth = getMeasuredWidth();
+ viewHeight = getMeasuredHeight();
+ // 保存尺寸到SP(新增)
+ saveViewSize();
+ // 初始化位置
+ initPosition();
+ updateViewPosition();
+ }
+ });
+ }
+
+ // 初始化位置(不变)
+ private void initPosition() {
+ SharedPreferences sp = getContext().getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
+ int defaultLeft = screenWidth - viewWidth;
+ int defaultTop = screenHeight - viewHeight;
+ viewLeft = sp.getInt(KEY_LEFT, defaultLeft);
+ viewTop = sp.getInt(KEY_TOP, defaultTop);
+ checkBoundary();
+ }
+
+ // 新增:保存布局尺寸到SP
+ private void saveViewSize() {
+ if (viewWidth > 0 && viewHeight > 0) {
+ SharedPreferences sp = getContext().getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
+ sp.edit()
+ .putInt(KEY_WIDTH, viewWidth)
+ .putInt(KEY_HEIGHT, viewHeight)
+ .apply();
+ }
+ }
+
+ // 新增:公共静态方法 - 查询最后保存的布局尺寸
+ public static int[] getLastViewSize(Context context) {
+ SharedPreferences sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
+ // 默认尺寸:120x120像素(与view_tts_back.xml示例尺寸一致,避免无值时异常)
+ int defaultWidth = dp2px(context, 120);
+ int defaultHeight = dp2px(context, 120);
+ // 从SP读取尺寸(无值则用默认)
+ int width = sp.getInt(KEY_WIDTH, defaultWidth);
+ int height = sp.getInt(KEY_HEIGHT, defaultHeight);
+ return new int[]{width, height};
+ }
+
+ // 新增:dp转px工具方法(确保默认尺寸适配不同屏幕)
+ private static int dp2px(Context context, float dpValue) {
+ final float scale = context.getResources().getDisplayMetrics().density;
+ return (int) (dpValue * scale + 0.5f);
+ }
+
+ // 原有方法(checkBoundary、updateViewPosition、savePosition、onTouchEvent、getLastPosition)保持不变
+ private void checkBoundary() {
+ viewLeft = Math.max(0, viewLeft);
+ viewTop = Math.max(0, viewTop);
+ viewLeft = Math.min(screenWidth - viewWidth, viewLeft);
+ viewTop = Math.min(screenHeight - viewHeight, viewTop);
+ }
+
+ private void updateViewPosition() {
+ LayoutParams params = (LayoutParams) getLayoutParams();
+ if (params != null) {
+ params.leftMargin = viewLeft;
+ params.topMargin = viewTop;
+ setLayoutParams(params);
+ }
+ }
+
+ private void savePosition() {
+ SharedPreferences sp = getContext().getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
+ sp.edit()
+ .putInt(KEY_LEFT, viewLeft)
+ .putInt(KEY_TOP, viewTop)
+ .apply();
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (viewWidth == 0 || viewHeight == 0) return super.onTouchEvent(event);
+
+ float rawX = event.getRawX();
+ float rawY = event.getRawY();
+
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ isDragging = true;
+ downX = rawX - viewLeft;
+ downY = rawY - viewTop;
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ if (isDragging) {
+ viewLeft = (int) (rawX - downX);
+ viewTop = (int) (rawY - downY);
+ checkBoundary();
+ updateViewPosition();
+ }
+ break;
+
+ case MotionEvent.ACTION_UP:
+ if (isDragging) {
+ isDragging = false;
+ savePosition();
+ }
+ break;
+ }
+ return true;
+ }
+
+ public static int[] getLastPosition(Context context) {
+ SharedPreferences sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
+ DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ int screenWidth = metrics.widthPixels;
+ int screenHeight = metrics.heightPixels;
+
+ int defaultLeft = 0;
+ int defaultTop = 0;
+
+ int left = sp.getInt(KEY_LEFT, defaultLeft);
+ int top = sp.getInt(KEY_TOP, defaultTop);
+ return new int[]{left, top};
+ }
+}
+
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/PhoneListViewForScrollView.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/PhoneListViewForScrollView.java
new file mode 100644
index 0000000..b7d5b43
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/PhoneListViewForScrollView.java
@@ -0,0 +1,65 @@
+package cc.winboll.studio.mymessagemanager.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ListView;
+
+public class PhoneListViewForScrollView extends ListView {
+
+ public PhoneListViewForScrollView(Context context) {
+ super(context);
+ }
+
+ public PhoneListViewForScrollView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public PhoneListViewForScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ /**
+ * 重写onMeasure方法,重新计算高度,达到使ListView适应ScrollView的效果
+ *
+ * @param widthMeasureSpec 宽度测量规则
+ * @param heightMeasureSpec 高度测量规则
+ */
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ /*
+ // 子控件TextView不换行显示
+ ListAdapter listAdapter = this.getAdapter();
+ if (listAdapter == null) {
+ return;
+ }
+ int maxWidth = 0;
+ for (int i = 0; i < listAdapter.getCount(); i++) {
+ View listItem = listAdapter.getView(i, null, this);
+ View cb = listItem.findViewById(R.id.listviewfiledataCheckBox1);
+ View iv = listItem.findViewById(R.id.listviewfiledataImageView1);
+ View tv = listItem.findViewById(R.id.listviewfiledataTextView1);
+
+ cb.measure(0,0);
+ iv.measure(0,0);
+ tv.measure(0,0);
+
+ //listItem.measure(0, 0);
+ //int width = listItem.getMeasuredWidth();
+ int width = cb.getMeasuredWidth() + iv.getMeasuredWidth()+ tv.getMeasuredWidth();
+ if(width>maxWidth) maxWidth = width;
+ }
+ int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+ int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST);
+ super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec);
+ */
+
+ // 子控件TextView换行显示
+ //Integer.MAX_VALUE:表示int类型能够表示的最大值,值为2的31次方-1
+ //>>2:右移N位相当于除以2的N的幂
+ //MeasureSpec.AT_MOST:子布局可以根据自己的大小选择任意大小的模式
+ int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+ //int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthMeasureSpec, MeasureSpec.AT_MOST);
+
+ super.onMeasure(widthMeasureSpec, newHeightMeasureSpec);
+ }
+}
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/ProtectModeTextView.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/ProtectModeTextView.java
new file mode 100644
index 0000000..6e40ad8
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/ProtectModeTextView.java
@@ -0,0 +1,155 @@
+package cc.winboll.studio.mymessagemanager.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.widget.LinearLayout;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import cc.winboll.studio.mymessagemanager.R;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * 保护模式自定义控件
+ * 最终规则:
+ * 1. 刻度范围 0~12
+ * 2. 刻度值 = 每一组截取【相邻字符个数】
+ * 3. 从头到尾按固定长度切块分组
+ * 4. 所有分组收集后随机打乱再拼接输出
+ * 5. 刻度0 = 不打乱,显示原文
+ * 6. 按原生字符计算(包含空格、标点)
+ */
+public class ProtectModeTextView extends LinearLayout {
+
+ public interface OnScaleChangedListener {
+ void onScaleChanged(int progress);
+ }
+
+ private TextView tvContent;
+ private SeekBar seekBarScale;
+ private String originText;
+ private List charAllList;
+ private final Random random = new Random();
+ private OnScaleChangedListener mOnScaleChangedListener;
+
+ public ProtectModeTextView(Context context) {
+ super(context);
+ initView(context);
+ }
+
+ public ProtectModeTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initView(context);
+ }
+
+ public ProtectModeTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initView(context);
+ }
+
+ private void initView(Context context) {
+ LayoutInflater.from(context).inflate(R.layout.layout_protect_mode_textview, this, true);
+ tvContent = findViewById(R.id.tv_content);
+ seekBarScale = findViewById(R.id.seek_bar_scale);
+
+ // 刻度 0 ~ 12
+ seekBarScale.setMax(12);
+ seekBarScale.setProgress(0);
+
+ charAllList = new ArrayList<>();
+
+ seekBarScale.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ handleTextLogic(progress);
+ if (fromUser && mOnScaleChangedListener != null) {
+ mOnScaleChangedListener.onScaleChanged(progress);
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {}
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {}
+ });
+ }
+
+ public void setOnScaleChangedListener(OnScaleChangedListener listener) {
+ mOnScaleChangedListener = listener;
+ }
+
+ public void setContentTextWithScale(String text, int scaleProgress) {
+ this.originText = text;
+ convertToCharList(text);
+ seekBarScale.setProgress(scaleProgress);
+ handleTextLogic(scaleProgress);
+ }
+
+ public void setContentText(String text) {
+ this.originText = text;
+ convertToCharList(text);
+ handleTextLogic(seekBarScale.getProgress());
+ }
+
+ private void convertToCharList(String text) {
+ charAllList.clear();
+ if (text == null || text.isEmpty()) {
+ return;
+ }
+ char[] chars = text.toCharArray();
+ for (char c : chars) {
+ charAllList.add(c);
+ }
+ }
+
+ private void handleTextLogic(int groupSize) {
+ if (charAllList.isEmpty()) {
+ tvContent.setText(originText);
+ return;
+ }
+
+ // 刻度0 原样不打乱
+ if (groupSize <= 0) {
+ tvContent.setText(originText);
+ return;
+ }
+
+ List groupList = new ArrayList<>();
+ int totalLen = charAllList.size();
+
+ // 从头到尾 按 groupSize 个相邻字符切块
+ int index = 0;
+ while (index < totalLen) {
+ StringBuilder sb = new StringBuilder();
+ // 每一组取 groupSize 个相邻字符
+ for (int i = 0; i < groupSize && index < totalLen; i++) {
+ sb.append(charAllList.get(index));
+ index++;
+ }
+ groupList.add(sb.toString());
+ }
+
+ // 所有分组随机打乱
+ Collections.shuffle(groupList, random);
+
+ // 拼接输出
+ StringBuilder result = new StringBuilder();
+ for (String item : groupList) {
+ result.append(item);
+ }
+
+ tvContent.setText(result.toString());
+ }
+
+ public String getOriginText() {
+ return originText;
+ }
+
+ public void resetSeekBar() {
+ seekBarScale.setProgress(0);
+ }
+}
+
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/SMSAcceptRuleListViewForScrollView.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/SMSAcceptRuleListViewForScrollView.java
new file mode 100644
index 0000000..d60d8f6
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/SMSAcceptRuleListViewForScrollView.java
@@ -0,0 +1,33 @@
+package cc.winboll.studio.mymessagemanager.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ListView;
+
+public class SMSAcceptRuleListViewForScrollView extends ListView {
+
+ public SMSAcceptRuleListViewForScrollView(Context context) {
+ super(context);
+ }
+
+ public SMSAcceptRuleListViewForScrollView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SMSAcceptRuleListViewForScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ /**
+ * 重写onMeasure方法,重新计算高度,达到使ListView适应ScrollView的效果
+ *
+ * @param widthMeasureSpec 宽度测量规则
+ * @param heightMeasureSpec 高度测量规则
+ */
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+ super.onMeasure(widthMeasureSpec, newHeightMeasureSpec);
+ }
+
+}
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/SMSListViewForScrollView.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/SMSListViewForScrollView.java
new file mode 100644
index 0000000..296882e
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/SMSListViewForScrollView.java
@@ -0,0 +1,73 @@
+package cc.winboll.studio.mymessagemanager.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ListView;
+
+public class SMSListViewForScrollView extends ListView {
+ static int nMaxWidth = 0;
+
+ public SMSListViewForScrollView(Context context) {
+ super(context);
+ }
+
+ public SMSListViewForScrollView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ }
+
+ public SMSListViewForScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ /**
+ * 重写onMeasure方法,重新计算高度,达到使ListView适应ScrollView的效果
+ *
+ * @param widthMeasureSpec 宽度测量规则
+ * @param heightMeasureSpec 高度测量规则
+ */
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+
+ /*
+ // 子控件TextView不换行显示
+ ListAdapter listAdapter = this.getAdapter();
+ if (listAdapter == null) {
+ return;
+ }
+ int maxWidth = 0;
+ for (int i = 0; i < listAdapter.getCount(); i++) {
+ View listItem = listAdapter.getView(i, null, this);
+ View cb = listItem.findViewById(R.id.listviewfiledataCheckBox1);
+ View iv = listItem.findViewById(R.id.listviewfiledataImageView1);
+ View tv = listItem.findViewById(R.id.listviewfiledataTextView1);
+
+ cb.measure(0,0);
+ iv.measure(0,0);
+ tv.measure(0,0);
+
+ //listItem.measure(0, 0);
+ //int width = listItem.getMeasuredWidth();
+ int width = cb.getMeasuredWidth() + iv.getMeasuredWidth()+ tv.getMeasuredWidth();
+ if(width>maxWidth) maxWidth = width;
+ }
+ int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+ int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST);
+ super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec);
+ */
+
+ // 子控件TextView换行显示
+ //Integer.MAX_VALUE:表示int类型能够表示的最大值,值为2的31次方-1
+ //>>2:右移N位相当于除以2的N的幂
+ //MeasureSpec.AT_MOST:子布局可以根据自己的大小选择任意大小的模式
+
+ int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+
+ //int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthMeasureSpec, MeasureSpec.AT_MOST);
+
+ //int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightMeasureSpec, MeasureSpec.AT_MOST);
+
+ super.onMeasure(widthMeasureSpec, newHeightMeasureSpec);
+ }
+
+}
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/SMSView.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/SMSView.java
new file mode 100644
index 0000000..9ce0bbe
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/SMSView.java
@@ -0,0 +1,78 @@
+package cc.winboll.studio.mymessagemanager.views;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import androidx.cardview.widget.CardView;
+import cc.winboll.studio.mymessagemanager.R;
+
+public class SMSView extends CardView {
+
+ public static final String TAG = "SMSView";
+
+ Context mContext;
+ int colorInbox;
+ int colorSend;
+ int colorItem;
+ public enum SMSType { INBOX, SEND }
+ SMSType mSMSType = SMSType.INBOX;
+
+ public void setSMSType(SMSType smsType) {
+ this.mSMSType = smsType;
+ updateViewBackgroundColor();
+ }
+
+ public SMSType getCardType() {
+ return mSMSType;
+ }
+
+ void updateViewBackgroundColor() {
+ if (mSMSType == SMSType.INBOX) {
+ setCardBackgroundColor(colorInbox);
+ } else if (mSMSType == SMSType.SEND) {
+ setCardBackgroundColor(colorSend);
+ }
+ }
+
+ public SMSView(Context context) {
+ super(context);
+ mContext = context;
+ }
+
+ public SMSView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mContext = context;
+
+ TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.SMSView, 0, 0);
+ String szSMSType = a.getString(R.styleable.SMSView_attrSMSType);
+ if((szSMSType == null)||szSMSType.equals("")) {
+ mSMSType = SMSType.SEND;
+ } else {
+ mSMSType = SMSType.valueOf(szSMSType);
+ }
+ colorInbox = a.getColor(R.styleable.SMSView_attrSMSViewInboxColor, 0);
+ colorSend = a.getColor(R.styleable.SMSView_attrSMSViewSendColor, 0);
+ a.recycle();
+ }
+
+ public SMSView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ mContext = context;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // 子控件TextView换行显示
+ //Integer.MAX_VALUE:表示int类型能够表示的最大值,值为2的31次方-1
+ //>>2:右移N位相当于除以2的N的幂
+ //MeasureSpec.AT_MOST:子布局可以根据自己的大小选择任意大小的模式
+ int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+ super.onMeasure(widthMeasureSpec, newHeightMeasureSpec);
+ }
+}
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/TTSRuleListViewForScrollView.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/TTSRuleListViewForScrollView.java
new file mode 100644
index 0000000..be676cb
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/TTSRuleListViewForScrollView.java
@@ -0,0 +1,82 @@
+package cc.winboll.studio.mymessagemanager.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ListView;
+
+public class TTSRuleListViewForScrollView extends ListView {
+ static int nMaxWidth = 0;
+
+ public TTSRuleListViewForScrollView(Context context) {
+ super(context);
+ }
+
+ public TTSRuleListViewForScrollView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ }
+
+ public TTSRuleListViewForScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ public void setSelection(int position) {
+ super.setSelection(position);
+ }
+
+ /**
+ * 重写onMeasure方法,重新计算高度,达到使ListView适应ScrollView的效果
+ *
+ * @param widthMeasureSpec 宽度测量规则
+ * @param heightMeasureSpec 高度测量规则
+ */
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+
+ /*
+ // 子控件TextView不换行显示
+ ListAdapter listAdapter = this.getAdapter();
+ if (listAdapter == null) {
+ return;
+ }
+ int maxWidth = 0;
+ for (int i = 0; i < listAdapter.getCount(); i++) {
+ View listItem = listAdapter.getView(i, null, this);
+ View cb = listItem.findViewById(R.id.listviewfiledataCheckBox1);
+ View iv = listItem.findViewById(R.id.listviewfiledataImageView1);
+ View tv = listItem.findViewById(R.id.listviewfiledataTextView1);
+
+ cb.measure(0,0);
+ iv.measure(0,0);
+ tv.measure(0,0);
+
+ //listItem.measure(0, 0);
+ //int width = listItem.getMeasuredWidth();
+ int width = cb.getMeasuredWidth() + iv.getMeasuredWidth()+ tv.getMeasuredWidth();
+ if(width>maxWidth) maxWidth = width;
+ }
+ int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+ int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST);
+ super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec);
+ */
+
+ // 子控件TextView换行显示
+ //Integer.MAX_VALUE:表示int类型能够表示的最大值,值为2的31次方-1
+ //>>2:右移N位相当于除以2的N的幂
+ //MeasureSpec.AT_MOST:子布局可以根据自己的大小选择任意大小的模式
+
+ int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+
+ //int newWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthMeasureSpec, MeasureSpec.AT_MOST);
+
+ //int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightMeasureSpec, MeasureSpec.AT_MOST);
+
+ super.onMeasure(widthMeasureSpec, newHeightMeasureSpec);
+ }
+
+}
+
+
+
+
diff --git a/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/TTSRuleView.java b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/TTSRuleView.java
new file mode 100644
index 0000000..73ed2a3
--- /dev/null
+++ b/mymessagemanager/src/main/java/cc/winboll/studio/mymessagemanager/views/TTSRuleView.java
@@ -0,0 +1,48 @@
+package cc.winboll.studio.mymessagemanager.views;
+
+/**
+ * @Author ZhanGSKen
+ * @Date 2023/07/24 15:08:31
+ * @Describe TTS语音规则视图
+ */
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import androidx.cardview.widget.CardView;
+import cc.winboll.studio.mymessagemanager.R;
+
+public class TTSRuleView extends CardView {
+
+ public static final String TAG = "TTSRuleView";
+
+ Context mContext;
+
+ public TTSRuleView(Context context) {
+ super(context);
+ mContext = context;
+ }
+
+ public TTSRuleView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mContext = context;
+ TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.TTSRuleView, 0, 0);
+ int colorBackground = a.getColor(R.styleable.TTSRuleView_attrTTSRuleViewBackgroundColor, 0);
+ a.recycle();
+ setCardBackgroundColor(colorBackground);
+ }
+
+ public TTSRuleView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ mContext = context;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ //Integer.MAX_VALUE:表示int类型能够表示的最大值,值为2的31次方-1
+ //>>2:右移N位相当于除以2的N的幂
+ //MeasureSpec.AT_MOST:子布局可以根据自己的大小选择任意大小的模式
+ int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+ super.onMeasure(widthMeasureSpec, newHeightMeasureSpec);
+ }
+
+}
diff --git a/mymessagemanager/src/main/res/anim/slow_fade_in.xml b/mymessagemanager/src/main/res/anim/slow_fade_in.xml
new file mode 100644
index 0000000..fa73170
--- /dev/null
+++ b/mymessagemanager/src/main/res/anim/slow_fade_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable-night/bg_frame.xml b/mymessagemanager/src/main/res/drawable-night/bg_frame.xml
new file mode 100644
index 0000000..bf2fe54
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable-night/bg_frame.xml
@@ -0,0 +1,32 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/bg_container_border.xml b/mymessagemanager/src/main/res/drawable/bg_container_border.xml
new file mode 100644
index 0000000..09c5bdf
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/bg_container_border.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/bg_frame.xml b/mymessagemanager/src/main/res/drawable/bg_frame.xml
new file mode 100644
index 0000000..2f208a6
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/bg_frame.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/bg_frame_black.xml b/mymessagemanager/src/main/res/drawable/bg_frame_black.xml
new file mode 100644
index 0000000..d28eb1b
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/bg_frame_black.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/bg_frame_white.xml b/mymessagemanager/src/main/res/drawable/bg_frame_white.xml
new file mode 100644
index 0000000..4b78840
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/bg_frame_white.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/cursor_pointer.xml b/mymessagemanager/src/main/res/drawable/cursor_pointer.xml
new file mode 100644
index 0000000..e828063
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/cursor_pointer.xml
@@ -0,0 +1,20 @@
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/ic_launcher.xml b/mymessagemanager/src/main/res/drawable/ic_launcher.xml
new file mode 100644
index 0000000..d4d1eaf
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/ic_launcher.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/ic_launcher_background.xml b/mymessagemanager/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..a4f78de
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/ic_launcher_background_golden.xml b/mymessagemanager/src/main/res/drawable/ic_launcher_background_golden.xml
new file mode 100644
index 0000000..804236c
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/ic_launcher_background_golden.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/ic_launcher_background_sky.xml b/mymessagemanager/src/main/res/drawable/ic_launcher_background_sky.xml
new file mode 100644
index 0000000..1ff84d4
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/ic_launcher_background_sky.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/ic_launcher_foreground.xml b/mymessagemanager/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..872b04e
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/ic_message.xml b/mymessagemanager/src/main/res/drawable/ic_message.xml
new file mode 100644
index 0000000..70f1497
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/ic_message.xml
@@ -0,0 +1,20 @@
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/listview_item_selector.xml b/mymessagemanager/src/main/res/drawable/listview_item_selector.xml
new file mode 100644
index 0000000..8fcab31
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/listview_item_selector.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/shape_gradient.xml b/mymessagemanager/src/main/res/drawable/shape_gradient.xml
new file mode 100644
index 0000000..c164fe9
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/shape_gradient.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/drawable/speaker.xml b/mymessagemanager/src/main/res/drawable/speaker.xml
new file mode 100644
index 0000000..53e00c1
--- /dev/null
+++ b/mymessagemanager/src/main/res/drawable/speaker.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/activity_about.xml b/mymessagemanager/src/main/res/layout/activity_about.xml
new file mode 100644
index 0000000..2638726
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/activity_about.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/activity_appsettings.xml b/mymessagemanager/src/main/res/layout/activity_appsettings.xml
new file mode 100644
index 0000000..93f929b
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/activity_appsettings.xml
@@ -0,0 +1,422 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/activity_composesms.xml b/mymessagemanager/src/main/res/layout/activity_composesms.xml
new file mode 100644
index 0000000..3f269f6
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/activity_composesms.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/activity_main.xml b/mymessagemanager/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..75bf771
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/activity_main.xml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/activity_sharedjsonreceive.xml b/mymessagemanager/src/main/res/layout/activity_sharedjsonreceive.xml
new file mode 100644
index 0000000..501df04
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/activity_sharedjsonreceive.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/activity_sms.xml b/mymessagemanager/src/main/res/layout/activity_sms.xml
new file mode 100644
index 0000000..1049e58
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/activity_sms.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/activity_smsacceptrulesetting.xml b/mymessagemanager/src/main/res/layout/activity_smsacceptrulesetting.xml
new file mode 100644
index 0000000..9c8c228
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/activity_smsacceptrulesetting.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/activity_smsrecycle.xml b/mymessagemanager/src/main/res/layout/activity_smsrecycle.xml
new file mode 100644
index 0000000..0f35153
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/activity_smsrecycle.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/activity_smsrecycle2.xml b/mymessagemanager/src/main/res/layout/activity_smsrecycle2.xml
new file mode 100644
index 0000000..df39118
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/activity_smsrecycle2.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/activity_ttsfloatsettings.xml b/mymessagemanager/src/main/res/layout/activity_ttsfloatsettings.xml
new file mode 100644
index 0000000..567b5ec
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/activity_ttsfloatsettings.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/activity_ttsplayrule.xml b/mymessagemanager/src/main/res/layout/activity_ttsplayrule.xml
new file mode 100644
index 0000000..7a10022
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/activity_ttsplayrule.xml
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/activity_unittest.xml b/mymessagemanager/src/main/res/layout/activity_unittest.xml
new file mode 100644
index 0000000..0e27922
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/activity_unittest.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/item_ttsplayrule.xml b/mymessagemanager/src/main/res/layout/item_ttsplayrule.xml
new file mode 100644
index 0000000..0543820
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/item_ttsplayrule.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/item_ttsplayrule_simple.xml b/mymessagemanager/src/main/res/layout/item_ttsplayrule_simple.xml
new file mode 100644
index 0000000..8d38ded
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/item_ttsplayrule_simple.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/layout_protect_mode_textview.xml b/mymessagemanager/src/main/res/layout/layout_protect_mode_textview.xml
new file mode 100644
index 0000000..0af0422
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/layout_protect_mode_textview.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/listview_contracts.xml b/mymessagemanager/src/main/res/layout/listview_contracts.xml
new file mode 100644
index 0000000..954a70f
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/listview_contracts.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/listview_phone.xml b/mymessagemanager/src/main/res/layout/listview_phone.xml
new file mode 100644
index 0000000..c8471bc
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/listview_phone.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/listview_sms.xml b/mymessagemanager/src/main/res/layout/listview_sms.xml
new file mode 100644
index 0000000..870f51e
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/listview_sms.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/listview_sms_part1.xml b/mymessagemanager/src/main/res/layout/listview_sms_part1.xml
new file mode 100644
index 0000000..afef768
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/listview_sms_part1.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/listview_smsacceptrule.xml b/mymessagemanager/src/main/res/layout/listview_smsacceptrule.xml
new file mode 100644
index 0000000..db124a2
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/listview_smsacceptrule.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/listview_smsacceptrule_simple.xml b/mymessagemanager/src/main/res/layout/listview_smsacceptrule_simple.xml
new file mode 100644
index 0000000..417e6cf
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/listview_smsacceptrule_simple.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/listview_smsrecycle.xml b/mymessagemanager/src/main/res/layout/listview_smsrecycle.xml
new file mode 100644
index 0000000..f3bcf0b
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/listview_smsrecycle.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/listview_smsrecycle2.xml b/mymessagemanager/src/main/res/layout/listview_smsrecycle2.xml
new file mode 100644
index 0000000..54fd844
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/listview_smsrecycle2.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/listview_smsrecycle_simple.xml b/mymessagemanager/src/main/res/layout/listview_smsrecycle_simple.xml
new file mode 100644
index 0000000..984c48f
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/listview_smsrecycle_simple.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/listview_ttsplayrule.xml b/mymessagemanager/src/main/res/layout/listview_ttsplayrule.xml
new file mode 100644
index 0000000..506fe50
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/listview_ttsplayrule.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/listview_ttsplayrule_simple.xml b/mymessagemanager/src/main/res/layout/listview_ttsplayrule_simple.xml
new file mode 100644
index 0000000..97450ea
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/listview_ttsplayrule_simple.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/remoteview.xml b/mymessagemanager/src/main/res/layout/remoteview.xml
new file mode 100644
index 0000000..593b401
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/remoteview.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/toast_custom_view.xml b/mymessagemanager/src/main/res/layout/toast_custom_view.xml
new file mode 100644
index 0000000..e43b760
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/toast_custom_view.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/toolbar_sendsms.xml b/mymessagemanager/src/main/res/layout/toolbar_sendsms.xml
new file mode 100644
index 0000000..531b8fc
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/toolbar_sendsms.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/view_smssend.xml b/mymessagemanager/src/main/res/layout/view_smssend.xml
new file mode 100644
index 0000000..18920d7
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/view_smssend.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/view_smssend_part1.xml b/mymessagemanager/src/main/res/layout/view_smssend_part1.xml
new file mode 100644
index 0000000..8bee679
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/view_smssend_part1.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/layout/view_tts_back.xml b/mymessagemanager/src/main/res/layout/view_tts_back.xml
new file mode 100644
index 0000000..00cdde4
--- /dev/null
+++ b/mymessagemanager/src/main/res/layout/view_tts_back.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/menu/toolbar_about.xml b/mymessagemanager/src/main/res/menu/toolbar_about.xml
new file mode 100644
index 0000000..a5662ee
--- /dev/null
+++ b/mymessagemanager/src/main/res/menu/toolbar_about.xml
@@ -0,0 +1,6 @@
+
+
diff --git a/mymessagemanager/src/main/res/menu/toolbar_item_sms.xml b/mymessagemanager/src/main/res/menu/toolbar_item_sms.xml
new file mode 100644
index 0000000..b186290
--- /dev/null
+++ b/mymessagemanager/src/main/res/menu/toolbar_item_sms.xml
@@ -0,0 +1,23 @@
+
+
diff --git a/mymessagemanager/src/main/res/menu/toolbar_item_smsrecycle.xml b/mymessagemanager/src/main/res/menu/toolbar_item_smsrecycle.xml
new file mode 100644
index 0000000..6f73933
--- /dev/null
+++ b/mymessagemanager/src/main/res/menu/toolbar_item_smsrecycle.xml
@@ -0,0 +1,9 @@
+
+
diff --git a/mymessagemanager/src/main/res/menu/toolbar_main_debug.xml b/mymessagemanager/src/main/res/menu/toolbar_main_debug.xml
new file mode 100644
index 0000000..fe63e44
--- /dev/null
+++ b/mymessagemanager/src/main/res/menu/toolbar_main_debug.xml
@@ -0,0 +1,12 @@
+
+
diff --git a/mymessagemanager/src/main/res/menu/toolbar_main_first.xml b/mymessagemanager/src/main/res/menu/toolbar_main_first.xml
new file mode 100644
index 0000000..84b6807
--- /dev/null
+++ b/mymessagemanager/src/main/res/menu/toolbar_main_first.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/menu/toolbar_main_last.xml b/mymessagemanager/src/main/res/menu/toolbar_main_last.xml
new file mode 100644
index 0000000..536d15f
--- /dev/null
+++ b/mymessagemanager/src/main/res/menu/toolbar_main_last.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/menu/toolbar_rule.xml b/mymessagemanager/src/main/res/menu/toolbar_rule.xml
new file mode 100644
index 0000000..736fbc2
--- /dev/null
+++ b/mymessagemanager/src/main/res/menu/toolbar_rule.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/menu/toolbar_smsacceptrulebean.xml b/mymessagemanager/src/main/res/menu/toolbar_smsacceptrulebean.xml
new file mode 100644
index 0000000..db92aa3
--- /dev/null
+++ b/mymessagemanager/src/main/res/menu/toolbar_smsacceptrulebean.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/menu/toolbar_smsrecycle.xml b/mymessagemanager/src/main/res/menu/toolbar_smsrecycle.xml
new file mode 100644
index 0000000..c3503f8
--- /dev/null
+++ b/mymessagemanager/src/main/res/menu/toolbar_smsrecycle.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/menu/toolbar_ttsrule.xml b/mymessagemanager/src/main/res/menu/toolbar_ttsrule.xml
new file mode 100644
index 0000000..ea4ac1d
--- /dev/null
+++ b/mymessagemanager/src/main/res/menu/toolbar_ttsrule.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/values-night/colors.xml b/mymessagemanager/src/main/res/values-night/colors.xml
new file mode 100644
index 0000000..4cb8e93
--- /dev/null
+++ b/mymessagemanager/src/main/res/values-night/colors.xml
@@ -0,0 +1,12 @@
+
+
+
+ #FF999999
+ #FF999999
+ #FF999999
+ #FF999999
+ #FF999999
+ #FF999999
+ #FF000000
+
+
diff --git a/mymessagemanager/src/main/res/values-night/styles.xml b/mymessagemanager/src/main/res/values-night/styles.xml
new file mode 100644
index 0000000..75d157e
--- /dev/null
+++ b/mymessagemanager/src/main/res/values-night/styles.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/values-zh/strings.xml b/mymessagemanager/src/main/res/values-zh/strings.xml
new file mode 100644
index 0000000..c6778ec
--- /dev/null
+++ b/mymessagemanager/src/main/res/values-zh/strings.xml
@@ -0,0 +1,46 @@
+
+
+ 我的短信管家
+ 用正则表达式方法自定义短信过滤和语音播报的短信应用。
+ 应用日志
+ 应用主题
+ 默认主题
+ 蓝色天空主题
+ 辉煌历程主题
+ 开发选项
+ 默认应用设置
+ 单元测试
+ 应用异常崩溃处理测试
+ 关于应用
+ 短信回收站
+ 应用权限申请提示
+ https://winboll.cc/studio/details.php?app=MyMessageManager
+ 短信管理中心
+ JSON 文件处理
+ 发送短信
+ 短信列表
+ 应用日志
+ 关于应用
+ 应用设置
+ 删除时间:
+ 来自:
+ 这是短信服务运行时的提示窗口,您可以在应用设置的通知消息设置中设置为隐藏本类通知。
+ TTS语音播报规则
+ 短信接收规则
+ 分享设置
+ 重置设置
+ 清理设置
+ 发送短信
+ 短信服务管理总开关
+ 无限制接收联系人短信
+ 使用TTS语音播报
+ 使用TTS语音自定义规则
+ 短信管理服务已启动。
+ 短信管理服务已关闭。
+ (未在联系人列表)
+ 应用设置
+ TTS播放延迟时间(秒):
+ 接收到新的消息。
+ >>>拉动到100%可发信息>>>
+ >>>拉动到100%可应用设置>>>
+
diff --git a/mymessagemanager/src/main/res/values/attrs.xml b/mymessagemanager/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..7ec833d
--- /dev/null
+++ b/mymessagemanager/src/main/res/values/attrs.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/values/colors.xml b/mymessagemanager/src/main/res/values/colors.xml
new file mode 100644
index 0000000..845b15f
--- /dev/null
+++ b/mymessagemanager/src/main/res/values/colors.xml
@@ -0,0 +1,42 @@
+
+
+
+ #FFFFFFFF
+
+ #FF212121
+ #FF1A237E
+ #FF01579B
+ #FF3E2723
+ #FF4A148C
+ #FF424242
+ #FFFFFFFF
+
+ #FFDCDA3D
+ #FF3DDC84
+ #FFDCDA3D
+
+ #FFA28BFF
+ #FF8BAEFF
+ #FFA28BFF
+
+ #FFFFEB8C
+ #FF8CD9FF
+ #FFFFEB8C
+
+ #FF78BDFF
+ #FFFFED78
+ #FF78BDFF
+
+ #FF5AEB53
+ #FFE653EB
+ #FF5AEB53
+
+ #FFB4B4B4
+ #FFD9D9D9
+ #FFB4B4B4
+
+
+ #FF696969
+
+ #FFE0E0E0
+
diff --git a/mymessagemanager/src/main/res/values/dimens.xml b/mymessagemanager/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..03c8154
--- /dev/null
+++ b/mymessagemanager/src/main/res/values/dimens.xml
@@ -0,0 +1,4 @@
+
+
+ 60dp
+
diff --git a/mymessagemanager/src/main/res/values/strings.xml b/mymessagemanager/src/main/res/values/strings.xml
new file mode 100644
index 0000000..b8b478d
--- /dev/null
+++ b/mymessagemanager/src/main/res/values/strings.xml
@@ -0,0 +1,52 @@
+
+ My Message Manager
+ MyMessageManager
+ The SMS application of the custom SMS voice broadcast with the regular expression method.Play with regular expressions.
+ Application Log
+ App Theme
+ Default Theme
+ Sky Theme
+ Golden Theme
+ Develop Options
+ Default App Settings
+ Unit Test
+ Crash Test
+ About APP
+ SMS Recycle
+ APP Permission Require Info
+ https://winboll.cc/studio/details.php?app=MyMessageManager
+ SMS Management Center
+ Shared JSON Handling
+ Message Sender
+ Messages
+ Application Log
+ About APP
+ Settings
+ DeleteDate:
+ Restore SMS
+ Clean SMS Recycle
+ From:
+ TTS Play Rule
+ SMS Receive Rule
+ This is the prompt window when the SMS service runs, which you can set to hide this class notification in the notification message settings.
+ Share Setting
+ Reset Setting
+ Clean Setting
+ Send SMS
+ Main Service
+ No rules Receive Contacts
+ Using TTS
+ Using TTS Rule
+ The main service is start.
+ The main service is stoped.
+ (Not In Contacts)
+ Settings
+ TTS Play delay times(second) :
+ Received new message.
+ >>>Seek 100% To Send Message.>>>
+ >>>Seek 100% To Apply settings.>>>
+
+ - "I am here!"
+ - "I think, I am here!"
+
+
diff --git a/mymessagemanager/src/main/res/values/styles.xml b/mymessagemanager/src/main/res/values/styles.xml
new file mode 100644
index 0000000..07653e7
--- /dev/null
+++ b/mymessagemanager/src/main/res/values/styles.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/xml/file_provider.xml b/mymessagemanager/src/main/res/xml/file_provider.xml
new file mode 100644
index 0000000..a53d7e6
--- /dev/null
+++ b/mymessagemanager/src/main/res/xml/file_provider.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/main/res/xml/network_security_config.xml b/mymessagemanager/src/main/res/xml/network_security_config.xml
new file mode 100644
index 0000000..ee39aa4
--- /dev/null
+++ b/mymessagemanager/src/main/res/xml/network_security_config.xml
@@ -0,0 +1,6 @@
+
+
+
+ winboll.cc
+
+
diff --git a/mymessagemanager/src/stage/AndroidManifest.xml b/mymessagemanager/src/stage/AndroidManifest.xml
new file mode 100644
index 0000000..7b53259
--- /dev/null
+++ b/mymessagemanager/src/stage/AndroidManifest.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mymessagemanager/src/stage/res/values/strings.xml b/mymessagemanager/src/stage/res/values/strings.xml
new file mode 100644
index 0000000..ace0c41
--- /dev/null
+++ b/mymessagemanager/src/stage/res/values/strings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/winboll/src/main/res/drawable/bg_container_border.xml b/winboll/src/main/res/drawable/bg_container_border.xml
new file mode 100644
index 0000000..09c5bdf
--- /dev/null
+++ b/winboll/src/main/res/drawable/bg_container_border.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+