Problem ze zeminna w onChildAdded

0

Witam, mam problem ze zmiana zmiennej powiadamiaj. niby wszystko się dobrze zmienia ( logcat tak pokazuje ), ale w metodzien onChildAdded w funkcji ladowanieListy zmienna po pierwszym przejsciu w pauze caly czas zostane na true i nigdy nie chce wrocic na false. chcialbym zrobic powiadomienia ktore przychodza tylko jak opuscilo sie glowna activity aplikacji. W czym jest problem?

class test : AppCompatActivity() {


    var powiadamiaj = false


    lateinit var notificationManager : NotificationManager
    lateinit var notificationChannel : NotificationChannel
    lateinit var builder : Notification.Builder
    private val channelId = "test"
    private val description = "test"



    override fun onPause() {
        super.onPause()

        powiadamiaj = true
        Log.d("eloczo", "var from z Onpause: "+powiadamiaj)


    }

    override fun onResume() {
        super.onResume()
        powiadamiaj = false
        Log.d("eloczo", "var from z OnResume: "+powiadamiaj)



    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)


        recyclerAdmin.layoutManager = LinearLayoutManager(applicationContext)



        ladowanieListy(adminid)


    }


    private fun ladowanieListy(idAdma:String){


        val base = FirebaseDatabase.getInstance().getReference("ListaUserow/")
        base.addChildEventListener(object : ChildEventListener {
            override fun onCancelled(p0: DatabaseError) {

            }

            override fun onChildMoved(p0: DataSnapshot, p1: String?) {

            }

            override fun onChildChanged(p0: DataSnapshot, p1: String?) {

            }

            override fun onChildAdded(p0: DataSnapshot, p1: String?) {

                val zamowienieKZA = p0.getValue(Zamowienie::class.java)
                if(zamowienieKZA != null){

                    tablicaZamowien.add(zamowienieKZA)
                    tablicaZamowien.sortBy {

                        it.numer

                    }
                    recyclerAdmin.adapter = kolejkaAdapter(tablicaZamowien, applicationContext, idAdma)

                }


                if(powiadamiaj){
                    powiadomienie()
                }




            }

            override fun onChildRemoved(p0: DataSnapshot) {



            }


        })

    }

    private fun powiadomienie(){


        Log.d("eloczo", "var from z powiadomienie(): "+powiadamiaj)

        // Powiadomienie



        notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        val intent = Intent(applicationContext, Kolejka_zamowien_admin::class.java)
        intent.putExtra("idRestauracjiAdmin", idRestauracjiTwojejAdminie)
        val pendingIntent = PendingIntent.getActivity(applicationContext,0,intent, PendingIntent.FLAG_UPDATE_CURRENT)


        val contentView = RemoteViews(packageName,R.layout.notification_layout)
        contentView.setTextViewText(R.id.tv_title,"test")
        contentView.setTextViewText(R.id.tv_content,"test")

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notificationChannel = NotificationChannel(channelId,description,
                NotificationManager.IMPORTANCE_HIGH)
            notificationChannel.enableLights(true)
            notificationChannel.lightColor = Color.GREEN
            notificationChannel.enableVibration(true)
            notificationChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
            notificationManager.createNotificationChannel(notificationChannel)

            builder = Notification.Builder(applicationContext,channelId)
                .setContent(contentView)
                .setVisibility(Notification.VISIBILITY_PUBLIC)
                .setSmallIcon(R.drawable.logo_apki_powiadomienie)
                .setContentTitle("test")
                .setContentText("test")
                .setLargeIcon(BitmapFactory.decodeResource(resources,R.drawable.logo_apki_powiadomienie))
                .setContentIntent(pendingIntent)
        }else{

            builder = Notification.Builder(applicationContext)
                .setVisibility(Notification.VISIBILITY_PUBLIC)
                .setSmallIcon(R.drawable.logo_apki_powiadomienie)
                .setContentTitle("test")
                .setContentText("test")
                .setLargeIcon(BitmapFactory.decodeResource(resources,R.drawable.logo_apki_powiadomienie))
                .setContentIntent(pendingIntent)
        }



        notificationManager.notify(1234,builder.build())





        // Koniec powiadomienia




    }



}
1

Pokaż jakieś logi z tymonResume, onPause i powiadomienie, bo coś musiłaś źle opisać.

0
2020-02-16 18:48:08.109 24305-24305/com.example.restauracja D/eloczo: var from z Onpause: true
2020-02-16 18:48:12.204 24305-24305/com.example.restauracja D/eloczo: var from z OnCreate: false
2020-02-16 18:48:12.210 24305-24305/com.example.restauracja D/eloczo: var from z OnResume: false
2020-02-16 18:48:18.424 24305-24305/com.example.restauracja D/eloczo: var from z powiadomienie(): true
2020-02-16 18:48:18.489 24305-24305/com.example.restauracja D/eloczo: var from z powiadomienie(): true

Nie mam pojecia co jest tylko onChildAdded pamieta jako true...

1

Skąd pochodzi to pierwsze Onpause? Operujesz na tej samej instancji aktywności czy tworzysz nową np. poprzez startActivity albo obrót ekranu czy też inną zmianę konfiguracji?

0
Michał Sikora napisał(a):

Skąd pochodzi to pierwsze Onpause? Operujesz na tej samej instancji aktywności czy tworzysz nową np. poprzez startActivity albo obrót ekranu czy też inną zmianę konfiguracji?

dopiero zaczynam i nie bardzo rozumiem o co chodzi. pochodzi Kolejka_zamowien_admin : AppCompatActivity()

1

Co dokładnie robisz? Odpalasz aplikację, pomniejszasz ją i powiększasz czy coś innego?

0

Piszę komunikator wysyłanie wiadomości, dodawanie znajomych itp. Tutaj konkretnie chodzi o to żeby powiadomienie z wiadomością nie pokazywało się kiedy jestem oknie rozmowy z użytkownikiem który do mnie napisał. Myślałem, że wystarczy utworzyć zmienna z wartością false w onPause przestawić ja na true żeby tylko tam wyświetlało wiadomości i jak wroci sie do aktywnosci to, że jak onResume zmieni ja znowu na false to bedzie dobrze, ale jak widac w tym onChildAdded caly czas pamieta wartość z pierwszego pauzownia aplikacji. Ktoś mi podpowiedział, że problemem możeby być to, że jak się wróci to tworzy się nowe activity i onChildAdded trzyma info ze starej aktywnosci

0

Chodziło mi o to jakie kroki dokładnie wykonujesz :). Też podejrzewam, że to stara aktywność jest trzymana w callbacku.

Możesz zalogować jaka akytwność jest używana przy metodach i pokazać logi? Coś w stylu Log.d("eloczo", "Activity: $this").

0

D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@778c617

dzieki za pomoc :)
wrzuciłem to w ten on ChildAdded

przegladam teraz cykl zycia aplikacji i z tego co tam widzę to onCreate tworzy się tylko raz więc raczej powinno być dobrze. onPause zmienia powiadamiaj na true, a onResume na false i wydaje mi się, że powinno działać

1

Dodaj to też do innych metod (albo przynajmniej do onCreate) inaczej nic nie wywnioskujesz. Musisz sprawdzić czy numer po @ jest ten sam.

0
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin@d8fac75
D/eloczo: var from z Onpause: true
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin@d8fac75
D/eloczo: var from z OnResume: false
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin@d8fac75
D/eloczo: var from z Onpause: true
D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin@d8fac75
D/eloczo: var from z OnResume: false

chyba inny numer

to: D/eloczo: Activity: com.example.restauracja.Kolejka_zamowien_admin$ladowanieZamowien$1@295326b

jest z onChildAdded

a reszta na przemian z onCreate i onResume

2

W onChildAdded nie logujesz aktywności tylko callback jako this. Dlatego chciałem, żebyś dodał to do powiadomienie(). Jeżeli chcesz mieć aktywność w onChildAdded() to musisz zrobić ${this@Kolejka_zamowien_admin} zamiast $this.

A najlepiej jakbyś zapoznał się z debuggerem i zbadał temat. https://developer.android.com/studio/debug

0
2020-02-16 20:18:27.413 30767-30767/com.example.restauracja D/eloczo: Activity onCreate: com.example.restauracja.Kolejka_zamowien_admin@b15ff7
2020-02-16 20:18:27.413 30767-30767/com.example.restauracja D/eloczo: var from z OnCreate: false
2020-02-16 20:18:27.423 30767-30767/com.example.restauracja D/eloczo: Activity onResume: com.example.restauracja.Kolejka_zamowien_admin@b15ff7
2020-02-16 20:18:27.424 30767-30767/com.example.restauracja D/eloczo: var from z OnResume: false
2020-02-16 20:18:27.642 30767-30767/com.example.restauracja D/eloczo: Activity onChildAdded: com.example.restauracja.Kolejka_zamowien_admin@b15ff7
2020-02-16 20:18:31.052 30767-30767/com.example.restauracja D/eloczo: Activity onPause: com.example.restauracja.Kolejka_zamowien_admin@b15ff7
2020-02-16 20:18:31.055 30767-30767/com.example.restauracja D/eloczo: var from z Onpause: true
2020-02-16 20:18:32.424 30767-30767/com.example.restauracja D/eloczo: Activity onCreate: com.example.restauracja.Kolejka_zamowien_admin@4fc0446
2020-02-16 20:18:32.425 30767-30767/com.example.restauracja D/eloczo: var from z OnCreate: false
2020-02-16 20:18:32.433 30767-30767/com.example.restauracja D/eloczo: Activity onResume: com.example.restauracja.Kolejka_zamowien_admin@4fc0446
2020-02-16 20:18:32.434 30767-30767/com.example.restauracja D/eloczo: var from z OnResume: false
2020-02-16 20:18:32.562 30767-30767/com.example.restauracja D/eloczo: Activity onChildAdded: com.example.restauracja.Kolejka_zamowien_admin@4fc0446
2020-02-16 20:18:33.566 30767-30767/com.example.restauracja D/eloczo: Activity onPause: com.example.restauracja.Kolejka_zamowien_admin@4fc0446
2020-02-16 20:18:33.568 30767-30767/com.example.restauracja D/eloczo: var from z Onpause: true
2020-02-16 20:18:34.387 30767-30767/com.example.restauracja D/eloczo: Activity onCreate: com.example.restauracja.Kolejka_zamowien_admin@3deb36c
2020-02-16 20:18:34.387 30767-30767/com.example.restauracja D/eloczo: var from z OnCreate: false
2020-02-16 20:18:34.396 30767-30767/com.example.restauracja D/eloczo: Activity onResume: com.example.restauracja.Kolejka_zamowien_admin@3deb36c
2020-02-16 20:18:34.397 30767-30767/com.example.restauracja D/eloczo: var from z OnResume: false
2020-02-16 20:18:34.513 30767-30767/com.example.restauracja D/eloczo: Activity onChildAdded: com.example.restauracja.Kolejka_zamowien_admin@3deb36c
2020-02-16 20:18:35.396 30767-30767/com.example.restauracja D/eloczo: Activity onPause: com.example.restauracja.Kolejka_zamowien_admin@3deb36c
2020-02-16 20:18:35.397 30767-30767/com.example.restauracja D/eloczo: var from z Onpause: true

Dzieki jeszcze raz za pomoc :) słabo to ogarniam, ale tu już widać, że numery się zmieniaja. To znaczy, że onCreate tworzy się kilka razy i onResume, nie zmienia zmiennej na false dla tego activity w którym jestem? Bardzo mi zależy żeby iść z tym do przodu.

0

Tak, dzieje się dokładnie to, co napisałeś. Teraz pytanie czemu. Jak tworzysz aktywność? Robisz gdzieś startActivity() czy to domyślna aktywność aplikacji? Obracasz ekranem w międzyczasie? Możesz masz w ustawieniach programisty telefonu zaznaczoną opcję Don't keep activities/Nie zachowuj działań?

0

nigdzie nie mam startActivity() ekranem tez nie obracam nawet mam zablokowane obracanie. Nie zachowuj działan też na off. Domyślna aktywność chodzi o to, że startowa? Trzeba przejść przez dwie inne żeby do niej się dostać.

0

Tak, chodziło mi o startową. Jak w takim razie dostajesz się do tej aktywności jeśli nigdzie nie robisz startActivity()? I czy możesz udostępnić kod np. na GitHubie? Bo trochę wróżę tutaj, jak dochodzi u Ciebie do wycieku aktywności.

Jedna sprawa jest pewna. Nie usuwasz nigdzie listenera z Firebase'a. Musisz gdzieś w onDestroy wywołać removeChildEventListener czy coś w stylu (nie wiem dokładnie z głowy jak nazywa się metoda).

0

robię startActivity. Źle zrozumiałem pytanie myślałem, ze chodzi czy na tej aktywności jest gdzies startActivity. przetesujeć. Kod całej apki będzie potrzebny? Jak wywołam onDestroy to całe activity chyba padnie i nie będzie nasłuchiwać czy coś się dodało w firebase

1

Najlepiej byłoby cały kod wrzucić na GH, ale najpierw spróbuj usunąć callback. Firebase jest globalnym obiektem, więc wszystko co w nim zarejestrujesz musisz odrejestrować zgodnie z cyklem życia obiektu. Czyli jeśli Twój callback ma refrencję do aktywności, to po wywołaniu onDestroy() aktywność nie może być posprzątana, bo Firebase ciągle trzyma do niej referencję. To dosyć typowy wyciek pamięci w Androidzie, że coś gdzieś trzyma referencję do aktywności albo widoku.

0

Nie bardzo rozumiem jeszcze jak to zrobić. nie używam nigdzie onDestroy(), a żeby odłaczyć childEventListener to muszę zrobić coś w stylu:

 val base = FirebaseDatabase.getInstance().getReference("uzytkownicy")
val listener =       val listener = object :ChildEventListener{

tutaj metody

        }


base.removeEventListener(listener)

Jak zrobie dwie funkcje pobieranie z firebase jedna dla aktywnej apki, a druga dla onPause i np jak aplikacja będzie aktywna to robię removeEventListener dla tej w pauzie, a jak jest w pauzie to removeEventListener dla tej z aktywnosci i wtedy w onPause odpalam druga funkcje która tam nasłuchuje? nie wiem czy to zrozumiałem, ale zaraz sam to sprawdzę.

1

Ty nigdy nie powinieneś wywoływać metod cyklu życia. onCreate, onDestroy itd wywołuje Android w odpowiednich momentach.

Co do drugiej częsci, to nie do końca rozumiem. Powineneś mieć mniej więcej coś takiego.

class MojaAktywność : Activity() {
  val listener: ChildEventListener = TODO()

  fun onCreate(inState: Bundle?) {
    super.onCreate(inState)
    FirebaseDatabase.getInstance().getReference("uzytkownicy").addChildEventListener(listener)
  }

  fun onDestroy() {
    super.onDestroy()
    FirebaseDatabase.getInstance().getReference("uzytkownicy").removeEventListener(listener)
  }
}
0

Tak ja nie wywołuje tego. o co chodzi z tymi callbackami ?

1

ChildEventListener to jest callback, który rejestrujesz w Firebase. Firebase w odpowiednich momentach wywołuje metody tego tego callbacku. Twój callback zawiera referencję do aktywności, więc kiedy rejesterujesz go w Firebase, to jest tam trzymany wraz z aktywnością, więc aktywność nie może zostać usunięta i dochodzi do wycieku pamięci. Dodatkowo wszystkie zarejestowane metody dalej są wywoływane, czyli onChildAdded() itd. dalej jest wywoływane przez Firebase i wykonuje kod, który był tam zarejestrowany (z referencją do starej aktywności).

0

Dzięki za te wszystkie informacje. Czyli jakbym użył removeEventListener() na moim nasłuchiwaniu to powinno przestać przesyłać powiadomienia? Spróbuję removeEventListener() rozwiązać ten problem.

0
baseTestPauza.removeEventListener(listenerTestPauza)

zrobiłem aktywowanie listenera w onPause i remove tego listenera w onResume, a to dalej daje powiadomienia

0

W taki sposób powinno zabijać się listenera? coś mi nie działa

val baseTestAktywny = FirebaseDatabase.getInstance().getReference("zamowienia")



    val baseListenerTest =  object :ChildEventListener{



            override fun onCancelled(p0: DatabaseError) {
                TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
            }

            override fun onChildMoved(p0: DataSnapshot, p1: String?) {
                TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
            }

            override fun onChildChanged(p0: DataSnapshot, p1: String?) {
                TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
            }

            override fun onChildAdded(p0: DataSnapshot, p1: String?) {
                val zamowienieKZA = p0.getValue(Zamowienie::class.java)
                if(zamowienieKZA != null){

                    tablicaZamowien.add(zamowienieKZA)
                    tablicaZamowien.sortBy {

                        it.numer

                    }
                    recyclerKolejkaZamowienAdmin.adapter = kolejkaZamowienAdapter(tablicaZamowien, applicationContext, "100002")

                }
                Log.d("eloczo", "Activity onChildAdded: ${this@Kolejka_zamowien_admin}")




            }

            override fun onChildRemoved(p0: DataSnapshot) {
                TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
            }
        }


    override fun onStop() {
        super.onStop()

        baseTestAktywny.removeEventListener(baseListenerTest)
    }
0

zrobilem dwa listenery jeden z powiadomieniem drugi bez. z powiadomieniem ma byc aktywny jak nie jestem w oknie z lista uzytkownikow. Udaje mi sie wylaczyc jednego tylko tego ktory aktywuje sie w onCreate przez wylaczenie go removeEventListener w onStop, a chce mieć jeszcze listenera ktory aktywuje się w onPause i aktywuje go w tym onPause, ale pozniej removeEventListener nie chce go wyłaczyć nigdzie daje to w onCreate, onStart, onResume i nic

1

Jeżeli rejestujesz coś w onPause() to na 100% robisz coś źle, bo w większości wypadków nie będziesz miał kiedy odrejestrować tego listenera. Będziesz miał mniej więcej taką sytuację.

Otwierasz aktywność i wywołuje się po kolei.

onCreate()
onStart()
onResume()

Wychodzisz z niej.

onPause() // rejestrujesz listenera
onStop()
onDestroy()

Masz teraz wyciek pamięci i nie masz jak odrejestować listenera zarejestrowanego w onPause() (jeśli był on tworzony lokalnie).

0

Własnie tak myślałem, ze nie będzie gdzie tego zatrzymać. To w jaki sposób zrobić wyświetlanie powiadomień tylko wtedy kiedy np ekran rozmowy jest wyłączony? kiedy używam ChildEventListener i w onChildAdded daję tego ifa sprawdzającego który pamięta tylko ostatnia zmiane z onPause. Nie mam już pomysłow

0

może jest jaka funkcja która zabija wszystkie aktywne Listenery? wtedy wrzuciłbym to w onCreate i nie pokazywałby sie wiadomości

1

Robisz to źle. Użyj FCM do powiadomień i albo skorzystaj z sekcji Notification przy wysyłaniu i Firebase ci wygeneruje powiadomienie (ale tylko wtedy, gdy aplikacja wyłączona), albo nie i sam generuj powiadomienia kiedy chcesz.

Jeśli pushe mają być związane ze zmianą jakiejś gałęzi w Firestore/Database, to użyj Functions na serwerze, aby automatycznie generować pushe.

Zresztą, tak jak to robisz teraz to i tak nie ma szans działać, bo gdy zamkniesz albo zminimalizujesz aplikację, to żadne powiadomienie nie dojdzie. Więc żaden to komunikator. Wciśniesz Home, system ubije aplikację i komunikator zdechł. Przyjdzie event dopiero, gdy ponownie uruchomisz aplikację

1 użytkowników online, w tym zalogowanych: 0, gości: 1