Compare commits

...

8 Commits

Author SHA1 Message Date
ZhanGSKen
d875b6965d <timestamp>APK 15.0.4 release Publish. 2025-05-06 18:33:32 +08:00
ZhanGSKen
bc873852c2 修复时间戳复制格式设置未保存问题 2025-05-06 18:32:51 +08:00
ZhanGSKen
b032de55dc 添加说明书 2025-05-06 18:14:34 +08:00
ZhanGSKen
8fa20b56ec <timestamp>APK 15.0.3 release Publish. 2025-05-06 18:01:46 +08:00
ZhanGSKen
1ca93a610e 优化常驻通知电量消耗 2025-05-06 17:59:57 +08:00
ZhanGSKen
6555346618 重构通知栏模块 2025-05-06 17:04:14 +08:00
ZhanGSKen
df6633046c <timestamp>APK 15.0.2 release Publish. 2025-05-06 11:34:02 +08:00
ZhanGSKen
7d35d5a9b8 添加通知栏打开主窗口功能 2025-05-06 11:33:28 +08:00
9 changed files with 125 additions and 69 deletions

6
timestamp/README.md Normal file
View File

@@ -0,0 +1,6 @@
## TimpStamp
## 时间戳工具集
## 使用要点:
1。常驻通知栏按钮的正常使用
需要设置允许应用[写入剪贴板]的[始终允许]权限。

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Tue May 06 11:27:46 HKT 2025
stageCount=2
#Tue May 06 18:33:32 HKT 2025
stageCount=5
libraryProject=
baseVersion=15.0
publishVersion=15.0.1
publishVersion=15.0.4
buildCount=0
baseBetaVersion=15.0.2
baseBetaVersion=15.0.5

View File

@@ -5,9 +5,13 @@
<!-- 运行前台服务 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.READ_CLIPBOARD" />
<uses-permission android:name="android.permission.WRITE_CLIPBOARD" />
<!-- READ_CLIPBOARD -->
<uses-permission android:name="android.permission.READ_CLIPBOARD"/>
<!-- WRITE_CLIPBOARD -->
<uses-permission android:name="android.permission.WRITE_CLIPBOARD"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"

View File

@@ -31,8 +31,6 @@ import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Timer;
import java.util.TimerTask;
public class MainService extends Service {
@@ -45,11 +43,11 @@ public class MainService extends Service {
Notification mNotification;
RemoteViews mRemoteViews;
TextView mtvTimeStamp;
Timer mTimer;
//Timer mTimer;
private static boolean _mIsServiceAlive;
public static final String EXTRA_APKFILEPATH = "EXTRA_APKFILEPATH";
final static int MSG_INSTALL_APK = 0;
MyHandler mMyHandler;
static MyHandler _MyHandler;
MyServiceConnection mMyServiceConnection;
MainActivity mInstallCompletedFollowUpActivity;
@@ -77,7 +75,7 @@ public class MainService extends Service {
LogUtils.d(TAG, "onCreate()");
_mIsServiceAlive = false;
mMyHandler = new MyHandler();
_MyHandler = new MyHandler();
if (mMyServiceConnection == null) {
mMyServiceConnection = new MyServiceConnection();
}
@@ -102,17 +100,18 @@ public class MainService extends Service {
wakeupAndBindAssistant();
LogUtils.d(TAG, "running...");
_MyHandler.sendEmptyMessage(MSG_UPDATE_TIMESTAMP);
mTimer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
//System.out.println("定时任务执行了");
mMyHandler.sendEmptyMessage(MSG_UPDATE_TIMESTAMP);
}
};
// 延迟1秒后开始执行之后每隔100毫秒执行一次
mTimer.schedule(task, 1000, 100);
// mTimer = new Timer();
// TimerTask task = new TimerTask() {
// @Override
// public void run() {
// //System.out.println("定时任务执行了");
// mMyHandler.sendEmptyMessage(MSG_UPDATE_TIMESTAMP);
// }
// };
// // 延迟1秒后开始执行之后每隔100毫秒执行一次
// mTimer.schedule(task, 1000, 100);
@@ -126,14 +125,17 @@ public class MainService extends Service {
@Override
public void onDestroy() {
super.onDestroy();
if (mTimer != null) {
mTimer.cancel();
}
// if (mTimer != null) {
// mTimer.cancel();
// }
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.cancelAll();
_mIsServiceAlive = false;
_MyHandler = null;
LogUtils.d(TAG, "onDestroy()");
}
@@ -217,9 +219,9 @@ public class MainService extends Service {
String szTimeStampFormatString = AppConfigsUtil.getInstance(MainService.this).getAppConfigsModel().getTimeStampFormatString();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(szTimeStampFormatString);
String formattedDateTime = ldt.format(formatter);
TimeStampRemoteViewsUtil.getInstance(MainService.this).showNotification(formattedDateTime);
TimeStampRemoteViewsUtil.getInstance(MainService.this).showNotification(formattedDateTime + " 已复制");
//LogUtils.d(TAG, "Hello, World");
LogUtils.d(TAG, "Hello, World! " + formattedDateTime);
break;
}
default:
@@ -228,4 +230,10 @@ public class MainService extends Service {
super.handleMessage(message);
}
}
public static void updateCopiedTimeStamp() {
if (_MyHandler != null) {
_MyHandler.sendEmptyMessage(MSG_UPDATE_TIMESTAMP);
}
}
}

View File

@@ -63,6 +63,7 @@ public class AppConfigsModel extends BaseBean {
super.writeThisToJsonWriter(jsonWriter);
jsonWriter.name("isEnableService").value(isEnableService());
jsonWriter.name("timeStampFormatString").value(getTimeStampFormatString());
jsonWriter.name("timeStampCopyFormatString").value(getTimeStampCopyFormatString());
}
@Override
@@ -72,6 +73,8 @@ public class AppConfigsModel extends BaseBean {
setIsEnableService(jsonReader.nextBoolean());
} else if (name.equals("timeStampFormatString")) {
setTimeStampFormatString(jsonReader.nextString());
} else if (name.equals("timeStampCopyFormatString")) {
setTimeStampCopyFormatString(jsonReader.nextString());
} else {
return false;
}

View File

@@ -10,6 +10,7 @@ import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.timestamp.MainService;
import cc.winboll.studio.timestamp.utils.AppConfigsUtil;
import cc.winboll.studio.timestamp.utils.ClipboardUtil;
import java.time.Instant;
@@ -39,6 +40,7 @@ public class ButtonClickReceiver extends BroadcastReceiver {
// 比如显示一个Toast
Toast.makeText(context, formattedDateTime + " 已复制", Toast.LENGTH_SHORT).show();
MainService.updateCopiedTimeStamp();
}
}

View File

@@ -120,7 +120,7 @@ public class NotificationHelper {
PendingIntent pendingIntent = createPendingIntent(intent);
Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID_TEMPORARY)
Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID_FOREGROUND)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher))
//.setContentTitle(title)

View File

@@ -5,17 +5,15 @@ package cc.winboll.studio.timestamp.utils;
* @Date 2025/05/05 21:10
* @Describe TimeStampRemoteViewsUtil
*/
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.widget.RemoteViews;
import android.widget.TextView;
import androidx.core.app.NotificationCompat;
import cc.winboll.studio.timestamp.MainActivity;
import cc.winboll.studio.timestamp.R;
import cc.winboll.studio.timestamp.receivers.ButtonClickReceiver;
import android.app.Notification;
public class TimeStampRemoteViewsUtil {
@@ -25,13 +23,16 @@ public class TimeStampRemoteViewsUtil {
static volatile TimeStampRemoteViewsUtil _TimeStampRemoteViewsUtil;
Context mContext;
NotificationHelper mNotificationHelper;
RemoteViews mRemoteViews;
TextView mtvMessage;
Notification mNotification;
Intent mIntentMain;
TimeStampRemoteViewsUtil(Context context) {
mContext = context;
createNotificationChannel();
mNotificationHelper = new NotificationHelper(context);
//createNotificationChannel();
}
public static synchronized TimeStampRemoteViewsUtil getInstance(Context context) {
@@ -40,37 +41,80 @@ public class TimeStampRemoteViewsUtil {
}
return _TimeStampRemoteViewsUtil;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "自定义视图通知通道";
String description = "用于展示自定义视图的通知通道";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
NotificationManager notificationManager = mContext.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
// private void createNotificationChannel() {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// CharSequence name = "自定义视图通知通道";
// String description = "用于展示自定义视图的通知通道";
// int importance = NotificationManager.IMPORTANCE_HIGH;
// NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
// channel.setDescription(description);
// NotificationManager notificationManager = mContext.getSystemService(NotificationManager.class);
// notificationManager.createNotificationChannel(channel);
// }
// }
// public void showNotification(String msg) {
// if (mRemoteViews == null) {
// // 创建 RemoteViews 对象,加载布局
// mRemoteViews = new RemoteViews(mContext.getPackageName(), R.layout.custom_notification_layout);
//
// }
// // 自定义 TextView 的文本
// mRemoteViews.setTextViewText(R.id.tv_timestamp, msg);
// // 自定义 TextView 的文本颜色
// mRemoteViews.setTextColor(R.id.tv_timestamp, mContext.getResources().getColor(R.color.colorAccent, null));
// // 这里虽然不能直接设置字体大小,但可以通过反射等方式尝试(不推荐,且有兼容性问题)
//
// // 创建点击通知后的意图
// Intent intent = new Intent(mContext, MainActivity.class);
// PendingIntent pendingMainIntent = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// // 设置通知的点击事件
// mRemoteViews.setOnClickPendingIntent(R.id.tv_timestamp, pendingMainIntent);
//
// // 创建点击按钮后要发送的广播 Intent
// Intent broadcastIntent = new Intent(ButtonClickReceiver.BUTTON_COPYTIMESTAMP_ACTION);
// android.app.PendingIntent pendingIntent = android.app.PendingIntent.getBroadcast(
// mContext,
// 0,
// broadcastIntent,
// android.app.PendingIntent.FLAG_UPDATE_CURRENT
// );
//
// // 为按钮设置点击事件
// mRemoteViews.setOnClickPendingIntent(R.id.btn_copytimestamp, pendingIntent);
//
// // 构建通知
// NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, CHANNEL_ID)
// .setSmallIcon(android.R.drawable.ic_dialog_info)
// .setContent(mRemoteViews)
// .setPriority(NotificationCompat.PRIORITY_HIGH)
// .setOngoing(true)
// .setAutoCancel(true);
//
// // 显示通知
// NotificationManager notificationManager = mContext.getSystemService(NotificationManager.class);
// mNotification = builder.build();
// notificationManager.notify(1, mNotification);
// }
public void showNotification(String msg) {
if (mRemoteViews == null) {
// 创建 RemoteViews 对象,加载布局
mRemoteViews = new RemoteViews(mContext.getPackageName(), R.layout.custom_notification_layout);
}
// 自定义 TextView 的文本
mRemoteViews.setTextViewText(R.id.tv_timestamp, msg);
// 自定义 TextView 的文本颜色
mRemoteViews.setTextColor(R.id.tv_timestamp, mContext.getResources().getColor(R.color.colorAccent, null));
// 这里虽然不能直接设置字体大小,但可以通过反射等方式尝试(不推荐,且有兼容性问题)
// 创建点击通知后的意图
//Intent intent = new Intent(mContext, MainActivity.class);
//PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mIntentMain = new Intent(mContext, MainActivity.class);
PendingIntent pendingMainIntent = PendingIntent.getActivity(mContext, 0, mIntentMain, PendingIntent.FLAG_UPDATE_CURRENT);
// 设置通知的点击事件
//mRemoteViews.setOnClickPendingIntent(R.id.btn_copytimestamp, pendingIntent);
mRemoteViews.setOnClickPendingIntent(R.id.tv_timestamp, pendingMainIntent);
// 创建点击按钮后要发送的广播 Intent
Intent broadcastIntent = new Intent(ButtonClickReceiver.BUTTON_COPYTIMESTAMP_ACTION);
android.app.PendingIntent pendingIntent = android.app.PendingIntent.getBroadcast(
@@ -82,18 +126,7 @@ public class TimeStampRemoteViewsUtil {
// 为按钮设置点击事件
mRemoteViews.setOnClickPendingIntent(R.id.btn_copytimestamp, pendingIntent);
// 构建通知
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, CHANNEL_ID)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContent(mRemoteViews)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setOngoing(true)
.setAutoCancel(true);
// 显示通知
NotificationManager notificationManager = mContext.getSystemService(NotificationManager.class);
mNotification = builder.build();
notificationManager.notify(1, mNotification);
mNotificationHelper.showCustomForegroundNotification(mIntentMain, mRemoteViews, mRemoteViews);
}
}

View File

@@ -1,5 +1,5 @@
<resources>
<string name="app_name">TimeStamp</string>
<string name="text_aboutservernotification">This is the prompt window when the SMS service runs, which you can set to hide this class notification in the notification message settings.</string>
<string name="accessibility_service_description">Accessibility service description.</string>
</resources>