添加常驻通知栏

This commit is contained in:
ZhanGSKen 2025-05-05 10:45:25 +08:00
parent 125c2b4431
commit f0a29dc7a9
12 changed files with 804 additions and 9 deletions

View File

@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Sun May 04 14:02:22 GMT 2025
#Mon May 05 02:43:50 GMT 2025
stageCount=0
libraryProject=
baseVersion=15.0
publishVersion=15.0.0
buildCount=2
buildCount=8
baseBetaVersion=15.0.1

View File

@ -3,6 +3,9 @@
xmlns:android="http://schemas.android.com/apk/res/android"
package="cc.winboll.studio.timestamp">
<!-- 运行前台服务 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
@ -32,6 +35,10 @@
<activity android:name=".GlobalApplication$CrashActivity"/>
<service android:name=".MainService"/>
<service android:name=".AssistantService"/>
</application>
</manifest>

View File

@ -0,0 +1,112 @@
package cc.winboll.studio.timestamp;
/**
* @Author ZhanGSKen
* @Date 2025/05/05 09:49
* @Describe MainService 守护进程服务
*/
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import cc.winboll.studio.timestamp.AssistantService;
import cc.winboll.studio.timestamp.MainService;
import cc.winboll.studio.timestamp.models.AppConfigs;
import cc.winboll.studio.timestamp.utils.ServiceUtil;
public class AssistantService extends Service {
public static final String TAG = "AssistantService";
//MyBinder mMyBinder;
MyServiceConnection mMyServiceConnection;
volatile boolean mIsThreadAlive;
@Override
public IBinder onBind(Intent intent) {
//return mMyBinder;
return null;
}
@Override
public void onCreate() {
//LogUtils.d(TAG, "call onCreate()");
super.onCreate();
//mMyBinder = new MyBinder();
if (mMyServiceConnection == null) {
mMyServiceConnection = new MyServiceConnection();
}
// 设置运行参数
mIsThreadAlive = false;
run();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//LogUtils.d(TAG, "call onStartCommand(...)");
run();
AppConfigs appConfigs = AppConfigs.getInstance(AssistantService.this).loadAppConfigs();
return appConfigs.isEnableService() ? Service.START_STICKY: super.onStartCommand(intent, flags, startId);
}
/*class MyBinder extends IMyAidlInterface.Stub {
@Override
public String getServiceName() {
return AssistantService.class.getSimpleName();
}
}*/
@Override
public void onDestroy() {
//LogUtils.d(TAG, "call onDestroy()");
mIsThreadAlive = false;
super.onDestroy();
}
// 运行服务内容
//
void run() {
//LogUtils.d(TAG, "call run()");
AppConfigs appConfigs = AppConfigs.getInstance(AssistantService.this).loadAppConfigs();
if (appConfigs.isEnableService()) {
if (mIsThreadAlive == false) {
// 设置运行状态
mIsThreadAlive = true;
// 唤醒和绑定主进程
wakeupAndBindMain();
}
}
}
// 唤醒和绑定主进程
//
void wakeupAndBindMain() {
if (ServiceUtil.isServiceAlive(getApplicationContext(), MainService.class.getName()) == false) {
//LogUtils.d(TAG, "wakeupAndBindMain() Wakeup... ControlCenterService");
startForegroundService(new Intent(AssistantService.this, MainService.class));
}
//LogUtils.d(TAG, "wakeupAndBindMain() Bind... ControlCenterService");
bindService(new Intent(AssistantService.this, MainService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
}
// 主进程与守护进程连接时需要用到此类
//
class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//LogUtils.d(TAG, "call onServiceConnected(...)");
}
@Override
public void onServiceDisconnected(ComponentName name) {
//LogUtils.d(TAG, "call onServiceDisconnected(...)");
AppConfigs appConfigs = AppConfigs.getInstance(AssistantService.this).loadAppConfigs();
if (appConfigs.isEnableService()) {
wakeupAndBindMain();
}
}
}
}

View File

@ -1,14 +1,17 @@
package cc.winboll.studio.timestamp;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import cc.winboll.studio.libappbase.LogView;
import com.hjq.toast.ToastUtils;
import android.widget.Switch;
public class MainActivity extends AppCompatActivity {
LogView mLogView;
Switch mswEnableMainService;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -18,8 +21,10 @@ public class MainActivity extends AppCompatActivity {
Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mswEnableMainService = findViewById(R.id.activitymainSwitch1);
mLogView = findViewById(R.id.logview);
ToastUtils.show("onCreate");
}
@ -28,4 +33,8 @@ public class MainActivity extends AppCompatActivity {
super.onResume();
mLogView.start();
}
public void onSetMainServiceStatus(View view) {
MainService.setMainServiceStatus(this, mswEnableMainService.isChecked());
}
}

View File

@ -0,0 +1,157 @@
package cc.winboll.studio.timestamp;
/**
* @Author ZhanGSKen
* @Date 2025/05/05 09:47
* @Describe 主要服务
*/
import android.app.Notification;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.timestamp.AssistantService;
import cc.winboll.studio.timestamp.MainService;
import cc.winboll.studio.timestamp.models.AppConfigs;
import cc.winboll.studio.timestamp.utils.NotificationHelper;
import cc.winboll.studio.timestamp.utils.ServiceUtil;
public class MainService extends Service {
public static String TAG = "MainService";
Notification notification;
private static boolean _mIsServiceAlive;
public static final String EXTRA_APKFILEPATH = "EXTRA_APKFILEPATH";
final static int MSG_INSTALL_APK = 0;
//Handler mHandler;
MyServiceConnection mMyServiceConnection;
MainActivity mInstallCompletedFollowUpActivity;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
LogUtils.d(TAG, "onCreate()");
_mIsServiceAlive = false;
//mHandler = new MyHandler(MainService.this);
if (mMyServiceConnection == null) {
mMyServiceConnection = new MyServiceConnection();
}
run();
}
private void run() {
AppConfigs appConfigs = AppConfigs.getInstance(MainService.this).loadAppConfigs();
if (appConfigs.isEnableService()) {
if (_mIsServiceAlive == false) {
// 设置运行状态
_mIsServiceAlive = true;
// 显示前台通知栏
NotificationHelper helper = new NotificationHelper(this);
Intent intent = new Intent(this, MainActivity.class);
notification = helper.showForegroundNotification(intent, getString(R.string.app_name), getString(R.string.text_aboutservernotification));
startForeground(NotificationHelper.FOREGROUND_NOTIFICATION_ID, notification);
// 唤醒守护进程
wakeupAndBindAssistant();
LogUtils.d(TAG, "running...");
} else {
LogUtils.d(TAG, "_mIsServiceAlive is " + Boolean.toString(_mIsServiceAlive));
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
_mIsServiceAlive = false;
LogUtils.d(TAG, "onDestroy()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
LogUtils.d(TAG, "onStartCommand");
run();
AppConfigs appConfigs = AppConfigs.getInstance(MainService.this).loadAppConfigs();
return appConfigs.isEnableService() ? Service.START_STICKY: super.onStartCommand(intent, flags, startId);
}
public static void setMainServiceStatus(Context context, boolean isEnable) {
AppConfigs appConfigs = AppConfigs.getInstance(context).loadAppConfigs();
appConfigs.setIsEnableService(isEnable);
Intent intent = new Intent(context, MainService.class);
if (isEnable) {
context.startService(intent);
} else {
context.stopService(intent);
}
}
// 主进程与守护进程连接时需要用到此类
//
private class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//LogUtils.d(TAG, "call onServiceConnected(...)");
}
@Override
public void onServiceDisconnected(ComponentName name) {
//LogUtils.d(TAG, "call onServiceConnected(...)");
AppConfigs appConfigs = AppConfigs.getInstance(MainService.this).loadAppConfigs();
if (appConfigs.isEnableService()) {
// 唤醒守护进程
wakeupAndBindAssistant();
}
}
}
// 唤醒和绑定守护进程
//
void wakeupAndBindAssistant() {
if (ServiceUtil.isServiceAlive(getApplicationContext(), AssistantService.class.getName()) == false) {
startService(new Intent(MainService.this, AssistantService.class));
//LogUtils.d(TAG, "call wakeupAndBindAssistant() : Binding... AssistantService");
bindService(new Intent(MainService.this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT);
}
}
//
// 服务事务处理类
//
// static class MyHandler extends Handler {
// WeakReference<MainService> weakReference;
// MyHandler(MainService service) {
// weakReference = new WeakReference<MainService>(service);
// }
// public void handleMessage(Message message) {
// MainService theActivity = weakReference.get();
// switch (message.what) {
// case MSG_INSTALL_APK:
// {
// break;
// }
// default:
// break;
// }
// super.handleMessage(message);
// }
// }
}

View File

@ -0,0 +1,128 @@
package cc.winboll.studio.timestamp.models;
/**
* @Author ZhanGSKen
* @Date 2025/05/05 09:51
* @Describe 应用配置数据模型
*/
import android.content.Context;
import android.util.JsonReader;
import android.util.JsonWriter;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.timestamp.models.AppConfigs;
import cc.winboll.studio.timestamp.utils.FileUtil;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
public class AppConfigs implements Serializable {
public static final String TAG = "AppConfigs";
volatile static AppConfigs _AppConfigs;
Context mContext;
// 是否启动服务
boolean isEnableService;
AppConfigs(Context context) {
this.mContext = context;
this.isEnableService = false;
}
public synchronized static AppConfigs getInstance(Context context) {
if (_AppConfigs == null) {
_AppConfigs = new AppConfigs(context);
_AppConfigs.loadAppConfigs();
}
return _AppConfigs;
}
public void setIsEnableService(boolean isEnableService) {
this.isEnableService = isEnableService;
}
public boolean isEnableService() {
return isEnableService;
}
@Override
public String toString() {
// 创建 JsonWriter 对象
StringWriter stringWriter = new StringWriter();
JsonWriter writer = new
JsonWriter(stringWriter);
try {
// 开始 JSON 对象
writer.beginObject();
// 写入键值对
writer.name("isEnableService").value(this.isEnableService);
// 结束 JSON 对象
writer.endObject();
return stringWriter.toString();
} catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
// 获取 JSON 字符串
return "";
}
public AppConfigs parseAppConfigs(String szAppConfigs) {
// 创建 JsonWriter 对象
StringReader stringReader = new StringReader(szAppConfigs);
JsonReader jsonReader = new
JsonReader(stringReader);
try {
// 开始 JSON 对象
jsonReader.beginObject();
// 写入键值对
while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
if (name.equals("isEnableService")) {
setIsEnableService(jsonReader.nextBoolean());
} else {
jsonReader.skipValue();
}
}
// 结束 JSON 对象
jsonReader.endObject();
return this;
} catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
// 获取 JSON 字符串
return null;
}
static String getDataPath(Context context) {
return context.getExternalFilesDir(TAG) + "/" + TAG + ".json";
}
public AppConfigs loadAppConfigs() {
AppConfigs appConfigs = null;
try {
String szJson = FileUtil.readFile(getDataPath(mContext));
appConfigs = parseAppConfigs(szJson);
if (appConfigs != null) {
_AppConfigs = appConfigs;
}
} catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
return _AppConfigs;
}
public void saveAppConfigs(AppConfigs appConfigs) {
try {
String szJson = appConfigs.toString();
FileUtil.writeFile(getDataPath(mContext), szJson);
} catch (IOException e) {
LogUtils.d(TAG, e.getMessage(), Thread.currentThread().getStackTrace());
}
}
}

View File

@ -0,0 +1,47 @@
package cc.winboll.studio.timestamp.utils;
/**
* @Author ZhanGSKen
* @Date 2025/05/05 09:52
* @Describe 文件管理工具类
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
public class FileUtil {
public static final String TAG = "FileUtil";
//
// 把字符串写入文件指定 UTF-8 编码
//
public static void writeFile(String filePath, String content) throws IOException {
File file = new File(filePath);
FileOutputStream outputStream = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
writer.write(content);
writer.close();
}
//
// 读取文件到字符串指定 UTF-8 编码
//
public static String readFile(String filePath) throws IOException {
File file = new File(filePath);
FileInputStream inputStream = new FileInputStream(file);
InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
StringBuilder content = new StringBuilder();
int character;
while ((character = reader.read()) != -1) {
content.append((char) character);
}
reader.close();
return content.toString();
}
}

View File

@ -0,0 +1,201 @@
package cc.winboll.studio.timestamp.utils;
/**
* @Author ZhanGSKen
* @Date 2025/05/05 10:36
* @Describe 应用通知工具类
*/
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.widget.RemoteViews;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.timestamp.R;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class NotificationHelper {
public static final String TAG = "NotificationHelper";
// 渠道ID和名称
private static final String CHANNEL_ID_FOREGROUND = "foreground_channel";
private static final String CHANNEL_NAME_FOREGROUND = "Foreground Service";
private static final String CHANNEL_ID_TEMPORARY = "temporary_channel";
private static final String CHANNEL_NAME_TEMPORARY = "Temporary Notifications";
// 通知ID
public static final int FOREGROUND_NOTIFICATION_ID = 1001;
public static final int TEMPORARY_NOTIFICATION_ID = 2001;
private final Context mContext;
private final NotificationManager mNotificationManager;
// 示例维护当前使用的渠道ID列表
// 渠道ID渠道重要性级别
Map<String, Integer> activeChannelConfigs = new HashMap<>();
public NotificationHelper(Context context) {
mContext = context;
mNotificationManager = context.getSystemService(NotificationManager.class);
// 初始化配置
activeChannelConfigs.put(
CHANNEL_ID_FOREGROUND,
NotificationManager.IMPORTANCE_HIGH
);
activeChannelConfigs.put(
CHANNEL_ID_TEMPORARY,
NotificationManager.IMPORTANCE_DEFAULT
);
createNotificationChannels();
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void createNotificationChannels() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createForegroundChannel();
createTemporaryChannel();
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void createForegroundChannel() {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID_FOREGROUND,
CHANNEL_NAME_FOREGROUND,
NotificationManager.IMPORTANCE_LOW
);
channel.setDescription("Persistent service notifications");
channel.setSound(null, null);
channel.enableVibration(false);
mNotificationManager.createNotificationChannel(channel);
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void createTemporaryChannel() {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID_TEMPORARY,
CHANNEL_NAME_TEMPORARY,
NotificationManager.IMPORTANCE_HIGH
);
channel.setDescription("Temporary alert notifications");
channel.setSound(null, null);
channel.enableVibration(true);
channel.setVibrationPattern(new long[]{100, 200, 300, 400});
channel.setBypassDnd(true);
mNotificationManager.createNotificationChannel(channel);
}
// 显示常驻通知通常用于前台服务
public Notification showForegroundNotification(Intent intent, String title, String content) {
PendingIntent pendingIntent = createPendingIntent(intent);
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)
.setContentTitle(content)
//.setContentText(content)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setOngoing(true)
.build();
mNotificationManager.notify(FOREGROUND_NOTIFICATION_ID, notification);
return notification;
}
// 显示临时通知自动消失
public void showTemporaryNotification(Intent intent, String title, String content) {
showTemporaryNotification(intent, TEMPORARY_NOTIFICATION_ID, title, content);
}
// 显示临时通知自动消失
public void showTemporaryNotification(Intent intent, int notificationID, String title, String content) {
PendingIntent pendingIntent = createPendingIntent(intent);
Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID_TEMPORARY)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher))
.setContentTitle(title)
.setContentText(content)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.setVibrate(new long[]{100, 200, 300, 400})
.build();
mNotificationManager.notify(notificationID, notification);
}
// 创建自定义布局通知可扩展
public void showCustomNotification(Intent intent, RemoteViews contentView, RemoteViews bigContentView) {
PendingIntent pendingIntent = createPendingIntent(intent);
Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID_TEMPORARY)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pendingIntent)
.setContent(contentView)
.setCustomBigContentView(bigContentView)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build();
mNotificationManager.notify(TEMPORARY_NOTIFICATION_ID + 1, notification);
}
// 取消所有通知
public void cancelAllNotifications() {
mNotificationManager.cancelAll();
}
// 取消指定通知
public void cancelNotification(int notificationID) {
mNotificationManager.cancel(notificationID);
}
// 创建PendingIntent兼容不同API版本
private PendingIntent createPendingIntent(Intent intent) {
int flags = PendingIntent.FLAG_UPDATE_CURRENT;
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// flags |= PendingIntent.FLAG_IMMUTABLE;
// }
return PendingIntent.getActivity(
mContext,
0,
intent,
flags
);
}
// public void sendSMSReceivedMessage(int notificationID, String szPhone, String szBody) {
// Intent intent = new Intent(mContext, SMSActivity.class);
// intent.putExtra(SMSActivity.EXTRA_PHONE, szPhone);
// String szTitle = mContext.getString(R.string.text_smsfrom) + "<" + szPhone + ">";
// String szContent = "[ " + szBody + " ]";
// showTemporaryNotification(intent, notificationID, szTitle, szContent);
// }
public void cleanOldChannels() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
List<NotificationChannel> allChannels = mNotificationManager.getNotificationChannels();
for (NotificationChannel channel : allChannels) {
LogUtils.d(TAG, "Clean channel : " + channel.getId());
if (!activeChannelConfigs.containsKey(channel.getId())) {
// 安全删除渠道
mNotificationManager.deleteNotificationChannel(channel.getId());
LogUtils.d(TAG, String.format("Deleted Channel %s", channel.getId()));
}
}
}
}
}

View File

@ -0,0 +1,90 @@
package cc.winboll.studio.timestamp.utils;
/**
* @Author ZhanGSKen
* @Date 2025/05/05 09:45
* @Describe 通知栏工具
*/
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.media.RingtoneManager;
import android.os.Build;
import android.util.Log;
import android.widget.RemoteViews;
import cc.winboll.studio.timestamp.MainService;
import cc.winboll.studio.timestamp.MainActivity;
import cc.winboll.studio.timestamp.R;
public class NotificationUtil {
public static final String TAG = "NotificationUtil";
static final String szServiceChannelID = "0";
static int mNumSendForegroundNotification = 10000;
public NotificationManager createServiceNotificationChannel(Context context) {
//创建通知渠道ID
String channelId = szServiceChannelID;
//创建通知渠道名称
String channelName = "Service Message";
//创建通知渠道重要性
int importance = NotificationManager.IMPORTANCE_MIN;
NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
channel.setSound(null, null);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(
Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
return notificationManager;
}
// 创建通知
//
public void sendForegroundNotification(MainService service) {
//创建Notification传入Context和channelId
Intent intent = new Intent();//这个intent会传给目标,可以使用getIntent来获取
intent.setClass(service, MainActivity.class);
//这里放一个count用来区分每一个通知
//intent.putExtra("intent", "intent--->" + count);//这里设置一个数据,带过去
//参数1:context 上下文对象
//参数2:发送者私有的请求码(Private request code for the sender)
//参数3:intent 意图对象
//参数4:必须为FLAG_ONE_SHOT,FLAG_NO_CREATE,FLAG_CANCEL_CURRENT,FLAG_UPDATE_CURRENT,中的一个
PendingIntent mForegroundPendingIntent = PendingIntent.getActivity(service, mNumSendForegroundNotification, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT);
Notification mForegroundNotification = new Notification.Builder(service, szServiceChannelID)
.setAutoCancel(true)
.setContentTitle(service.getString(R.string.app_name))
.setContentText(service.TAG + " is started.")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher)
//设置红色
.setColor(Color.parseColor("#F00606"))
.setLargeIcon(BitmapFactory.decodeResource(service.getResources(), R.drawable.ic_launcher))
.setContentIntent(mForegroundPendingIntent)
.build();
/*RemoteViews mrvForegroundNotificationView = new RemoteViews(service.getPackageName(), R.layout.remoteview);
mrvForegroundNotificationView.setTextViewText(R.id.remoteviewTextView1, notificationMessage.getTitle());
mrvForegroundNotificationView.setTextViewText(R.id.remoteviewTextView2, notificationMessage.getContent());
mrvForegroundNotificationView.setImageViewResource(R.id.remoteviewImageView1, R.drawable.ic_launcher);
mForegroundNotification.contentView = mrvForegroundNotificationView;
mForegroundNotification.bigContentView = mrvForegroundNotificationView;
*/
service.startForeground(mNumSendForegroundNotification, mForegroundNotification);
}
}

View File

@ -0,0 +1,35 @@
package cc.winboll.studio.timestamp.utils;
/**
* @Author ZhanGSKen
* @Date 2025/05/05 09:58
* @Describe 应用服务管理类
*/
import android.app.ActivityManager;
import android.content.Context;
import java.util.List;
public class ServiceUtil {
public final static String TAG = "ServiceUtil";
public static boolean isServiceAlive(Context context, String szServiceName) {
// 获取Activity管理者对象
ActivityManager manager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
// 获取正在运行的服务此处设置最多取1000个
List<ActivityManager.RunningServiceInfo> runningServices = manager
.getRunningServices(1000);
if (runningServices.size() <= 0) {
return false;
}
// 遍历若存在名字和传入的serviceName的一致则说明存在
for (ActivityManager.RunningServiceInfo runningServiceInfo : runningServices) {
if (runningServiceInfo.service.getClassName().equals(szServiceName)) {
return true;
}
}
return false;
}
}

View File

@ -19,6 +19,20 @@
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Switch
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="启用通知栏计时器"
android:id="@+id/activitymainSwitch1"
android:onClick="onSetMainServiceStatus"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
@ -26,12 +40,6 @@
android:layout_weight="1.0"
android:gravity="center_vertical|center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AndroidX Demo"
android:textAppearance="?android:attr/textAppearanceLarge"/>
</LinearLayout>
<LinearLayout

View File

@ -1,4 +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>
</resources>