Eine Datenbank-Voting App erstellen

  • Antworten:16
  • OffenNicht stickyBentwortet
  • Forum-Beiträge: 17

28.05.2018, 20:52:48 via Website

Hi,

bin ein Amateur im Java/Android Studio programmieren und mein Wissen über Datenbanken ist auch begrenzt.

Habe da einmal eine Frage.

Wie kann ich eine App programmieren, in der die User über ein Event abstimmen können. Also sie haben die Wahl zwischen zwei Buttons - "Ja" und "Nein". Unter den Buttons soll jeweils ein TextView sein, welche in Prozent anzeigt, wie sich die anderen User entschieden haben.

Hier mal das grobe Layout:

<FrameLayout 

//Links musste ich entfernen, da ich ein neuer Nutzer bin
xmlns:android="..."
xmlns:tools="..."
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TabCommunity">

android:id="@+id/voting"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:id="@+id/question"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentStart="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="100dp"
    android:gravity="center"
    android:text="Do you think the event is good?"
    android:textSize="20dp"
    android:textStyle="bold" />

<Button
    android:id="@+id/btnYes"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentStart="true"
    android:layout_centerVertical="true"
    android:layout_marginStart="50dp"
    android:background="@color/colorPrimaryDark"
    android:fontFamily="casual"
    android:padding="15dp"
    android:text="YES"
    android:textColor="#fff"
    android:textSize="20dp"
    android:textStyle="bold" />

<Button
    android:id="@+id/btnNo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentEnd="true"
    android:layout_centerVertical="true"
    android:layout_marginEnd="50dp"
    android:background="@color/colorPrimaryDark"
    android:fontFamily="casual"
    android:padding="15dp"
    android:text="NO"
    android:textColor="#fff"
    android:textSize="20dp"
    android:textStyle="bold" />

<TextView
    android:id="@+id/com_yes"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentStart="true"
    android:layout_marginBottom="170dp"
    android:layout_marginStart="120dp"
    android:text="- %"
    android:textSize="16dp"
    android:textStyle="italic" />

<TextView
    android:id="@+id/com_no"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentEnd="true"
    android:layout_alignTop="@+id/com_yes"
    android:layout_marginEnd="102dp"
    android:text="- %"
    android:textSize="16dp"
    android:textStyle="italic" />

Habe noch keinen Code, da ich absolut keine Ahnung habe, wie das zu realisieren ist...(thinking)

Wie kann man die Entscheidungen der Nutzer in einer Datenbank speichern und diese dann in Echtzeit (im TextView) anzeigen?

Also als Beispiel.
Es stimmt 9 Leute ab. 6 Nutzer voten mit "ja" und die anderen 3 mit "nein". Der 10e Nutzer stimmt ebenfalls mit "ja". Dem 10en Nutzer wird im TextView jetzt unter dem "ja" Button "70%" und unter dem "nein" Button "30%" angezeigt.

Was sollte man dafür verwenden?
Die Database von Firebase oder doch DB Browser for SQlite?

Danke schon einmal im Voraus! :)

Grüße

Diskutiere mit!
Beste Antwort
  • Forum-Beiträge: 483

30.05.2018, 19:58:23 via Website

Hallo
hier mal ein Code Beispiel was hoch zählen sollte.
in dem ValueEventListener() kommen die Daten an und werden in einer Variable gespeichert.
Beim Klick wird sie erhöht, die flag Variable dient dazu nur ein mal zu klicken.
Wobei da noch ein Schönheitsfehler ist denn, wenn du die App neu startest kannst du wieder Klicken.
Das müsstest du über den Username lösen der sich anmeldet.
Auch solltest du nicht alles in das Eltern Element schreiben benutze Kind Elemente. Die DB ist eine Json Struktur.

public class MainActivity extends AppCompatActivity implements View.OnClickListener
{
public static String[] bet = new String[] {"YES", "NO"};

private Button btn_yes, btn_no;
private TextView comY, comN;
private View voteView;

FirebaseDatabase database;
DatabaseReference myRefYes, myRefNo;
long oldYes, oldNo;
int flag = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btn_yes = (Button) voteView.findViewById(R.id.btnYes);
    btn_yes.setOnClickListener(this);
    btn_no = (Button) voteView.findViewById(R.id.btnNo);
    btn_no.setOnClickListener(this);

    myRefYes = database.getReference("ForecastVoteYes");
    myRefYes.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
              oldYes = dataSnapshot.getValue(long.class);
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

    myRefNo = database.getReference("ForecastVoteNo");
    myRefYes.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
             oldYes = dataSnapshot.getValue(long.class);
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

    }




public void onClick(View v) {
    switch (v.getId()){
        case R.id.btnYes:
            if ( flag == 0){
                oldYes++;
                myRefYes.setValue(oldYes);
                flag = 1;
            }
            break;

        case R.id.btnNo:
            if ( flag == 0){
                oldNo++;
                myRefYes.setValue(oldNo);
                flag = 1;
            }
            break;
    }
}

}

https://firebase.google.com/docs/database/android/read-and-write

PS. habe mir den Link von stackoverflow angeshen .
Das was du als Skript bezeichnest ist Json. Hat nichts mit Skript zu tun.
Das ist eine Daten Beschreibung Sprache, Struktur ähnlich wie XML.
In der DB werde deine Daten in einer Json Struktur gespeichert.
Die Ref die du benutzt ist das oberste Element dem du einen Wert gegeben hast.
Man kann aber auch Kind Elemente und Kindes Kind Elemente hinzufügen und am Ende Werte.
Das sind Key Wert Paare .
Auserdem ist der Code in Klotlin nicht in Java.

Schaue dir Json an .

— geändert am 04.06.2018, 11:56:32

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 483

29.05.2018, 09:14:26 via Website

Hallo willkommen im Forum.

Habe noch keinen Code, da ich absolut keine Ahnung habe, wie das zu realisieren ist

Da wirst du dich wohl erstmal etwas mit den Grundlagen der Android und Java Programmierung beschäftigen müssen. Nur das Layout reicht da nicht.

Zu deiner Frage .
DB Browser for SQlite ist doch nur ein Aufsatz für eine SQlite für den Browser oder irre ich mich jetzt. Bringt die auch gleich einen Server mit und eine Script Sprache ?

Firebase ist eine Online Echtzeitdatenbank mit API. Da brauchst du keinen Server. Nur ab einer bestimmten Größe oder Trafik ist es nicht mehr kostenlos.
Ist eine im Json Format arbeitende DB.

Du brauchst auf jeden fall eine DB die auf einen Server läuft und wo du auch Sprite ausführen kannst, darfst zB. in PHP.

fange erst mal hiermit an
http://www.programmierenlernenhq.de/android-app-programmieren-tutorial/
https://www.udemy.com/android-7-tutorial-einsteiger-und-firebase-server/

Bei dem Kurs musste öfters schaun den gibt es machmal für 10 Euro.

Hoffe das reicht fürs erste.
Lg J.

— geändert am 29.05.2018, 09:36:40

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 17

29.05.2018, 15:31:01 via Website

Hi,

Danke für die Antwort! :)

Habe mich gestern noch ein bisschen eingearbeitet und die Firebase Datenbank eingerichtet.
Hier mal den Code dazu:

import android.os.Bundle;

import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

public class TabVoting extends Fragment {

public static String[] bet = new String[] {"YES", "NO"};

private Button btn_yes, btn_no;
private TextView comY, comN;
private View voteView;


public TabVoting() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    voteView = inflater.inflate(R.layout.fragment_tab_voting, container, false);

    btn_yes = (Button) voteView.findViewById(R.id.btnYes);

    btn_yes.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            FirebaseDatabase database = FirebaseDatabase.getInstance();
            DatabaseReference myRef = database.getReference("ForecastVoteYes");

            myRef.setValue("+");
        }
    });

    btn_no = (Button) voteView.findViewById(R.id.btnNo);

    btn_no.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            FirebaseDatabase database = FirebaseDatabase.getInstance();
            DatabaseReference myRef = database.getReference("ForecastVoteNo");

            myRef.setValue("+");
        }
    });

    return voteView;
}

}

Also per Klick wird nun ein Eintrag in der Datenbank erstellt.

Werde es einmal ausprobieren, ob es auch "hochzählt" wenn mehrere User auf den Button klicken.

Der Rest wird dann auch noch einmal nachgeschaut. Wenn dann noch Fragen sind, wende ich mich noch einmal an Euch.
Ansonsten aktualisiere ich den Code, falls Andere auch auf der Suche nach so einem Code sind.

Danke.

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 483

29.05.2018, 22:47:09 via Website

Hallo
also hochzählen wird es wohl nicht.
Denn dafür müsstest du erstmal den alten in der DB vorhandenen Wert abfragen dann erhöhen und wieder speichern.
Auserdem hast du gar keinen Wert zum Zählen nur ein Zeichen "+" und jedesmal wenn du den Button klicks wird wieder das gleiche in die DB geschrieben. Da kann nichts Zählen.

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 17

30.05.2018, 13:04:48 via Website

Hi,

Okay ja das ergibt ja auch irgendwo Sinn, wenn man nur write und read hat(?) :D
Das "+" war nur so als Bezeichnung für mich selbst gedacht oder ist es ein Problem, dass zweimal der selbe Wert verwendet wird?

Habe jetzt hier etwas gefunden, was ja anscheinend genau das machen soll.

stackoverflow . com /questions/15148803/in-firebase-is-there-a-way-to-get-the-number-of-children-of-a-node-without-load

Aber das ist ja auf Script bezogen? Also die zwei ersten Antworten.

Verstehe das leider absolut nicht. Ist das überhaupt mit Android Studio/Java möglich?

Sorry für die dummen Fragen.

Dein Powerstart Link sieht ja gut aus, aber bin leider ein armer Student (das soll keine Ausrede sein, denn die 10€ sollte ja jeder haben) und wollte erst einmal schauen, ob es vielleicht über Foren auch funktioniert.

Trotzdem danke nochmal

Hilfreich?
Diskutiere mit!
Beste Antwort
  • Forum-Beiträge: 483

30.05.2018, 19:58:23 via Website

Hallo
hier mal ein Code Beispiel was hoch zählen sollte.
in dem ValueEventListener() kommen die Daten an und werden in einer Variable gespeichert.
Beim Klick wird sie erhöht, die flag Variable dient dazu nur ein mal zu klicken.
Wobei da noch ein Schönheitsfehler ist denn, wenn du die App neu startest kannst du wieder Klicken.
Das müsstest du über den Username lösen der sich anmeldet.
Auch solltest du nicht alles in das Eltern Element schreiben benutze Kind Elemente. Die DB ist eine Json Struktur.

public class MainActivity extends AppCompatActivity implements View.OnClickListener
{
public static String[] bet = new String[] {"YES", "NO"};

private Button btn_yes, btn_no;
private TextView comY, comN;
private View voteView;

FirebaseDatabase database;
DatabaseReference myRefYes, myRefNo;
long oldYes, oldNo;
int flag = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btn_yes = (Button) voteView.findViewById(R.id.btnYes);
    btn_yes.setOnClickListener(this);
    btn_no = (Button) voteView.findViewById(R.id.btnNo);
    btn_no.setOnClickListener(this);

    myRefYes = database.getReference("ForecastVoteYes");
    myRefYes.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
              oldYes = dataSnapshot.getValue(long.class);
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

    myRefNo = database.getReference("ForecastVoteNo");
    myRefYes.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
             oldYes = dataSnapshot.getValue(long.class);
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

    }




public void onClick(View v) {
    switch (v.getId()){
        case R.id.btnYes:
            if ( flag == 0){
                oldYes++;
                myRefYes.setValue(oldYes);
                flag = 1;
            }
            break;

        case R.id.btnNo:
            if ( flag == 0){
                oldNo++;
                myRefYes.setValue(oldNo);
                flag = 1;
            }
            break;
    }
}

}

https://firebase.google.com/docs/database/android/read-and-write

PS. habe mir den Link von stackoverflow angeshen .
Das was du als Skript bezeichnest ist Json. Hat nichts mit Skript zu tun.
Das ist eine Daten Beschreibung Sprache, Struktur ähnlich wie XML.
In der DB werde deine Daten in einer Json Struktur gespeichert.
Die Ref die du benutzt ist das oberste Element dem du einen Wert gegeben hast.
Man kann aber auch Kind Elemente und Kindes Kind Elemente hinzufügen und am Ende Werte.
Das sind Key Wert Paare .
Auserdem ist der Code in Klotlin nicht in Java.

Schaue dir Json an .

— geändert am 04.06.2018, 11:56:32

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 17

01.06.2018, 13:59:02 via Website

Hey Jokel,

vielen, lieben Dank!

So funktioniert es! Bist der Beste :)

Werde mich aber trotzdem einmal in JSON einlesen, da ich noch ein paar andere Sachen vor haben.

Noch ein schönes Wochenende :)

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 17

04.06.2018, 09:30:42 via Website

Sorry nochmal für den neuen Eintrag.

@Jokel. Kann ich Deine Antwort auf StackOverflow posten? (Natürlich mit - wenn gewünscht - Deinem Username) Habe dort die Frage auch gestellt und die Antwort hilft bestimmt ein paar Anderen auch.

Wenn nicht, ist das auch okay :)

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 483

04.06.2018, 10:00:26 via Website

Hallo
von mir aus das ist kein geheimer Code. Der läst sich bei Google nachschauen.
Hier ist es auch öffentlich.

Name hinzufügen nicht schlecht.

lg J.

Hilfreich?
Diskutiere mit!
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.174

04.06.2018, 10:04:14 via App

Oder einfach zum Beitrag zusätzlich verlinken.

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

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 483

04.06.2018, 11:47:43 via Website

Hi, @Hans Cluedo wie ist dein Username bei StackOverflow?

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 17

04.06.2018, 15:20:54 via Website

Hallo,

ok gut. Bin da vorsichtig. Frage lieber vorher nach :D

Dann verlinke ich den Beitrag einmal

Name müsste "Hansi" sein. Bin dort auch über Facebook eingeloggt.

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 17

10.08.2018, 12:26:13 via Website

Hallo Leute,

habe es letztes Mal leider nicht hinbekommen. Habe jetzt wieder Zeit und wollte es wieder in Angriff nehmen.

Habe dazu noch ein bisschen im Internet geschaut. Das Thema Firebase ist wohl durch :D
Mache das jetzt über eine SQLite Datenbank. Aber das verstehe ich leider nicht so wirklich.

Habe dazu einen Code gefunden, welche eine Datenbank mit einer Tabelle anlegt. Das funktioniert auch soweit und so gut.

Hier mal der Link dazu:

Android SQLite Datenbank Tutorial – Teil 1: Android SQLite Projekt in Android Studio anlegen

So jetzt aber die Frage. Wie erstellt man eine DB mit mehreren Tabellen?
Egal was ich mache, es funktioniert einfach nicht.

Habe schon versucht in dem Helper das zu machen:

//second table
public static final String TABLE_FIRST_LIST = "first_list";
public static final String COLUMN_ID_1 = "_id_1";
public static final String COLUMN_FIRST = "first";

//third table
public static final String TABLE_SECOND_LIST = "second_list";
public static final String COLUMN_ID_2 = "_id_2";
public static final String COLUMN_SECOND = "second";

public static final String SQL_CREATE_2 =
"CREATE_TABLE" + TABLE_FIRST_LIST +
"(" + COLUMN_ID_1 + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_FIRST + " TEXT NOT NULL):";

public static final String SQL_CREATE_3 =
        "CREATE_TABLE" + TABLE_SECOND_LIST +
                "(" + COLUMN_ID_2 + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COLUMN_SECOND + " TEXT NOT NULL):";

und dann wird es mit

db.execSQL(SQL_CREATE_2);
db.execSQL(SQL_CREATE_3);

aufgerufen.

Ist das der richtige Weg? Oder muss man für jede Tabelle eine eigene Setter, Getter Klasse anlegen?

Mit SQLite wäre es ja immerhin möglich, den Durchschnitt ganz einfach zu erhalten?

Und wie geht das, dass man die DB dann auch in anderen Activities/Fragmenten aufrufen kann? (Aktuell funktioniert das nur in der MainActivity. Die anderen werfen einen Fehler aus "on a null object reference")

Habe noch einen Haufen anderer Fragen :D Aber möchte euch nicht überrennen mit den Fragen.
Wäre super nett, wenn mir jemand ein paar Tipps geben könnte. Vielleicht auch wirklich gute Literaturen.

Danke schon einmal

Hilfreich?
Diskutiere mit!
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.174

10.08.2018, 13:07:35 via Website

Hallo Hans,

den "richtigen Weg" gibt es hier nicht.
Das ist ein Weg, wie man das machen kann, wenn d das allerdings so machst, solltest du dir deine SpaltenNamen als Variablen eindeutig definieren.
Zudem würde ich die ID immer mit einedeuttigen Namen festlegen und unterstriche vermeiden.

z.b.

public static final String TABLE_NAME_SECOND_LIST = "SecondList";
public static final String SECOND_LIST_COLUMN_ID = "SecondListId";
public static final String  SECOND_LIST_COLUMN_SECOND = "Second";

In anderen Activities/Klassen kannst du die DB nutzen, indem du die Instanz der DB (SQLiteDatabase) übergibst oder die DB Datei/Inszanz neu öffnetst.

Ich empfehle dir aber: Baue dir eine oder Meherer DB Helper Klassen in denen deien SQL raw oder per Cursor abgelegt sind. Die abgefragten Daten packst du am besten in Objekte.
Solange du nicht ständig relationen zwischen Daten aufbauen musst, ist das der beste Weg.
Zudem hast du dann alle Abfragen in einer oder merhreren (Sub) Klassen und gesammelt aber nicht über alle Activities verteilt. Das hilft bei Änderungen ungemein.

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

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 17

10.08.2018, 15:04:30 via Website

Danke für Deine Antwort.

Habe es kurz versucht, aber leider ohne Erfolg. Meine Motivation ist für heute hinüber...

Werde es die Tage noch einmal versuchen.
Melde mich dann wieder :)

Wünsche ein schönes Wochenende.

Hilfreich?
Diskutiere mit!
Ludy
  • Mod
  • Blogger
  • Forum-Beiträge: 7.166

10.08.2018, 15:42:42 via App

Hallo zusammen,

also die ID sollte so wie alle Spaltennamen keine Zahlen haben, kann zu Fehlern führen - warum keine Ahnung. Unterstriche sind kein Problem, wenn danach mindestens zwei Buchstaben kommen.

Dein SQL Sting hat ein Doppelpunkt NULL):"; muss aber ein Semikolon sein.

— geändert am 10.08.2018, 15:43:10

Gruß Ludy (App Entwickler)

Mein Beitrag hat dir geholfen? Lass doch ein "Danke" da.☺

Lebensmittelwarnung App-Thread

Download Samsung Firmware Tool

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 483

10.08.2018, 16:29:52 via Website

Hi du baust deinen Strign nicht richtig zusammen.

"CREATE TABELE " nicht mit Unterstrich und auch ein Lehzeichen am ende

public static final String SQL_CREATE_2 = "CREATE TABLE " + TABLE_SECOND_LIST +
" ( "+COLUMN_ID_2 + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_SECOND + " TEXT NOT NULL )";

Hilfreich?
Diskutiere mit!

Empfohlene Artikel