我在我的Android应用程序中使用AlarmManager安排前台服务的过程中遇到了一个问题。尽管我已经设置了代码来使用闹钟在特定时间触发前台服务,但是当应用程序不在后台运行时,闹钟无法启动前台服务(当应用程序在前台或后台运行时,它可以正常工作)。
我的应用程序有一个要求,即在一天的特定时间范围内执行前台服务。为了实现这一点,我使用AlarmManager来安排服务在所需的时间间隔内启动和停止。 除了AlarmManager之外,还有哪些其他方式可以安排前台服务? TimeBasedScheduler类:
设置活动类:
在应用程序处于前台或后台时,功能完全正常。
我的应用程序有一个要求,即在一天的特定时间范围内执行前台服务。为了实现这一点,我使用AlarmManager来安排服务在所需的时间间隔内启动和停止。 除了AlarmManager之外,还有哪些其他方式可以安排前台服务? TimeBasedScheduler类:
class TimeBasedScheduler : BroadcastReceiver() {
private val TAG = "TimeBasedScheduler"
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
Log.d(TAG, "Received action: $action")
if (action != null) {
when (action) {
"START_SERVICE" -> {
Log.d(TAG, "Initializing socket for START_SERVICE")
initializeSocket(context)
// Now execution is started and resumed
LocalPrefrenceUtils.insertDataInBoolean(context, AppConstants.BACKGROUND_WORK_ALLOWED_KEY_FOR_LOCAL_PREFERENCE, true)
LocalPrefrenceUtils.insertDataInBoolean(context, AppConstants.BACKGROUND_WORK_TEMPORARILY_PAUSED_KEY_FOR_LOCAL_PREFERENCE, false
)
}
"STOP_SERVICE" -> {
Log.d(TAG, "Stopping service for STOP_SERVICE")
LocalPrefrenceUtils.insertDataInBoolean(
context,
AppConstants.BACKGROUND_WORK_TEMPORARILY_PAUSED_KEY_FOR_LOCAL_PREFERENCE,
true
)
val stopIntent = Intent(context, SocketManagerService::class.java)
context.stopService(stopIntent)
}
}
}
}
private fun initializeSocket(context: Context?) {
Log.d(TAG, "Initializing socket")
val intent = Intent(context, SocketManagerService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Log.d(TAG, "Starting foreground service")
context?.startForegroundService(intent)
} else {
Log.d(TAG, "Starting service")
context?.startService(intent)
}
}
}
设置活动类:
private fun setupForegroundServiceAlarms() {
val TAG = "TaskBasedScheduler"
// Get the start and end times from preferences
val startTime = LocalPrefrenceUtils.getStartTime(this)
val endTime = LocalPrefrenceUtils.getEndTime(this)
Log.d(TAG, "Start Time: $startTime")
Log.d(TAG, "End Time: $endTime")
// Calculate start and end times based on step sizes and special cases for value 48
val startHour = 7 // Starting hour (7:00 am)
val stepSizeMinutes = 30 // Step size in minutes
val startHourForAlarms = startHour + (stepSizeMinutes * startTime) / 60
val endHourForAlarms = if (endTime == 48) startHour + (stepSizeMinutes * endTime) / 60 - 1 else startHour + (stepSizeMinutes * endTime) / 60
val startMinute = (stepSizeMinutes * startTime) % 60
val endMinute = if (endTime == 48) ((stepSizeMinutes * endTime) % 60) - 1 else ((stepSizeMinutes * endTime) % 60)
// Set the Calendar instances for start and end times
val startCalendar = Calendar.getInstance().apply {
timeInMillis = System.currentTimeMillis()
set(Calendar.HOUR_OF_DAY, startHourForAlarms)
set(Calendar.MINUTE, startMinute)
set(Calendar.SECOND, 0)
}
val endCalendar = Calendar.getInstance().apply {
timeInMillis = System.currentTimeMillis()
set(Calendar.HOUR_OF_DAY, endHourForAlarms)
set(Calendar.MINUTE, endMinute)
set(Calendar.SECOND, 0)
}
Log.d(TAG, "Start Calendar Time: ${startCalendar.time}")
Log.d(TAG, "End Calendar Time: ${endCalendar.time}")
// Cancel previously set alarms
alarmManager.cancel(startPendingIntent)
alarmManager.cancel(endPendingIntent)
Log.d(TAG, "Canceled previous alarms")
// Create intents for starting and stopping the service
val startIntent = Intent(this, TimeBasedScheduler::class.java).apply {
action = "START_SERVICE"
}
val endIntent = Intent(this, TimeBasedScheduler::class.java).apply {
action = "STOP_SERVICE"
}
// Create pending intents for start and end actions
startPendingIntent = PendingIntent.getBroadcast(this, 0, startIntent, PendingIntent.FLAG_IMMUTABLE)
endPendingIntent = PendingIntent.getBroadcast(this, 1, endIntent, PendingIntent.FLAG_IMMUTABLE)
Log.d(TAG, "Created pending intents")
// Set alarms using AlarmManager for daily repetition
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
startCalendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
startPendingIntent
)
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
endCalendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
endPendingIntent
)
Log.d(TAG, "Alarms set for start: ${startCalendar.time}, end: ${endCalendar.time}")
}
和相关的代码清单:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<receiver android:name=".schedulers.TimeBasedScheduler"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="START_SERVICE" />
<action android:name="STOP_SERVICE" />
</intent-filter>
</receiver>
在应用程序处于前台或后台时,功能完全正常。
我使用Logcat检查了日志,没有显示与闹钟或前台服务未启动相关的错误消息。
我正在寻求关于为什么闹钟没有按预期触发前台服务的指导。我将非常感谢任何见解、建议或潜在解决方案来解决这个问题。
谢谢您的帮助。