Compare commits
7 Commits
timestamp-
...
timestamp-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a3383a43b | ||
|
|
d875b6965d | ||
|
|
bc873852c2 | ||
|
|
b032de55dc | ||
|
|
8fa20b56ec | ||
|
|
1ca93a610e | ||
|
|
6555346618 |
6
timestamp/README.md
Normal file
6
timestamp/README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
## TimpStamp
|
||||||
|
## 时间戳工具集
|
||||||
|
|
||||||
|
## 使用要点:
|
||||||
|
1。常驻通知栏按钮的正常使用,
|
||||||
|
需要设置允许应用[写入剪贴板]的[始终允许]权限。
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Tue May 06 11:34:02 HKT 2025
|
#Tue May 06 18:33:59 HKT 2025
|
||||||
stageCount=3
|
stageCount=6
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=15.0
|
baseVersion=15.0
|
||||||
publishVersion=15.0.2
|
publishVersion=15.0.5
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.0.3
|
baseBetaVersion=15.0.6
|
||||||
|
|||||||
@@ -5,8 +5,12 @@
|
|||||||
|
|
||||||
<!-- 运行前台服务 -->
|
<!-- 运行前台服务 -->
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
<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
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ import java.time.Instant;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
public class MainService extends Service {
|
public class MainService extends Service {
|
||||||
|
|
||||||
@@ -45,11 +43,11 @@ public class MainService extends Service {
|
|||||||
Notification mNotification;
|
Notification mNotification;
|
||||||
RemoteViews mRemoteViews;
|
RemoteViews mRemoteViews;
|
||||||
TextView mtvTimeStamp;
|
TextView mtvTimeStamp;
|
||||||
Timer mTimer;
|
//Timer mTimer;
|
||||||
private static boolean _mIsServiceAlive;
|
private static boolean _mIsServiceAlive;
|
||||||
public static final String EXTRA_APKFILEPATH = "EXTRA_APKFILEPATH";
|
public static final String EXTRA_APKFILEPATH = "EXTRA_APKFILEPATH";
|
||||||
final static int MSG_INSTALL_APK = 0;
|
final static int MSG_INSTALL_APK = 0;
|
||||||
MyHandler mMyHandler;
|
static MyHandler _MyHandler;
|
||||||
MyServiceConnection mMyServiceConnection;
|
MyServiceConnection mMyServiceConnection;
|
||||||
MainActivity mInstallCompletedFollowUpActivity;
|
MainActivity mInstallCompletedFollowUpActivity;
|
||||||
|
|
||||||
@@ -77,7 +75,7 @@ public class MainService extends Service {
|
|||||||
LogUtils.d(TAG, "onCreate()");
|
LogUtils.d(TAG, "onCreate()");
|
||||||
_mIsServiceAlive = false;
|
_mIsServiceAlive = false;
|
||||||
|
|
||||||
mMyHandler = new MyHandler();
|
_MyHandler = new MyHandler();
|
||||||
if (mMyServiceConnection == null) {
|
if (mMyServiceConnection == null) {
|
||||||
mMyServiceConnection = new MyServiceConnection();
|
mMyServiceConnection = new MyServiceConnection();
|
||||||
}
|
}
|
||||||
@@ -102,17 +100,18 @@ public class MainService extends Service {
|
|||||||
wakeupAndBindAssistant();
|
wakeupAndBindAssistant();
|
||||||
|
|
||||||
LogUtils.d(TAG, "running...");
|
LogUtils.d(TAG, "running...");
|
||||||
|
_MyHandler.sendEmptyMessage(MSG_UPDATE_TIMESTAMP);
|
||||||
|
|
||||||
mTimer = new Timer();
|
// mTimer = new Timer();
|
||||||
TimerTask task = new TimerTask() {
|
// TimerTask task = new TimerTask() {
|
||||||
@Override
|
// @Override
|
||||||
public void run() {
|
// public void run() {
|
||||||
//System.out.println("定时任务执行了");
|
// //System.out.println("定时任务执行了");
|
||||||
mMyHandler.sendEmptyMessage(MSG_UPDATE_TIMESTAMP);
|
// mMyHandler.sendEmptyMessage(MSG_UPDATE_TIMESTAMP);
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
// 延迟1秒后开始执行,之后每隔100毫秒执行一次
|
// // 延迟1秒后开始执行,之后每隔100毫秒执行一次
|
||||||
mTimer.schedule(task, 1000, 100);
|
// mTimer.schedule(task, 1000, 100);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -126,14 +125,17 @@ public class MainService extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
if (mTimer != null) {
|
|
||||||
mTimer.cancel();
|
|
||||||
}
|
// if (mTimer != null) {
|
||||||
|
// mTimer.cancel();
|
||||||
|
// }
|
||||||
|
|
||||||
NotificationManager notificationManager = getSystemService(NotificationManager.class);
|
NotificationManager notificationManager = getSystemService(NotificationManager.class);
|
||||||
notificationManager.cancelAll();
|
notificationManager.cancelAll();
|
||||||
|
|
||||||
_mIsServiceAlive = false;
|
_mIsServiceAlive = false;
|
||||||
|
_MyHandler = null;
|
||||||
LogUtils.d(TAG, "onDestroy()");
|
LogUtils.d(TAG, "onDestroy()");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,9 +219,9 @@ public class MainService extends Service {
|
|||||||
String szTimeStampFormatString = AppConfigsUtil.getInstance(MainService.this).getAppConfigsModel().getTimeStampFormatString();
|
String szTimeStampFormatString = AppConfigsUtil.getInstance(MainService.this).getAppConfigsModel().getTimeStampFormatString();
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(szTimeStampFormatString);
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(szTimeStampFormatString);
|
||||||
String formattedDateTime = ldt.format(formatter);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -228,4 +230,10 @@ public class MainService extends Service {
|
|||||||
super.handleMessage(message);
|
super.handleMessage(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void updateCopiedTimeStamp() {
|
||||||
|
if (_MyHandler != null) {
|
||||||
|
_MyHandler.sendEmptyMessage(MSG_UPDATE_TIMESTAMP);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ public class AppConfigsModel extends BaseBean {
|
|||||||
super.writeThisToJsonWriter(jsonWriter);
|
super.writeThisToJsonWriter(jsonWriter);
|
||||||
jsonWriter.name("isEnableService").value(isEnableService());
|
jsonWriter.name("isEnableService").value(isEnableService());
|
||||||
jsonWriter.name("timeStampFormatString").value(getTimeStampFormatString());
|
jsonWriter.name("timeStampFormatString").value(getTimeStampFormatString());
|
||||||
|
jsonWriter.name("timeStampCopyFormatString").value(getTimeStampCopyFormatString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -72,6 +73,8 @@ public class AppConfigsModel extends BaseBean {
|
|||||||
setIsEnableService(jsonReader.nextBoolean());
|
setIsEnableService(jsonReader.nextBoolean());
|
||||||
} else if (name.equals("timeStampFormatString")) {
|
} else if (name.equals("timeStampFormatString")) {
|
||||||
setTimeStampFormatString(jsonReader.nextString());
|
setTimeStampFormatString(jsonReader.nextString());
|
||||||
|
} else if (name.equals("timeStampCopyFormatString")) {
|
||||||
|
setTimeStampCopyFormatString(jsonReader.nextString());
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
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.AppConfigsUtil;
|
||||||
import cc.winboll.studio.timestamp.utils.ClipboardUtil;
|
import cc.winboll.studio.timestamp.utils.ClipboardUtil;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -39,6 +40,7 @@ public class ButtonClickReceiver extends BroadcastReceiver {
|
|||||||
|
|
||||||
// 比如显示一个Toast
|
// 比如显示一个Toast
|
||||||
Toast.makeText(context, formattedDateTime + " 已复制", Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, formattedDateTime + " 已复制", Toast.LENGTH_SHORT).show();
|
||||||
|
MainService.updateCopiedTimeStamp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ public class NotificationHelper {
|
|||||||
PendingIntent pendingIntent = createPendingIntent(intent);
|
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)
|
.setSmallIcon(R.drawable.ic_launcher)
|
||||||
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher))
|
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher))
|
||||||
//.setContentTitle(title)
|
//.setContentTitle(title)
|
||||||
|
|||||||
@@ -5,16 +5,12 @@ package cc.winboll.studio.timestamp.utils;
|
|||||||
* @Date 2025/05/05 21:10
|
* @Date 2025/05/05 21:10
|
||||||
* @Describe TimeStampRemoteViewsUtil
|
* @Describe TimeStampRemoteViewsUtil
|
||||||
*/
|
*/
|
||||||
import android.app.Notification;
|
|
||||||
import android.app.NotificationChannel;
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
import android.widget.TextView;
|
|
||||||
import androidx.core.app.NotificationCompat;
|
|
||||||
import cc.winboll.studio.timestamp.MainActivity;
|
import cc.winboll.studio.timestamp.MainActivity;
|
||||||
import cc.winboll.studio.timestamp.R;
|
import cc.winboll.studio.timestamp.R;
|
||||||
import cc.winboll.studio.timestamp.receivers.ButtonClickReceiver;
|
import cc.winboll.studio.timestamp.receivers.ButtonClickReceiver;
|
||||||
@@ -27,13 +23,16 @@ public class TimeStampRemoteViewsUtil {
|
|||||||
|
|
||||||
static volatile TimeStampRemoteViewsUtil _TimeStampRemoteViewsUtil;
|
static volatile TimeStampRemoteViewsUtil _TimeStampRemoteViewsUtil;
|
||||||
Context mContext;
|
Context mContext;
|
||||||
|
NotificationHelper mNotificationHelper;
|
||||||
RemoteViews mRemoteViews;
|
RemoteViews mRemoteViews;
|
||||||
TextView mtvMessage;
|
Intent mIntentMain;
|
||||||
Notification mNotification;
|
|
||||||
|
|
||||||
|
|
||||||
TimeStampRemoteViewsUtil(Context context) {
|
TimeStampRemoteViewsUtil(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
createNotificationChannel();
|
mNotificationHelper = new NotificationHelper(context);
|
||||||
|
//createNotificationChannel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized TimeStampRemoteViewsUtil getInstance(Context context) {
|
public static synchronized TimeStampRemoteViewsUtil getInstance(Context context) {
|
||||||
@@ -43,23 +42,66 @@ public class TimeStampRemoteViewsUtil {
|
|||||||
return _TimeStampRemoteViewsUtil;
|
return _TimeStampRemoteViewsUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createNotificationChannel() {
|
// private void createNotificationChannel() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
CharSequence name = "自定义视图通知通道";
|
// CharSequence name = "自定义视图通知通道";
|
||||||
String description = "用于展示自定义视图的通知通道";
|
// String description = "用于展示自定义视图的通知通道";
|
||||||
int importance = NotificationManager.IMPORTANCE_HIGH;
|
// int importance = NotificationManager.IMPORTANCE_HIGH;
|
||||||
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
|
// NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
|
||||||
channel.setDescription(description);
|
// channel.setDescription(description);
|
||||||
NotificationManager notificationManager = mContext.getSystemService(NotificationManager.class);
|
// NotificationManager notificationManager = mContext.getSystemService(NotificationManager.class);
|
||||||
notificationManager.createNotificationChannel(channel);
|
// 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) {
|
public void showNotification(String msg) {
|
||||||
if (mRemoteViews == null) {
|
if (mRemoteViews == null) {
|
||||||
// 创建 RemoteViews 对象,加载布局
|
// 创建 RemoteViews 对象,加载布局
|
||||||
mRemoteViews = new RemoteViews(mContext.getPackageName(), R.layout.custom_notification_layout);
|
mRemoteViews = new RemoteViews(mContext.getPackageName(), R.layout.custom_notification_layout);
|
||||||
|
|
||||||
}
|
}
|
||||||
// 自定义 TextView 的文本
|
// 自定义 TextView 的文本
|
||||||
mRemoteViews.setTextViewText(R.id.tv_timestamp, msg);
|
mRemoteViews.setTextViewText(R.id.tv_timestamp, msg);
|
||||||
@@ -68,8 +110,8 @@ public class TimeStampRemoteViewsUtil {
|
|||||||
// 这里虽然不能直接设置字体大小,但可以通过反射等方式尝试(不推荐,且有兼容性问题)
|
// 这里虽然不能直接设置字体大小,但可以通过反射等方式尝试(不推荐,且有兼容性问题)
|
||||||
|
|
||||||
// 创建点击通知后的意图
|
// 创建点击通知后的意图
|
||||||
Intent intent = new Intent(mContext, MainActivity.class);
|
mIntentMain = new Intent(mContext, MainActivity.class);
|
||||||
PendingIntent pendingMainIntent = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent pendingMainIntent = PendingIntent.getActivity(mContext, 0, mIntentMain, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
// 设置通知的点击事件
|
// 设置通知的点击事件
|
||||||
mRemoteViews.setOnClickPendingIntent(R.id.tv_timestamp, pendingMainIntent);
|
mRemoteViews.setOnClickPendingIntent(R.id.tv_timestamp, pendingMainIntent);
|
||||||
|
|
||||||
@@ -85,17 +127,6 @@ public class TimeStampRemoteViewsUtil {
|
|||||||
// 为按钮设置点击事件
|
// 为按钮设置点击事件
|
||||||
mRemoteViews.setOnClickPendingIntent(R.id.btn_copytimestamp, pendingIntent);
|
mRemoteViews.setOnClickPendingIntent(R.id.btn_copytimestamp, pendingIntent);
|
||||||
|
|
||||||
// 构建通知
|
mNotificationHelper.showCustomForegroundNotification(mIntentMain, mRemoteViews, mRemoteViews);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">TimeStamp</string>
|
<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="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>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user