添加带图标的设置菜单按钮

This commit is contained in:
2025-12-09 20:48:44 +08:00
parent eaf16f1a41
commit fa5c6db163
5 changed files with 96 additions and 16 deletions

View File

@@ -18,13 +18,17 @@ def genVersionName(def versionName){
} }
android { android {
compileSdkVersion 32
buildToolsVersion "32.0.0" // 1. compileSdkVersion必须 ≥ targetSdkVersion建议直接等于 targetSdkVersion30
compileSdkVersion 30
// 2. buildToolsVersion需匹配 compileSdkVersion建议使用 30.x.x 最新稳定版(无需高于 compileSdkVersion
buildToolsVersion "30.0.3" // 这是 30 对应的最新稳定版,避免使用 beta 版
defaultConfig { defaultConfig {
applicationId "cc.winboll.studio.timestamp" applicationId "cc.winboll.studio.timestamp"
minSdkVersion 24 minSdkVersion 23
targetSdkVersion 29 targetSdkVersion 30
versionCode 1 versionCode 1
// versionName 更新后需要手动设置 // versionName 更新后需要手动设置
// .winboll/winbollBuildProps.properties 文件的 stageCount=0 // .winboll/winbollBuildProps.properties 文件的 stageCount=0
@@ -34,9 +38,24 @@ android {
versionName = genVersionName("${versionName}") versionName = genVersionName("${versionName}")
} }
} }
// 米盟 SDK
packagingOptions {
doNotStrip "*/*/libmimo_1011.so"
}
} }
dependencies { dependencies {
// 米盟
api 'com.miui.zeus:mimo-ad-sdk:5.3.+'//请使用最新版sdk
//注意以下5个库必须要引入
//api 'androidx.appcompat:appcompat:1.4.1'
api 'androidx.recyclerview:recyclerview:1.0.0'
api 'com.google.code.gson:gson:2.8.5'
api 'com.github.bumptech.glide:glide:4.9.0'
//annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
// SSH // SSH
api 'com.jcraft:jsch:0.1.55' api 'com.jcraft:jsch:0.1.55'
// Html 解析 // Html 解析

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Tue Dec 09 12:14:13 GMT 2025 #Tue Dec 09 12:47:32 GMT 2025
stageCount=0 stageCount=0
libraryProject= libraryProject=
baseVersion=15.12 baseVersion=15.12
publishVersion=15.12.0 publishVersion=15.12.0
buildCount=3 buildCount=9
baseBetaVersion=15.12.1 baseBetaVersion=15.12.1

View File

@@ -1,6 +1,7 @@
package cc.winboll.studio.timestamp; package cc.winboll.studio.timestamp;
import android.os.Bundle; import android.os.Bundle;
import android.view.Menu;
import android.view.View; import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Switch; import android.widget.Switch;
@@ -10,12 +11,12 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.LogView; import cc.winboll.studio.libappbase.LogView;
import cc.winboll.studio.libappbase.ToastUtils;
import cc.winboll.studio.timestamp.MainService; import cc.winboll.studio.timestamp.MainService;
import cc.winboll.studio.timestamp.R; import cc.winboll.studio.timestamp.R;
import cc.winboll.studio.timestamp.utils.AppConfigsUtil; import cc.winboll.studio.timestamp.utils.AppConfigsUtil;
import cc.winboll.studio.timestamp.utils.ClipboardUtil; import cc.winboll.studio.timestamp.utils.ClipboardUtil;
import cc.winboll.studio.timestamp.utils.TimeStampUtil; import cc.winboll.studio.timestamp.utils.TimeStampUtil;
import java.lang.reflect.Method;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
@@ -29,7 +30,7 @@ public class MainActivity extends AppCompatActivity {
TextView mtvTimeStampFormatString; TextView mtvTimeStampFormatString;
EditText metTimeStampCopyFormatString; EditText metTimeStampCopyFormatString;
TextView mtvTimeStampCopyFormatString; TextView mtvTimeStampCopyFormatString;
LogView mLogView; LogView mLogView;
Switch mswEnableMainService; Switch mswEnableMainService;
@@ -40,17 +41,17 @@ public class MainActivity extends AppCompatActivity {
Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar); Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
metTimeStampFormatString = findViewById(R.id.et_timestampformatstring); metTimeStampFormatString = findViewById(R.id.et_timestampformatstring);
mtvTimeStampFormatString = findViewById(R.id.tv_timestampformatstring); mtvTimeStampFormatString = findViewById(R.id.tv_timestampformatstring);
metTimeStampCopyFormatString = findViewById(R.id.et_timestampcopyformatstring); metTimeStampCopyFormatString = findViewById(R.id.et_timestampcopyformatstring);
mtvTimeStampCopyFormatString = findViewById(R.id.tv_timestampcopyformatstring); mtvTimeStampCopyFormatString = findViewById(R.id.tv_timestampcopyformatstring);
metTimeStampFormatString.setText(AppConfigsUtil.getInstance(this).getAppConfigsModel().getTimeStampFormatString()); metTimeStampFormatString.setText(AppConfigsUtil.getInstance(this).getAppConfigsModel().getTimeStampFormatString());
showPreViewResult(metTimeStampFormatString, mtvTimeStampFormatString); showPreViewResult(metTimeStampFormatString, mtvTimeStampFormatString);
metTimeStampCopyFormatString.setText(AppConfigsUtil.getInstance(this).getAppConfigsModel().getTimeStampCopyFormatString()); metTimeStampCopyFormatString.setText(AppConfigsUtil.getInstance(this).getAppConfigsModel().getTimeStampCopyFormatString());
showPreViewResult(metTimeStampCopyFormatString, mtvTimeStampCopyFormatString); showPreViewResult(metTimeStampCopyFormatString, mtvTimeStampCopyFormatString);
mswEnableMainService = findViewById(R.id.activitymainSwitch1); mswEnableMainService = findViewById(R.id.activitymainSwitch1);
mswEnableMainService.setChecked(AppConfigsUtil.getInstance(this).loadAppConfigs().isEnableService()); mswEnableMainService.setChecked(AppConfigsUtil.getInstance(this).loadAppConfigs().isEnableService());
@@ -67,19 +68,56 @@ public class MainActivity extends AppCompatActivity {
mLogView.start(); mLogView.start();
} }
// 1. 反射核心方法:强制显示菜单图标
private void forceShowMenuIcons(Menu menu) {
if (menu == null) {
return; // 避免空指针(低版本兼容)
}
try {
// 1.1 获取系统 MenuBuilder 类(隐藏类,需通过反射访问)
Class<?> menuBuilderClass = Class.forName("com.android.internal.view.menu.MenuBuilder");
// 1.2 获取 setOptionalIconsVisible 方法(参数为 boolean控制图标显示
Method setIconsVisibleMethod = menuBuilderClass.getDeclaredMethod(
"setOptionalIconsVisible", boolean.class
);
// 1.3 开放私有方法访问权限(关键:系统方法默认是 private
setIconsVisibleMethod.setAccessible(true);
// 1.4 调用方法:传入 menu 对象 + true显示图标
setIconsVisibleMethod.invoke(menu, true);
} catch (Exception e) {
// 捕获反射异常(避免低版本系统类名/方法名变更导致崩溃)
LogUtils.d(TAG, e, Thread.currentThread().getStackTrace());
//e.printStackTrace();
}
}
// 2. 加载菜单(正常加载你的 menu.xml
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_main, menu); // 替换为你的菜单文件名
return true;
}
// 3. 关键:在菜单打开时触发反射(确保每次打开菜单都生效)
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
forceShowMenuIcons(menu); // 调用反射方法显示图标
return super.onMenuOpened(featureId, menu);
}
public void onSetMainServiceStatus(View view) { public void onSetMainServiceStatus(View view) {
MainService.setMainServiceStatus(this, mswEnableMainService.isChecked()); MainService.setMainServiceStatus(this, mswEnableMainService.isChecked());
} }
public void onSaveFormatString(View view) { public void onSaveFormatString(View view) {
if(showPreViewResult(metTimeStampFormatString, mtvTimeStampFormatString)) { if (showPreViewResult(metTimeStampFormatString, mtvTimeStampFormatString)) {
AppConfigsUtil.getInstance(this).getAppConfigsModel().setTimeStampFormatString(metTimeStampFormatString.getText().toString()); AppConfigsUtil.getInstance(this).getAppConfigsModel().setTimeStampFormatString(metTimeStampFormatString.getText().toString());
AppConfigsUtil.getInstance(this).saveAppConfigs(); AppConfigsUtil.getInstance(this).saveAppConfigs();
} }
} }
public void onSaveCopyFormatString(View view) { public void onSaveCopyFormatString(View view) {
if(showPreViewResult(metTimeStampCopyFormatString, mtvTimeStampCopyFormatString)) { if (showPreViewResult(metTimeStampCopyFormatString, mtvTimeStampCopyFormatString)) {
AppConfigsUtil.getInstance(this).getAppConfigsModel().setTimeStampCopyFormatString(metTimeStampCopyFormatString.getText().toString()); AppConfigsUtil.getInstance(this).getAppConfigsModel().setTimeStampCopyFormatString(metTimeStampCopyFormatString.getText().toString());
AppConfigsUtil.getInstance(this).saveAppConfigs(); AppConfigsUtil.getInstance(this).saveAppConfigs();
} }
@@ -100,20 +138,20 @@ public class MainActivity extends AppCompatActivity {
} }
return false; return false;
} }
public void onTimeStamp(View view) { public void onTimeStamp(View view) {
// 在这里编写按钮点击后要执行的代码 // 在这里编写按钮点击后要执行的代码
TimeStampUtil.getInstance(this).genTimeStamp(); TimeStampUtil.getInstance(this).genTimeStamp();
String formattedDateTime = TimeStampUtil.getInstance(this).getTimeStampCopyString(); String formattedDateTime = TimeStampUtil.getInstance(this).getTimeStampCopyString();
ClipboardUtil.copyTextToClipboard(this, formattedDateTime); ClipboardUtil.copyTextToClipboard(this, formattedDateTime);
// 更新时间戳文本框显示内容 // 更新时间戳文本框显示内容
EditText etTimeStamp = findViewById(R.id.et_timestamp); EditText etTimeStamp = findViewById(R.id.et_timestamp);
etTimeStamp.setText(formattedDateTime); etTimeStamp.setText(formattedDateTime);
// 输出一个提示音 // 输出一个提示音
TimeStampUtil.getInstance(this).playNotifyMusic(this); TimeStampUtil.getInstance(this).playNotifyMusic(this);
// 比如显示一个 Toast // 比如显示一个 Toast
Toast.makeText(this, "时间戳:\n" + TimeStampUtil.getInstance(this).getTimeStampCopyString() + "\n已拷贝到剪贴板。", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "时间戳:\n" + TimeStampUtil.getInstance(this).getTimeStampCopyString() + "\n已拷贝到剪贴板。", Toast.LENGTH_SHORT).show();
MainService.updateCopiedTimeStamp(); MainService.updateCopiedTimeStamp();

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#ff000000"
android:pathData="M12,15.5A3.5,3.5 0,0 1,8.5 12A3.5,3.5 0,0 1,12 8.5A3.5,3.5 0,0 1,15.5 12A3.5,3.5 0,0 1,12 15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"/>
</vector>

View File

@@ -0,0 +1,12 @@
<?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_settings"
android:title="Settings"
android:icon="@drawable/ic_settings"
android:showAsAction="ifRoom"
app:showAsAction="ifRoom"/>
</menu>