Я разрабатываю приложение для социальной сети. Я прочитал много тем о том, как реализовать систему присутствия в приложении Android, и из всех них я решил создать класс приложения (с расширением LifecycleObserver), чтобы сделать систему присутствия глобальной. Я нашел это решение лучшим, поскольку мне не нужно копировать и вставлять методы в каждое действие.
Проблема в том, что статус пользователя не всегда обновляется в базе данных Firebase. Например, вчера каждый раз, когда я выходил из приложения или выключал свой мобильный телефон, статус пользователя обновлялся на «нет на месте», а сегодня я выключал свой мобильный телефон, и он больше не go в статус «нет». Я ничего не менял из класса Application. Почему вчера сработало, а сегодня больше не работает? Как это исправить? Я потратил больше недели, пытаясь решить эту проблему.
Вот мой класс приложения:
package com.example.bemyhero
import android.annotation.SuppressLint
import android.app.Application
import android.util.Log
import androidx.lifecycle.*
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.*
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.HashMap
class SubApplication : Application(), LifecycleObserver {
private lateinit var userRef: DatabaseReference
private lateinit var mAuth: FirebaseAuth
private lateinit var currUserId: String
override fun onCreate() {
super.onCreate()
FirebaseDatabase.getInstance().setPersistenceEnabled(true)
mAuth = FirebaseAuth.getInstance()
currUserId = mAuth.currentUser?.uid.toString()
userRef = FirebaseDatabase.getInstance().reference.child("Users")
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
private fun onAppStart(){
Log.d("[*] Status","Online")
updateOnlineStatus("online")
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private fun onAppForegrounded() {
Log.d("[*] Status","Online")
updateOnlineStatus("online")
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
private fun onAppBackgrounded() {
Log.d("[*] Status","Away")
updateOnlineStatus("away")
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
private fun onAppCrash() {
Log.d("[*] Status","Offline")
updateOnlineStatus("offline")
}
private fun updateOnlineStatus(status: String){
val currDate: String = getDate()
val currTime: String = getTime()
val currStateMap = HashMap<String, String>()
currStateMap["date"] = currDate
currStateMap["time"] = currTime
currStateMap["type"] = status
if(currUserId != "null"){
userRef.child(currUserId).child("OnlineStatus")
.updateChildren(currStateMap as Map<String, Any>) { databaseError, _ ->
if (databaseError == null) {
Log.d("[*] isWorking", "True")
} else {
Log.d("[*] isWorking", "False")
}
}
}
}
@SuppressLint("SimpleDateFormat")
private fun getDate(): String{
val calendar: Calendar = Calendar.getInstance()
val currDate = SimpleDateFormat("dd/MM/yyyy")
return currDate.format(calendar.time)
}
@SuppressLint("SimpleDateFormat")
private fun getTime(): String {
val calendar: Calendar = Calendar.getInstance()
val currTime = SimpleDateFormat("hh:mm a")
return currTime.format(calendar.time)
}
}
Кроме того, я добавил несколько операторов журнала для отладки. Вот что происходит, когда приложение находится в фоновом режиме:
2020-07-11 15:38:02.390 30232-30232/com.example.bemyhero D/[*] Status: Away
Это то, что происходит, когда приложение находится на переднем плане:
2020-07-11 16:04:48.649 1076-1076/com.example.bemyhero D/[*] Status: Online
2020-07-11 16:04:48.939 1076-1076/com.example.bemyhero D/[*] isWorking: True
2020-07-11 16:04:48.949 1076-1076/com.example.bemyhero D/[*] isWorking: True
2020-07-11 16:04:48.954 1076-1076/com.example.bemyhero D/[*] isWorking: True
Если вы внимательно посмотрите, вы могли бы увидеть, что два операторов "isWorking: True" взяты из onResume и onStart, второй, я предполагаю, может быть из onPause. Похоже, он обновляется только каждый раз, когда я открываю приложение, но для меня это не имеет никакого смысла, так как я добавил метод setPersistenceEnabled (true). Почему не работает?