Android Kotlin服务问题

Android Kotlin服务问题,android,kotlin,Android,Kotlin,我已经实现了一个在应用程序后台运行的服务。该服务每分钟调用一次该函数,该函数检查触发通知提醒的时间是否已到(检索当前日期和时间,并将其与数据库中保存的数据进行比较。如果日期和时间匹配,则会触发通知。该函数每1分钟调用一次。该函数必须每1分钟检查一次用户使用应用程序、应用程序在后台运行、不使用应用程序时的条件。)n和手机的睡眠方式。通过在前一天晚上到晚上和第二天实施提醒。提醒在当天晚上出现,第二天第一次提醒出现。第二次提醒不会出现。另一方面,提醒设置为5分钟有效,30分钟不再有效。正在查找我在t上

我已经实现了一个在应用程序后台运行的服务。该服务每分钟调用一次该函数,该函数检查触发通知提醒的时间是否已到(检索当前日期和时间,并将其与数据库中保存的数据进行比较。如果日期和时间匹配,则会触发通知。该函数每1分钟调用一次。该函数必须每1分钟检查一次用户使用应用程序、应用程序在后台运行、不使用应用程序时的条件。)n和手机的睡眠方式。通过在前一天晚上到晚上和第二天实施提醒。提醒在当天晚上出现,第二天第一次提醒出现。第二次提醒不会出现。另一方面,提醒设置为5分钟有效,30分钟不再有效。正在查找我在t上找到的信息他指出,问题在于:

  • 时间漂移-当屏幕打开且手机处于完全唤醒状态时,两个连续事件之间的间隔在大部分时间内保持不变,但可能会不时跳变(延长)
  • 手机进入睡眠模式
你们有谁知道怎么解决这个问题吗

前台服务

classforegroundservice:Service(){
伴星{
val CHANNEL\u ID=“ForegroundServiceChannel”
val CHANNEL\u ID\u CHILD=“ForegroundServiceChannelCHILD”
private var isRunning=true
}
override-fun-onstart命令(intent:intent,flags:Int,startId:Int):Int{
val input=intent.getIntExtra(“时间”,15)
createNotificationChannel()
val notificationIntent=Intent(此菜单::class.java)
val pendingent=pendingent.getActivity(
这
0,notificationIntent,0
)
val wakeLock:PowerManager.wakeLock=
(作为PowerManager的getSystemService(Context.POWER\u服务)。运行{
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,“MyApp::AR_Apteczka”)。应用{
获得
}
}
val notification=NotificationCompat.Builder(此,通道ID)
.setContentTitle(“Twoja Elektroniczna Apteczka”)
.setContentText(“Dbamy o Twoje zdrowie”)
.setSmallIcon(com.example.agnieszka.ar_apteczka.R.drawable.pills)
.setonlylertonce(真)
//.setContentIntent(挂起内容)
//.setSound(空)
.build()
startForeground(1,通知)
isRunning=true
val context=this
val intent=intent(这个,ShowAllTodaysMedicines::class.java)
val pendingIntentNotification=PendingIntent.getActivity(上下文,0,意图,PendingIntent.FLAG_UPDATE_CURRENT)
doAsync{
while(true)
{
var message=createmembermessage(上下文)
超线程{
如果(真){
如果(信息!=“Nadszedłczas by zażyć:”){
val通知=
NotificationCompat.Builder(上下文、通道ID子级)
.setContentTitle(“Zażyj leki”)
.setContentText(消息)
.setSmallIcon(com.example.agnieszka.ar_apteczka.R.drawable.pills)
.setContentIntent(挂起通知)
.setAutoCancel(真)
.build()
使用(NotificationManagerCompat.from(上下文)){
notificationManager.notify(2,通知)
}
}
}
}
//系统时钟。睡眠(60000)
SystemClock.sleep(60*1000 SystemClock.elapsedRealtime()%1000)
//SystemClock.sleep(50000)//10*1000 SystemClock.elapsedRealtime()%1000
}
}
返回开始\u不粘
}
覆盖有趣的onBind(意图:意图):IBinder{
返回空
}
重写onDestroy(){
super.ondestory()
isRunning=false
}
私人娱乐createNotificationChannel(){
if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.O){
val serviceChannel=通知通道(
频道ID,
“前台服务频道”,
//NotificationManager.IMPORTANCE\u默认值
NotificationManager.IMPORTANCE\u默认值
)
//serviceChannel.setSound(空,空)//
val serviceChannel2=通知通道(
频道(ID)(CHILD),
“前台服务ChannelChild”,
NotificationManager.IMPORTANCE\u默认值
//通知经理。重要性低
)
val manager=getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(serviceChannel)
manager.createNotificationChannel(serviceChannel2)
}
}
有趣的提醒器ornow(context:context):ArrayList{
var-listOfReminder:ArrayList=ArrayList()
var timetoday=takeTimeNow()
var dateToday=takeTodayDate()
val dbHelper=SQLConector(上下文)
val allemendorslist=dbHelper.getAllemendors()
对于(i:所有提醒列表中的提醒){
如果(i.employerDate==dateToday&&i.employerTime==timetoday){
var提醒=提醒(
i、 伊德里米德,
i、 医学名称,
i、 提醒者,
i、 提醒时间
)
listOfReminder.add(提醒)
}
}
返回列表记录器
}
普里夫
class ForegroundService : Service() {
    companion object {
        val CHANNEL_ID = "ForegroundServiceChannel"
        val CHANNEL_ID_CHILD = "ForegroundServiceChannelCHILD"
        private var isRunning = true
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        val input = intent.getIntExtra("time",15)
        createNotificationChannel()
        val notificationIntent = Intent(this, Menu::class.java)
        val pendingIntent = PendingIntent.getActivity(
            this,
            0, notificationIntent, 0
        )

        val wakeLock: PowerManager.WakeLock =
            (getSystemService(Context.POWER_SERVICE) as PowerManager).run {
                newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::AR_Apteczka").apply {
                    acquire()
                }
            }



        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Twoja Elektroniczna Apteczka")
            .setContentText("Dbamy o Twoje zdrowie")
            .setSmallIcon(com.example.agnieszka.ar_apteczka.R.drawable.pills)
            .setOnlyAlertOnce(true)
            //.setContentIntent(pendingIntent)
            //.setSound(null)
            .build()



        startForeground(1, notification)
        isRunning = true
        val context = this
        val intent = Intent(this, ShowAllTodaysMedicines::class.java)
        val pendingIntentNotification = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        doAsync {
            while(true)
            {
                var message= createReminderMessage(context)

                uiThread {
                        if(true) {
                            if (message != "Nadszedł czas by zażyć: ") {
                                val notification =
                                    NotificationCompat.Builder(context, CHANNEL_ID_CHILD)
                                        .setContentTitle("Zażyj leki")
                                        .setContentText(message)
                                        .setSmallIcon(com.example.agnieszka.ar_apteczka.R.drawable.pills)
                                        .setContentIntent(pendingIntentNotification)
                                        .setAutoCancel(true)
                                        .build()
                                with(NotificationManagerCompat.from(context)) {
                                    notificationManager.notify(2, notification)
                                }
                            }
                        }
                }

                //SystemClock.sleep(60000)
                SystemClock.sleep(60*1000-SystemClock.elapsedRealtime()%1000)
               // SystemClock.sleep(50000) //10*1000-SystemClock.elapsedRealtime()%1000
            }
        }
        return START_NOT_STICKY
    }

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    override fun onDestroy() {
        super.onDestroy()
        isRunning = false
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val serviceChannel = NotificationChannel(
                CHANNEL_ID,
                "Foreground Service Channel",
                //NotificationManager.IMPORTANCE_DEFAULT
                NotificationManager.IMPORTANCE_DEFAULT
            )
            //serviceChannel.setSound(null, null) //
            val serviceChannel2 = NotificationChannel(
                CHANNEL_ID_CHILD,
                "Foreground Service ChannelChild ",
                NotificationManager.IMPORTANCE_DEFAULT
                //NotificationManager.IMPORTANCE_LOW
            )
            val manager = getSystemService(NotificationManager::class.java)
            manager.createNotificationChannel(serviceChannel)
            manager.createNotificationChannel(serviceChannel2)
        }
    }

    fun reminderForNow(context: Context) : ArrayList<Reminder> {
        var listOfReminder : ArrayList<Reminder> = ArrayList()
        var timetoday = takeTimeNow()
        var dateToday = takeTodayDate()

        val dbHelper = SQLConector(context)
        val allRemindersList = dbHelper.getAllReminders()
        for (i: Reminder in allRemindersList) {

            if (i.reminderDate == dateToday && i.ReminderTime == timetoday) {
                var reminder = Reminder(
                    i.idReminder,
                    i.medicineName,
                    i.reminderDate,
                    i.ReminderTime
                )
                listOfReminder.add(reminder)
            }
        }
        return listOfReminder
    }

    private fun createReminderMessage(p0: Context) : String{
        var message = "Nadszedł czas by zażyć: "
        var listOfReminders = reminderForNow(p0)
        if(listOfReminders.count() > 0){
            for (i: Reminder in listOfReminders) {
                message += i.medicineName + ", "
            }
        }
        return message
    }

 private fun takeTodayDate():String{
        val current = LocalDateTime.now()
        val formatDate = DateTimeFormatter.ofPattern("yyyy-MM-dd")
     var currentDate = current.format(formatDate).toString()
        return  currentDate
    }

    private fun takeTimeNow() : String{
        val current = LocalDateTime.now()
        val formatTime = DateTimeFormatter.ofPattern("HH:mm")
        return current.format(formatTime).toString()
    }
}


**Main Activity**

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        binding.buttonStart.setOnClickListener { startService() }
        binding.buttonStop.setOnClickListener {stopService()  }
        startService()
    }


    private fun startService() {
        val serviceIntent = Intent(this, ForegroundService::class.java)
        serviceIntent.putExtra("time", 1)

        ContextCompat.startForegroundService(this, serviceIntent)
    }

    private fun stopService() {
        val serviceIntent = Intent(this, ForegroundService::class.java)
        stopService(serviceIntent)
    }

}

*Manifest*
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
            android:allowBackup="false"
            android:icon="@drawable/pills"
            android:label="@string/nameOfApplications"
            android:roundIcon="@drawable/icon"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        <service
                android:name=".ForegroundService"
                android:enabled="true"
                android:exported="true"/>
        <activity android:name=".MainActivity">

            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>