Compare commits

...

18 Commits

Author SHA1 Message Date
ZhanGSKen
5507126f6b <mymessagemanager>APK 15.3.2 release Publish. 2025-08-23 13:40:21 +08:00
ZhanGSKen
d381c29452 短信发送窗口UI优化 2025-08-23 13:38:20 +08:00
ZhanGSKen
945eadb617 <mymessagemanager>APK 15.3.1 release Publish. 2025-07-03 13:50:15 +08:00
ZhanGSKen
c5bffc5eef <mymessagemanager>APK 15.3.0 release Publish. 2025-07-03 13:47:44 +08:00
ZhanGSKen
88597fe407 介于UI界面有调整,版本号升级以区分。 2025-07-03 13:28:17 +08:00
ZhanGSKen
53f985533a Merge branch 'mymessagemanager' into appbase 2025-07-03 13:00:51 +08:00
ZhanGSKen
a3950f13ad 应用介绍页链接更新 2025-07-03 12:56:57 +08:00
ZhanGSKen
c878e9dc02 菜单功能BugFix 2025-07-03 12:53:33 +08:00
ZhanGSKen
f2f7cab330 应用菜单排列调整 2025-07-03 12:38:09 +08:00
ZhanGSKen
c4e88e9593 编译配置初始化 2025-06-24 19:18:23 +08:00
ZhanGSKen
08d9d92ae4 <autoinstaller>APK 15.2.2 release Publish. 2025-06-24 09:54:47 +08:00
ZhanGSKen
74841c08dc 编译参数修复 2025-06-24 09:52:39 +08:00
ZhanGSKen
945bacb825 <autoinstaller>APK 15.2.1 release Publish. 2025-06-24 09:49:39 +08:00
ZhanGSKen
0e464495fd 编译调试 2025-06-24 09:45:47 +08:00
ZhanGSKen
e8682ce410 Merge remote-tracking branch 'origin/androidxdemo' into appbase 2025-06-19 20:56:32 +08:00
ZhanGSKen
198b0975ce <libaes>Library Release 15.9.1 2025-06-19 20:42:45 +08:00
ZhanGSKen
24a578a9d2 <aes>APK 15.9.1 release Publish. 2025-06-19 20:42:26 +08:00
ZhanGSKen
46de24447f 编译调试 2025-06-19 20:40:41 +08:00
23 changed files with 409 additions and 234 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Mon Jun 09 01:44:28 HKT 2025
stageCount=1
#Thu Jun 19 20:42:40 HKT 2025
stageCount=2
libraryProject=libaes
baseVersion=15.9
publishVersion=15.9.0
publishVersion=15.9.1
buildCount=0
baseBetaVersion=15.9.1
baseBetaVersion=15.9.2

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Sun May 04 05:32:00 GMT 2025
stageCount=1
#Tue Jun 24 09:54:47 HKT 2025
stageCount=3
libraryProject=
baseVersion=15.2
publishVersion=15.2.0
buildCount=74
baseBetaVersion=15.2.1
publishVersion=15.2.2
buildCount=0
baseBetaVersion=15.2.3

View File

@@ -42,23 +42,24 @@ android {
}
}
compileOptions {
/*compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
}*/
}
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
api project(':libjc')
api 'cc.winboll.studio:libaes:15.9.1'
api 'cc.winboll.studio:libapputils:15.8.4'
api 'cc.winboll.studio:libappbase:15.8.4'
// https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on
//implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
implementation 'org.bouncycastle:bcprov-jdk15to18:1.69'
implementation 'org.bouncycastle:bcpkix-jdk15to18:1.69'
api project(':libjc')
api 'androidx.appcompat:appcompat:1.0.0'
api 'com.google.android.material:material:1.0.0'
api 'cc.winboll.studio:libapputils:9.1.0'
api 'cc.winboll.studio:libappbase:1.0.3'
api fileTree(dir: 'libs', include: ['*.jar'])
}

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Fri Jan 10 22:03:57 GMT 2025
#Tue Jun 24 11:17:30 GMT 2025
stageCount=0
libraryProject=libjc
baseVersion=1.0
publishVersion=1.0.0
buildCount=133
buildCount=135
baseBetaVersion=1.0.1

View File

@@ -15,10 +15,10 @@ import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import cc.winboll.studio.jc.R;
import cc.winboll.studio.libapputils.log.LogUtils;
import cc.winboll.studio.libjc.JAR_RUNNING_MODE;
import cc.winboll.studio.libjc.JCMainThread;
import cc.winboll.studio.libjc.net.JCSocketClient;
import cc.winboll.studio.libjc.util.LogUtils;
import cc.winboll.studio.libjc.Main;
final public class MainActivity extends Activity implements JCMainThread.OnMessageListener {
@@ -77,7 +77,7 @@ final public class MainActivity extends Activity implements JCMainThread.OnMessa
// 启动主线程
_JCMainThread = JCMainThread.getInstance(getPackageName());
_JCMainThread.setOnLogListener(this);
_JCMainThread.setRunningMode(JAR_RUNNING_MODE.JC);
//_JCMainThread.setRunningMode(Main.JAR_RUNNING_MODE.JC);
_JCMainThread.start();
// 设置 WinBoll 应用 UI 类型

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Mon Jun 09 01:44:28 HKT 2025
stageCount=1
#Thu Jun 19 20:42:26 HKT 2025
stageCount=2
libraryProject=libaes
baseVersion=15.9
publishVersion=15.9.0
publishVersion=15.9.1
buildCount=0
baseBetaVersion=15.9.1
baseBetaVersion=15.9.2

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Fri Jan 10 22:03:57 GMT 2025
#Tue Jun 24 11:17:30 GMT 2025
stageCount=0
libraryProject=libjc
baseVersion=1.0
publishVersion=1.0.0
buildCount=133
buildCount=135
baseBetaVersion=1.0.1

View File

@@ -21,7 +21,7 @@ public class Main {
public final static int JAR_RUNNING_MODE_JCNDK_DEBUG = 4;
public final static int JAR_RUNNING_MODE_JC = 5;
public final static int JAR_RUNNING_MODE_JC_DEBUG = 6;
public enum JAR_RUNNING_MODE {
public static enum JAR_RUNNING_MODE {
UNKNOWN(JAR_RUNNING_MODE_UNKNOWN),
CONSOLE(JAR_RUNNING_MODE_CONSOLE),
CONSOLE_DEBUG(JAR_RUNNING_MODE_CONSOLE_DEBUG),

View File

@@ -29,7 +29,7 @@ android {
// versionName 更新后需要手动设置
// .winboll/winbollBuildProps.properties 文件的 stageCount=0
// Gradle编译环境下合起来的 versionName 就是 "${versionName}.0"
versionName "15.2"
versionName "15.3"
if(true) {
versionName = genVersionName("${versionName}")
}
@@ -45,9 +45,9 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
api 'cc.winboll.studio:libaes:15.8.0'
api 'cc.winboll.studio:libapputils:15.8.1'
api 'cc.winboll.studio:libappbase:15.8.1'
api 'cc.winboll.studio:libaes:15.9.2'
api 'cc.winboll.studio:libapputils:15.8.4'
api 'cc.winboll.studio:libappbase:15.8.4'
api 'io.github.medyo:android-about-page:2.0.0'
api 'com.github.getActivity:ToastUtils:10.5'

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Tue May 20 20:39:06 HKT 2025
stageCount=6
#Sat Aug 23 13:40:21 HKT 2025
stageCount=3
libraryProject=
baseVersion=15.2
publishVersion=15.2.5
baseVersion=15.3
publishVersion=15.3.2
buildCount=0
baseBetaVersion=15.2.6
baseBetaVersion=15.3.3

View File

@@ -17,7 +17,7 @@ import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity;
import cc.winboll.studio.mymessagemanager.App;
import cc.winboll.studio.mymessagemanager.R;
public class AboutActivity extends WinBollActivity implements IWinBoLLActivity {
public class AboutActivity extends WinBoLLActivity implements IWinBoLLActivity {
public static final String TAG = "AboutActivity";
@@ -79,11 +79,11 @@ public class AboutActivity extends WinBollActivity implements IWinBoLLActivity {
appInfo.setAppName(getString(R.string.app_name));
appInfo.setAppIcon(cc.winboll.studio.libaes.R.drawable.ic_winboll);
appInfo.setAppDescription(getString(R.string.app_description));
appInfo.setAppGitName("APP");
appInfo.setAppGitName("APPBase");
appInfo.setAppGitOwner("Studio");
appInfo.setAppGitAPPBranch(szBranchName);
appInfo.setAppGitAPPSubProjectFolder(szBranchName);
appInfo.setAppHomePage("https://www.winboll.cc/studio/details.php?app=MyMessageManager");
appInfo.setAppHomePage("https://discuz.winboll.cc/forum.php?mod=viewthread&tid=5&extra=page%3D1");
appInfo.setAppAPKName("MyMessageManager");
appInfo.setAppAPKFolderName("MyMessageManager");
return new AboutView(mContext, appInfo);

View File

@@ -103,6 +103,9 @@ abstract public class BaseActivity extends AppCompatActivity {
} else if (R.id.item_defaulttheme == item.getItemId()) {
AESThemeUtil.saveThemeStyleID(this, R.style.MyAppTheme);
recreate();
} else if (R.id.item_defaulttheme == item.getItemId()) {
AESThemeUtil.saveThemeStyleID(this, R.style.MyAppTheme);
recreate();
}
//ToastUtils.show("nThemeStyleID " + Integer.toString(nThemeStyleID));

View File

@@ -128,7 +128,7 @@ public class MainActivity extends BaseActivity {
mToolbar = findViewById(R.id.activitymainASupportToolbar1);
mToolbar.setSubtitle(getString(R.string.activity_name_main));
setSupportActionBar(mToolbar);
boolean isEnableService = mAppConfigUtil.mAppConfigBean.isEnableService();
msvEnableService = findViewById(R.id.activitymainSwitchView1);
msvEnableService.setChecked(isEnableService);
@@ -269,17 +269,9 @@ public class MainActivity extends BaseActivity {
public boolean onCreateOptionsMenu(Menu menu) {
//return super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.toolbar_main, menu);
/*ThemeUtil.BaseTheme baseTheme = ThemeUtil.getTheme(mAppConfigUtil.mAppConfigBean.getAppThemeID());
if (baseTheme == ThemeUtil.BaseTheme.DEFAULT) {
menu.findItem(R.id.app_defaulttheme).setChecked(true);
} else if (baseTheme == ThemeUtil.BaseTheme.SKY) {
menu.findItem(R.id.app_skytheme).setChecked(true);
} else if (baseTheme == ThemeUtil.BaseTheme.GOLDEN) {
menu.findItem(R.id.app_goldentheme).setChecked(true);
}*/
return super.onCreateOptionsMenu(menu);
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.toolbar_main2, menu);
return true;
}
public static void reloadSMS() {
@@ -306,7 +298,7 @@ public class MainActivity extends BaseActivity {
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
} else if (nItemId == R.id.app_log) {
//App.getWinBoLLActivityManager().startLogActivity(this);
App.getWinBoLLActivityManager().startLogActivity(this);
} else if (nItemId == R.id.app_unittest) {
Intent i = new Intent(MainActivity.this, UnitTestActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -324,7 +316,7 @@ public class MainActivity extends BaseActivity {
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
return super.onOptionsItemSelected(item);
}

View File

@@ -4,11 +4,16 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
@@ -16,19 +21,17 @@ import android.widget.Toolbar;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import cc.winboll.studio.libaes.views.AOHPCTCSeekBar;
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.utils.AddressUtils;
import cc.winboll.studio.mymessagemanager.utils.SMSUtil;
import cc.winboll.studio.mymessagemanager.utils.ViewUtil;
import cc.winboll.studio.mymessagemanager.views.BottomPositionFixedScrollView;
import cc.winboll.studio.mymessagemanager.views.SMSListViewForScrollView;
import java.lang.ref.WeakReference;
public class SMSActivity extends BaseActivity {
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 EXTRA_PHONE = "Phone";
final static int MSG_SET_FOCUS = 0;
@@ -36,10 +39,11 @@ public class SMSActivity extends BaseActivity {
Toolbar mToolbar;
String mszPhoneTo;
SMSArrayAdapter mSMSArrayAdapter;
ScrollView mScrollView;
BottomPositionFixedScrollView mScrollView1;
EditText metSMSBody;
SMSActivityBroadcastReceiver mSMSActivityBroadcastReceiver;
Handler mSetFocusHandler;
private boolean isImeVisible = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -47,45 +51,90 @@ public class SMSActivity extends BaseActivity {
setContentView(R.layout.activity_sms);
initView();
mSetFocusHandler = new MyHandler(SMSActivity.this);
scrollScrollView();
setupImeStatusListener();
// 每隔一定时间设置输入框获得焦点
//
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滚动到底部
setupScrollToBottomAfterWindowLoaded();
}
//
// 设置输入框获得焦点的类
//
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();
break;
default:
break;
}
super.handleMessage(msg);
}
}
// 新增窗口加载完成后让mScrollView1滚动到底部
private void setupScrollToBottomAfterWindowLoaded() {
final View rootView = findViewById(android.R.id.content);
// 监听根布局绘制完成(窗口加载完成的标志)
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// 滚动到底部
mScrollView1.post(new Runnable() {
@Override
public void run() {
mScrollView1.fullScroll(ScrollView.FOCUS_DOWN);
}
});
// 移除监听,避免重复触发
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
rootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} 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
protected void onDestroy() {
@@ -94,135 +143,130 @@ public class SMSActivity extends BaseActivity {
}
void initView() {
// 发送端空号码退出
mszPhoneTo = getIntent().getStringExtra(EXTRA_PHONE);
if (mszPhoneTo == null || mszPhoneTo.trim().equals("")) {
finish();
}
// 初始化标题栏
mToolbar = findViewById(R.id.activitysmsASupportToolbar1);
mToolbar = (Toolbar) findViewById(R.id.activitysmsASupportToolbar1);
mToolbar.setSubtitle(getString(R.string.activity_name_smsinphone) + " < Phone : " + AddressUtils.getFormattedAddress(mszPhoneTo) + " >");
setActionBar(mToolbar);
// 初始化滚动窗口
mScrollView = findViewById(R.id.activitysmsinphoneScrollView1);
mScrollView1 = (BottomPositionFixedScrollView) findViewById(R.id.activitysmsScrollView1);
// 初始化发送消息框
//Drawable drawableFrame = AppCompatResources.getDrawable(this, R.drawable.bg_frame);
metSMSBody = findViewById(R.id.viewsmssendpart1EditText1);
//metSMSBody.setBackground(drawableFrame);
metSMSBody = (EditText) findViewById(R.id.viewsmssendpart1EditText1);
metSMSBody.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setupScrollView1Height();
}
});
metSMSBody.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
setupScrollView1Height();
}
});
// 初始化发送拉动控件
final AOHPCTCSeekBar aOHPCTCSeekBar = findViewById(R.id.viewsmssendpart1AOHPCTCSeekBar1);
final AOHPCTCSeekBar aOHPCTCSeekBar = (AOHPCTCSeekBar) findViewById(R.id.viewsmssendpart1AOHPCTCSeekBar1);
aOHPCTCSeekBar.setThumb(getDrawable(R.drawable.ic_message));
aOHPCTCSeekBar.setThumbOffset(20);
aOHPCTCSeekBar.setOnOHPCListener(
new AOHPCTCSeekBar.OnOHPCListener(){
@Override
public void onOHPCommit() {
//Toast.makeText(getApplication(), "Send", Toast.LENGTH_SHORT).show();
sendSMS();
}
});
aOHPCTCSeekBar.setOnOHPCListener(new AOHPCTCSeekBar.OnOHPCListener() {
@Override
public void onOHPCommit() {
sendSMS();
}
});
// 初始化提示框
TextView tvAOHPCTCSeekBarMSG = findViewById(R.id.viewsmssendpart1TextView1);
TextView tvAOHPCTCSeekBarMSG = (TextView) findViewById(R.id.viewsmssendpart1TextView1);
tvAOHPCTCSeekBarMSG.setText(R.string.msg_100sendmsg);
mlvSMS = (SMSListViewForScrollView) findViewById(R.id.activitysmsinphoneListView1);
// 准备数据
mlvSMS = (SMSListViewForScrollView) findViewById(R.id.activitysmsSMSListViewForScrollView1);
mSMSArrayAdapter = new SMSArrayAdapter(SMSActivity.this, mszPhoneTo);
mlvSMS.setAdapter(mSMSArrayAdapter);
// 设置短信列表滚动到底部就取消已发送的通知消息
//
mlvSMS.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) {
// 滑动到了底部
mSMSArrayAdapter.cancelMessageNotification();
}
}
});
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) {
mSMSArrayAdapter.cancelMessageNotification();
}
}
});
mSMSActivityBroadcastReceiver = new SMSActivityBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_NOTIFY_SMS_CHANGED);
IntentFilter intentFilter = new IntentFilter(ACTION_NOTIFY_SMS_CHANGED);
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() {
mSMSArrayAdapter.reLoadSMSList(SMSActivity.this, mszPhoneTo);
mSMSArrayAdapter.notifyDataSetChanged();
}
//
// 滚动消息文本框
//
void scrollScrollView() {
ViewUtil.scrollScrollView(mScrollView);
ViewUtil.scrollScrollView(mScrollView1);
}
//
// 发送短信
//
void sendSMS() {
// 空消息不发送
String szSMSBody = metSMSBody.getText().toString();
if (szSMSBody.equals("")) {
Toast.makeText(getApplication(), "没有消息内容可发送。", Toast.LENGTH_SHORT).show();
return;
}
// 发送短信
if (SMSUtil.sendMessageByInterface2(this, mszPhoneTo, szSMSBody)) {
metSMSBody.setText("");
new Handler().postDelayed(new Runnable(){
@Override
public void run() {
updateSMSView();
ViewUtil.scrollScrollView(mScrollView);
}
}, 1000);
metSMSBody.clearFocus();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
updateSMSView();
ViewUtil.scrollScrollView(mScrollView1);
}
}, 1000);
}
}
class SMSActivityBroadcastReceiver extends BroadcastReceiver {
public SMSActivityBroadcastReceiver() {
//LogUtils.d(TAG, "SMSActivityBroadcastReceiver()");
}
public SMSActivityBroadcastReceiver() {}
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case ACTION_NOTIFY_SMS_CHANGED :
//Toast.makeText(context, "ACTION_NOTIFY_SMS_CHANGED", Toast.LENGTH_SHORT).show();
updateSMSView();
ViewUtil.scrollScrollView(mScrollView);
//LogUtils.d(TAG, "ACTION_NOTIFY_SMS_CHANGED");
break;
default:
throw new IllegalStateException("Unexpected value: " + intent.getAction());
if (ACTION_NOTIFY_SMS_CHANGED.equals(intent.getAction())) {
updateSMSView();
ViewUtil.scrollScrollView(mScrollView1);
} else {
throw new IllegalStateException("Unexpected value: " + intent.getAction());
}
}
}
}

View File

@@ -13,9 +13,9 @@ import cc.winboll.studio.libaes.beans.AESThemeBean;
import cc.winboll.studio.libaes.utils.AESThemeUtil;
import cc.winboll.studio.libappbase.winboll.IWinBoLLActivity;
public class WinBollActivity extends AppCompatActivity implements IWinBoLLActivity {
public class WinBoLLActivity extends AppCompatActivity implements IWinBoLLActivity {
public static final String TAG = "WinBollActivity";
public static final String TAG = "WinBoLLActivity";
protected volatile AESThemeBean.ThemeType mThemeType;

View File

@@ -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;
}
}

View File

@@ -10,36 +10,40 @@
android:layout_height="@dimen/toolbar_height"
android:id="@+id/activitysmsASupportToolbar1"/>
<RelativeLayout
android:orientation="vertical"
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="10dp">
android:layout_height="0dp"
android:layout_weight="1.0"
android:id="@+id/activitysmsScrollView2">
<ScrollView
android:layout_alignParentTop="true"
android:layout_above="@+id/activitysmsinclude1"
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="@+id/activitysmsinphoneScrollView1"
android:layout_weight="1.0"
android:isScrollContainer="false">
android:layout_height="match_parent"
android:id="@+id/activitysmsLinearLayout1">
<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_height="wrap_content"
android:id="@+id/activitysmsinphoneListView1"/>
android:id="@+id/activitysmsinclude1"/>
</LinearLayout>
</ScrollView>
<include
android:layout_alignParentBottom="true"
layout="@layout/view_smssend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/activitysmsinclude1"/>
</RelativeLayout>
</ScrollView>
</LinearLayout>

View File

@@ -34,7 +34,7 @@
</ScrollView>
<cc.winboll.studio.shared.log.LogView
<cc.winboll.studio.libappbase.LogView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"

View File

@@ -7,6 +7,18 @@
android:layout_height="wrap_content"
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
android:scrollbars="vertical"
android:maxHeight="150dp"
@@ -17,17 +29,6 @@
android:id="@+id/viewsmssendpart1EditText1"
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>

View File

@@ -17,26 +17,4 @@
<item
android:id="@+id/app_smsrule"
android:title="@string/text_smsrule"/>
<item android:title="@string/app_developoptions">
<menu>
<item
android:id="@+id/app_log"
android:title="@string/app_log"/>
<item
android:id="@+id/app_unittest"
android:title="@string/app_unittest"/>
<item
android:id="@+id/app_crashtest"
android:title="@string/app_crashtest"/>
</menu>
</item>
<item
android:id="@+id/app_appsettings"
android:title="@string/text_appsettings"/>
<item
android:id="@+id/app_about"
android:title="@string/app_about"/>
<item
android:id="@+id/app_smsrecycle"
android:title="@string/app_smsrecycle"/>
</menu>

View File

@@ -0,0 +1,26 @@
<?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:title="@string/app_developoptions">
<menu>
<item
android:id="@+id/app_log"
android:title="@string/app_log"/>
<item
android:id="@+id/app_unittest"
android:title="@string/app_unittest"/>
<item
android:id="@+id/app_crashtest"
android:title="@string/app_crashtest"/>
</menu>
</item>
<item
android:id="@+id/app_appsettings"
android:title="@string/text_appsettings"/>
<item
android:id="@+id/app_about"
android:title="@string/app_about"/>
<item
android:id="@+id/app_smsrecycle"
android:title="@string/app_smsrecycle"/>
</menu>

View File

@@ -41,6 +41,6 @@
<string name="text_appsettings">应用设置</string>
<string name="text_ttsplaydelaytimes">TTS播放延迟时间</string>
<string name="msg_newsms">接收到新的消息。</string>
<string name="msg_100sendmsg">&gt;&gt;&gt;图标动到 100% 以发送信息&gt;&gt;&gt;</string>
<string name="msg_100applysettings">&gt;&gt;&gt;图标动到 100% 应用设置&gt;&gt;&gt;</string>
<string name="msg_100sendmsg">&gt;&gt;&gt;拉动到100%可发信息&gt;&gt;&gt;</string>
<string name="msg_100applysettings">&gt;&gt;&gt;拉动到100%应用设置&gt;&gt;&gt;</string>
</resources>

View File

@@ -22,6 +22,7 @@
// JC 项目编译设置
//include ':jc'
//include ':libjc'
//rootProject.name = "jc"
// AES 项目编译设置