Json listener? (Java)

  • Antworten:7
Marcus Ferl
  • Forum-Beiträge: 4

14.01.2021, 18:12:42 via Website

Hey leute,auf stackoverflow habe ich leider keine Antwort bekommen, folgendes ich beschäftige mich seid einiger zeit mit der App entwicklung.
Nun frage ich mich ob meine Lösung um daten live auszulesen richtig ist, funktionieren tut es. Nur bin ich mir nicht ganz sicher, ob ich es richtig gemacht habe.
Folgendes, ich hab in einem RecyclerView ein CardView item, dieses beihaltet zwei Buttons, An und Aus jeweilige dtsndsrt Farbe ist Weiß.
Wenn ich einen Button klicke wird dieser eingefärbt (An = Grün, Aus= Rot).
Je nach dem welchen Button ich klicke, wird unter der Url xxx folgendes zurückgegeben:

{POWER: ON}

Oder

{POWER: OFF}

Ziel war es nun, wenn ich z.b auf "An" klicke, dass falls die App auf einem anderem Gerät offen ist, automatisch die Farbe von Aus auf an springt.
Mit folgendem code funktioniert das auch wie gewünscht, nur hab ich so das Gefühl, dass es keine richtige Lösung ist.

public class JSONStatusParser {



String status;
RequestQueue requestQueue;




public JSONStatusParser() {
}


   public void statusrequest(String url, Context view, Button on, Button off, ImageView connectionView){

    requestQueue = Volley.newRequestQueue(view);



    JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET, url ,null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            try {
                status = response.toString();
                if (status.contains("OFF")) {
                    on.setBackgroundTintList(ColorStateList.valueOf(Color.WHITE));
                    off.setBackgroundTintList(ColorStateList.valueOf(Color.RED));
                } else if (status.contains("ON")) {
                    on.setBackgroundTintList(ColorStateList.valueOf(Color.GREEN));
                    off.setBackgroundTintList(ColorStateList.valueOf(Color.WHITE));
                } else {
                    on.setBackgroundTintList(ColorStateList.valueOf(Color.GREEN));
                    off.setBackgroundTintList(ColorStateList.valueOf(Color.RED));
                }

            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                   //error.printStackTrace();
                   connectionView.setImageResource(R.drawable.ic_disconnected);

                }
            });
 requestQueue.add(objectRequest);

}
}

Die Methode statusrequest rufe ich in der onBindViewHolder so auf:

autoUpdateHandler = new Handler();

    autoUpdateHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            JSONStatusParser statusParser = new JSONStatusParser();
            statusParser.statusrequest(currentItem.getUrl, holder.itemView.getContext(), holder.onButton, holder.offButton,holder.connectView);
            autoUpdateHandler.postDelayed(this, 1500);
        }
    }, 1500);

Nun wird alle 1,5 Sekunden abgefragt, ob ON oder OFF in der Url steht, und die Farben werden dem entsprechend gesetzt.
Ist es so richtig oder nicht?

— geändert am 14.01.2021, 18:13:16

Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

14.01.2021, 18:57:49 via Website

Hallo Marcus,

Herzlich wilkommen hier im Forum :)



Das Prinzip stimmt schon. Woran scheitert es denn? Gibt es einen Log oder Fehlermeldung?
Won welchem Gerät fragst du denn diesen Status ab, gibt es da keinen besseren Weg?
I.d.r ist Polling (alle x Sekunden ein Webseite abfragen) nicht sehr Effizient und verursacht je nach Anzahl an Geräten die gleichzeitig online sind, enormen Traffic...

Wenn du das auf Dauer einsetzen willst, überleg dir eine Push Lösung mittels FCM (Firebase), TCP Basiert oder per WebSocket. Wäre zumindest meine Empfehlung.

PS: Die View in deinem currentItem ist auch die richtige? Was ist wenn du das immer "Toogeln" lässt?

— geändert am 14.01.2021, 18:58:41

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Kommentieren
Marcus Ferl
  • Forum-Beiträge: 4

14.01.2021, 19:12:41 via Website

Erstmal vielen vielen Dank für die Antwort.

Also an sich funktioniert es ja. Ich hab mich nur gefragt ob das so richtig gelößt ist.
Ich habe smart Home Geräte, auf denen eine extra Firmware geflasht ist. Die halt je nach Powerstatus in einem Json File On bzw Off zurück gibt. Für diese habe ich eine App geschrieben um sie an oder aus zu schalten. Un ich wollte nun erreichen, dass sobald z.b meine Frau ein Gerät einschaltet, dass bei mir dann ebenfalls der Status auf eingeschaltet gesetzt wird, das ganze läuft Local ohne Verbindung nach außen. Ich hab noch keine jahrelange Programmiererfahrung, und hab mir deshalb gedacht, das ich den Status auslesen muss und diesen dann um wieder und wieder zu bekommen einen Thread brauche der es immer wiederholt.

Hilfreich?
Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

14.01.2021, 22:39:15 via Website

Ist das was du einsetzt Zufällig Tasmota. Wenn ja würde sich genau für solche Zwecke statt Polling auch MQTT anbieten. Nachteil ist, du brauchst einen Broker (dauerhaft laufender Server) im Netzwerk. Dann würde das auch ohne Polling gehen.

Ansonsten ja ist der Richtige Weg. Ich würde das abfrageintervall auf 5s setzen. Das reicht für realfallszenarien eigentlich immer aus.

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Marcus Ferl
Kommentieren
Marcus Ferl
  • Forum-Beiträge: 4

15.01.2021, 08:54:25 via Website

Jawohl, es handelt sich um Tasmota, ich hab auch ein Synology Nas mit dem könnte ich einen Server einrichten, aber da die App für jeden Tasmota Nutzer gedacht ist bzw bereits im Store erhältlich ist und nicht jeder ein Nas oder ähnliches hat und über das know how verfügt, bleib ich dann bei meiner Lösung. 5 Sekunden sind auch verkraftbar 🙂

Nochmals vielen Dank für die Antwort 🙂

Hilfreich?
Kommentieren
Marcus Ferl
  • Forum-Beiträge: 4

17.01.2021, 17:41:36 via Website

Genau da arbeite ich mich gerade für ein anderes Projekt ein aber danke für den Tip.

Was aber die App für Tasmota angeht, soll ja alles Lokal bleiben 😉

Hilfreich?
Kommentieren
danielcharles
  • Forum-Beiträge: 1

19.02.2021, 13:54:02 via Website

Hello I am Daniel, The Java API for JSON Processing provides a convenient way to process (parse, generate, transform, and query) JSON text. For generating and parsing JSON data, there are two programming models, which are similar to those used for XML documents: The object model creates a tree that represents the JSON data in memory.

Hilfreich?
Kommentieren