# Json listener?



## spike86 (13. Jan 2021)

Hey leute, 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, "http://" + 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.


----------



## xXSkyWalkerXx1 (30. Aug 2021)

Wenn's funktioniert, ist doch gut.

Man könnte in der "onResponse"-Methode das if-Statement verbessern:
benutze stattdessen "switch" und packe das, was du in der "else" hast, in den "default" von der switch

Ebenso wäre es für einen Feinschliff vllt besser, wenn das Programm in den 1.5s den Status (ON/OFF) abfragt 
und immer nur dann die LED (oder was auch immer) schaltet, wenn sich der Status vom Vorherigen geändert hat.
_(Siehe Oberserver-Pattern - also ein Listener für den Status)_


----------



## mihe7 (30. Aug 2021)

spike86 hat gesagt.:


> Je nach dem welchen Button ich klicke, wird unter der Url xxx folgendes zurückgegeben:


Was da zurückgegeben wird, ist schon mal kein gültiges JSON. Ein String hat in JSON in Anführungszeichen zu stehen: 

```
{"POWER":"ON"}
```

Wenn dem so wäre, könntest Du z. B. per `response.optString("POWER", "UNKNOWN") ;` den Wert des POWER-Attributs zurückgeben lassen (UNKNOWN, falls das Attribut nicht vorhanden ist). Danach kannst Du per if, switch, enum oder Map die Fallunterscheidung durchführen.


----------



## Jw456 (30. Aug 2021)

xXSkyWalkerXx1 hat gesagt.:


> Ebenso wäre es für einen Feinschliff vllt besser, wenn das Programm in den 1.5s den Status (ON/OFF) abfragt
> und immer nur dann die LED (oder was auch immer) schaltet, wenn sich der Status vom Vorherigen geändert hat.
> _(Siehe Oberserver-Pattern - also ein Listener für den Status)_



Er will scheinbar den  Status der LED von einem  Gerät was über einen Webserver verbunden ist.
Auch auf mehreren Handys anzeigen und steuern.
Nicht nur auf dem Handy wo ein Schaltbefehl gesendet wurde.
Deshalb  scheint er sich für ein Polling von  1.5 sek entschieden zu haben. 

Ob dafür das Http  Protokoll das richtige ist ?  Das hat ja keinen Rückkanal  zum Client.
Http 1.1 ist ja ein  zustandsloses Protokoll.

Um ohne Polling auszukommen vielleicht, MQTT und ein IObroker ,  Websockets Http 2.0,
FCM


----------

