Import einer Datenbank & in einer Datenbank hinterlegtes Bild anzeigen

  • 14 Antworten
  • Letztes Antwortdatum
T

Tippvehler

Neues Mitglied
1
Hallo zusammen,
ich bin daran ein Quiz zumachen und hab die ersten Codes zusammen aber da fehlt noch einiges und ich komme einfach nicht dahintert.
Ich hab den Code von DeveloperFeed | A Simple Quiz Game in Android genommen.

Zu meinen Fragen:
1. Wie kann ich eine Datenbank oder CSV datei in die App einlesen. Was schlagt ihr vor, eine sql Datenbank oder aus Excel eine CSV Datei importieren?
2. Wie kann ich in der Datenbank sagen bei dieser Frage gehört ein Bild dazu?
3. Wie kann ich sagen wenn ein Bild zu dieser Frage vorhanden ist, dann soll diese .xml Datei aufgerufen werden, sonst die andere?
4. Ich würde gerne eine Menü machen, das die verschiedenen Themen untereinander aufgelistet hat und wenn man auf ein Thema klickt, dass dann ab der bestimmten Zeile in der Datenbank oder mit einem Themen-Tag die gewünschten Fragen aufruft


Ich stöbere jetzt seit 2 Tagen im Internet nach Lösungen .... vorallem für das Importieren bin ich einfach zu Blöd =?

Ps.: Ich bin Anfänger
 
Ok. Ich habe mir die Seite mal angesehen.
Ich finde die Implementierung für ein Tutorial sehr gut strukturiert.
Jetzt meine Frage:
Verstehst du denn auch, was da gemacht wurde? Also wofür das Frageobjekt da ist?

Wenn ja, dann beantworte ich dir die Fragen:
1. Also es funktioniert auch eine Datenbank, aber ich würde eher die CSV-Datei nehmen, damit die Datenbankeigenschaften nicht verloren gehen.
Diese CSV kannst du entweder über die Ressourcen oder über das Netz laden.
Einlesen geht dann wie in normalem Java über einen BufferedReader etc.

2. Dann musst du der Datenbanktabelle eine Spalte hinzufügen. Ich speichere normalerweise den Pfad oder den Namen der Datei in einer Tabelle. Von BLOBs halte ich nicht viel. Vergiss hier nicht, auch deine Klasse upzudaten.

3. Es kommt zwar auf deine XML an, und wo du sie aufrufen willst. Ich würde aber eigentlich die Activity separieren und dann jeweils eine andere Activity anzeigen, wenn ein Bild dabei ist. Oder einfach durch Aus- und Einblenden die GUI manipulieren.
Wenn du es so nicht machen möchtest, dann schau mal wie das "Inflaten" funktioniert.

4. Dann füg doch deinem Objekt und deiner Datenbanktabelle noch ein Feld "Thema" hinzu. Nach diesen Themen kannst du dann mittels SQL-Query selektieren.

Leider zeigen deine Fragen, dass du blutiger Anfänger bist. Das soll dich natürlich nicht abhalten hier Fragen zu stellen, aber oft kommt man mit den Antworten dann auch nicht viel weiter. Ich hoffe aber, du kannst mit meinen Antworten was anfangen.
 
  • Danke
Reaktionen: Tippvehler
Danke schon mal für die Antworten, jetzt habe ich wenigstens neue Anhaltspunkte.

Ganz ehrlich, ich versteh einiges aber nicht alles. Ich habe dieses Java-Tutorial durch gemacht und bin bis zum 6 Kapitel gekommen. Es hat zwar geheißen ich soll bis Kapitel 9 mich durch arbeiten, damit ich mit Android anfangen kann.
Wenn ich es richitg verstanden habe sind das die Frage-Objekte:

private int ID;
private String QUESTION;
private String OPTA;
private String OPTB;
private String OPTC;
private String ANSWER;


diese Speichern den Wert der Frage damit man sie auslesen kann bzw einlesen.


1. Ich hab den Import schon mit verschiedenen Codes probiert aber es will einfach nicht ...

Code:
Klasse DbHelper

private void addQuestions()
    {
     

        InputStream is;
        try{
        AssetManager assets = mCtx.getAssets();
        is = assets.open("test1.csv");
        BufferedReader buffer = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        String line = "";
        String tableName ="DATABASE_NAME";
        String columns = "KEY_ID, KEY_QUES, KEY_ANSWER, KEY_OPTA, KEY_OPTB, KEY_OPTC";
        String str1     = "INSERT INTO " + tableName + " (" + columns + ") values(";
        String str2 = ");";
        String str3 = "this.addQuestion(qcount);";

        dbase.beginTransaction();
        while ((line = buffer.readLine()) != null) {
         
            StringBuilder sb = new StringBuilder(str1);
            String[] str = line.split(";");
            sb.append("'" + str[0] + "',");
            sb.append("'" +str[1] + "',");
            sb.append("'" +str[2] + "',");
            sb.append("'" +str[3] + "',");
            sb.append("'" +str[4] + "',");
            sb.append("'" +str[5] + "'");
            sb.append(str2);
            sb.append(str3);
            // Das sollte das ergebnis sein: Question q1 = new Question ('text0','text1','text2','text3','text4','text5'); this.addQuestion(q1); ich komme einfach nicht drauf wie ich das richitg umschreibe ...
            dbase.execSQL(sb.toString());
        }
        dbase.setTransactionSuccessful();
        dbase.endTransaction();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2. Reicht es wenn ich den Pfad in der Spalte einfach so einspeicher (data/data/Package-Name/assets/bild1 (png-format oder?))??

3. Also im groben:
Code:
if (Picture != Null || Picture.lenght() != 0) {
Intent myIntent = new Intent(???.this, QuizActivity.class);
startActivity(myIntent);
}
else {
Intent myIntent2 = new Intent(???.this, QuizPicActivity.class);
startActivity(myIntent2);
}

In welche Activtiy muss ich den das einfügen =?
Hoffe ich hab mich hier nicht grad blamiert ^^

4. Hab ich schon gelöst, trotzdem danke :) Ich hab vergessen die Datenbank zu Updaten und darum kamm dann immer ein Fehler ^^

Ich weiß und ich frage auch nicht gern ... aber ich kann mit dem bisschen was du mir jetzt gesagt hast, einfach schon nur nach neuen ideen Suchen, weil ich jetzt weiß nach was.

Lg Tippvehler
 
Tippvehler schrieb:
Wenn ich es richitg verstanden habe sind das die Frage-Objekte:

private int ID;
private String QUESTION;
private String OPTA;
private String OPTB;
private String OPTC;
private String ANSWER;




Nein, das sind die Klassenvariablen, Membervariablen, Properties oder wie sie sonst noch heißen.

Die Klasse heißt Question und aus der Klasse erstellt man Questionobjekte.

Tippvehler schrieb:
1. Ich hab den Import schon mit verschiedenen Codes probiert aber es will einfach nicht ...

Code:
Klasse DbHelper

private void addQuestions()
    {
    

        InputStream is;
        try{
        AssetManager assets = mCtx.getAssets();
        is = assets.open("test1.csv");
        BufferedReader buffer = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        String line = "";
        String tableName ="DATABASE_NAME";
        String columns = "KEY_ID, KEY_QUES, KEY_ANSWER, KEY_OPTA, KEY_OPTB, KEY_OPTC";
        String str1     = "INSERT INTO " + tableName + " (" + columns + ") values(";
        String str2 = ");";
        String str3 = "this.addQuestion(qcount);";

        dbase.beginTransaction();
        while ((line = buffer.readLine()) != null) {
        
            StringBuilder sb = new StringBuilder(str1);
            String[] str = line.split(";");
            sb.append("'" + str[0] + "',");
            sb.append("'" +str[1] + "',");
            sb.append("'" +str[2] + "',");
            sb.append("'" +str[3] + "',");
            sb.append("'" +str[4] + "',");
            sb.append("'" +str[5] + "'");
            sb.append(str2);
            sb.append(str3);
            // Das sollte das ergebnis sein: Question q1 = new Question ('text0','text1','text2','text3','text4','text5'); this.addQuestion(q1); ich komme einfach nicht drauf wie ich das richitg umschreibe ...
            dbase.execSQL(sb.toString());
        }
        dbase.setTransactionSuccessful();
        dbase.endTransaction();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



Dein Ansatz gefällt mir nicht. Du erstellst eine App nach einem Tutorial. Diese sollte auch funktionieren. Dann fügst du aber nicht nur Variablen hinzu. (Was bei dir ja schon reichen würde). Sondern kopierst einfach Code aus dem Netz in die vorhandene Implementierung ein. Warum benutzt du nicht die Methode aus dem Tutorial?

Code:
// Adding new question
public void addQuestion(Question quest) {
//SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_QUES, quest.getQUESTION());
values.put(KEY_ANSWER, quest.getANSWER());
values.put(KEY_OPTA, quest.getOPTA());
values.put(KEY_OPTB, quest.getOPTB());
values.put(KEY_OPTC, quest.getOPTC());
// Inserting Row
dbase.insert(TABLE_QUEST, null, values);
}

Tippvehler schrieb:
2. Reicht es wenn ich den Pfad in der Spalte einfach so einspeicher (data/data/Package-Name/assets/bild1 (png-format oder?))??

Also ich würde es in Android ohne data/data abspeichern. Den Pfad bekommt man ja durch Methoden raus: (z.B.: getExternalFilesDir() )

Tippvehler schrieb:
3. Also im groben:
Code:
if (Picture != Null || Picture.lenght() != 0) {
Intent myIntent = new Intent(???.this, QuizActivity.class);
startActivity(myIntent);
}
else {
Intent myIntent2 = new Intent(???.this, QuizPicActivity.class);
startActivity(myIntent2);
}

In welche Activtiy muss ich den das einfügen =?

In der, von der du die anderen Ansichten anzeigen willst.
Wenn es vom Menü aus gehen soll, dann im Menü. Wenn du verschiedene Frageformen über "next" anzeigen lassen willst, dann darüber.
 
  • Danke
Reaktionen: Tippvehler
achso ok.

1. Warum ich nicht die Methode aus dem Tutorial benutze? Weil ich bis jetzt nicht wusste, dass ich es für das Einlesen einer Datei auch verwenden kann.
Ich dachte diese Methode beschränkt sich darauf nur im Code enthaltene Fragen zu speichern. Wenn du mir jetzt noch sagen kannst wie ich die CSV-Datei importiere mit dem Code dann würde ich dich schon nicht mehr länger nerven :s

2/3. Danke das hilft mir schon sehr :D
 
Wie sieht deine CSV-Datei denn aus? Also die ersten zwei Zeilen mit anonymen Daten reicht aus.

Ich würde den Import in der Activity durchführen und dann dem DB-Helper die Daten pro Zeile mitgeben um es zu speichern.
 
Ich hab noch keine Datei erstellt, weil ich noch nicht wusste ob sql oder csv.

Aber so sieht sie aus, wenn ich sie in Excel als CSV-Datei speichere:
ID, KATEGORIE, FRAGE, OPTA, OPTB, OPTC, ANTWORT, BILDPFAD (Hab immer noch nicht verstanden wie ich den einfügen soll ...)

1;Infos;Wie heiße ich?;Manfred;Hans;Tippvehler;Tippvehler; Bild1
2;Tätigkeit;Was probier ich gerade?;Eine App zumachen; Essen; Malen; Eine App zumachen; null


Für den Import brauche ich aber doch immer einen eigenen/neuen Code?



Edit:

Wenn ich die Auswahl welche Activity gestartet werden soll, mit Bild/ohne Bild, über den Next-Buttton mache, kommt erst beim nächsten mal beim drücken des Buttons das "Bild".
Hab mir ne LogCat ausgabe gemacht und die sieht folgender maßen aus:

Start der QuizActivity ( Die erste Frage muss nach diesem Prinzip immer ohne Bild sein)
Question q1=new Question("Geräte- und Taktiklehre","Which of the following device", "Router", "Bridge", "Hub","Router", "");
Klick auf den Next-Button
LogCat: Picture
Question q2=new Question("Geräte- und Taktiklehre","Which of the following device", "Router", "Bridge", "Hub","Router","a");
Hier währe eig das Bild, aber es wird noch nicht ausgegeben.
Klick auf den Next-Button
LogCat: Picture a
Question q3=new Question("Geräte- und Taktiklehre","Which of the following device", "Router", "Bridge", "Hub","Router","");
Hier kommt jetzt bei der Ausgabe von LogCat das Bild vor aber die Frage beinhaltet kein Bild mehr.


Wo soll ich jetzt die Abfrage einbauen?
 
Zuletzt bearbeitet:
Hi,

ok.. wir müssen noch ein wenig weiter zurück gehen.
Die CSV sieht ja schon gut aus. Jetzt müsstest du mir sagen, wo du die Bilder hinlegen willst, damit sie dann in der App angezeigt werden können.

Willst du sie auch im Assets-Ordner ablegen? Willst du sie in den drawable-Ordner ablegen?
Müssen sie updatebar sein über das Netz?

Zu deiner zweiten Frage:
Ich kenne dein Layout nicht, aber wenn du es immer noch so machen würdest wie im Tutorial, dann ersetzt du ja normalerweise nur die Texte.

Code:
private void setQuestionView()
{
txtQuestion.setText(currentQ.getQUESTION());
rda.setText(currentQ.getOPTA());
rdb.setText(currentQ.getOPTB());
rdc.setText(currentQ.getOPTC());
qid++;
}

Dann würde der Ansatz mit den Activities nicht gehen.
Du könntest jetzt dein Layout so ändern, dass es Platzhalter für Bilder hat, und diese nur befüllt werden, wenn auch ein Bild in der Frage da ist:

Code:
private void setQuestionView()
{
txtQuestion.setText(currentQ.getQUESTION());
rda.setText(currentQ.getOPTA());
rdb.setText(currentQ.getOPTB());
rdc.setText(currentQ.getOPTC());

if(currentQ.getImage() != null)
{
imageView.setResource(currentQ.getImage()) //Ich weiß nicht mehr, wie es korrekt aufgerufen wird
imageView.setVisibility(View.VISIBLE);
}
else
{
imageView.setVisibility(View.GONE);
}

qid++;
}

(Der Code ist ungetestet)
 
  • Danke
Reaktionen: Tippvehler
Ich würde es gerne über den drawable-Ordner machen.
Nein übers Netz mache ich garnichts. (Das kann ich dann mal machen, wenn ich nicht mehr so ein Blutiger Anfänger bin ^^)

Ja ist noch immer alles gleich wie im Tutorial außer den 2 neuen Objekten.

Werde es gleich mal ausprobieren, melde mich dann noch mal

LG Tippvehler

Edit:

Ich habs hinbekommen mit diesem Code:
Code:
    if(currentQ.getPICPATH() != 0)
        {
           
        iv.setImageResource(currentQ.getPICPATH());
        iv.setVisibility(View.VISIBLE);
        }
        else
        {
        iv.setVisibility(View.GONE);
        }

        qid++;
        }

wobei bei mir das IMAGE, PICPATH heißt.

das darauf folgende Problem war das ich alles auf Int ändern musste (wegen R.drawable.bild1) und jetzt die put methode nicht mehr funktioniert.

Code:
       values.put(KEY_OPTC, quest.getOPTC());
        values.put(KEY_PICPATH, quest.getPICPATH()); //Hier kommt der Fehler, das es ein String sein muss.
        dbase.insert(TABLE_QUEST, null, values);

Dann habe ich ein bisschen im Internet gesucht und gelesen, dass mann das:
public static final int KEY_PICPATH = 0;
in einen String zurück machen soll:
public static final String KEY_PICPATH = "picpath";

jetzt wird die put Methode zwar nicht mehr als Fehler angezeigt aber hier will er alles in einen String umwandeln ... was soll ich da tun?

Code:
               quest.setOPTC(cursor.getString(6));
                quest.setPICPATH(cursor.getString(7)); // sagt mir ich soll die Set-MEthode in einen String abändern
                quesList.add(quest);
 
Zuletzt bearbeitet:
Ok. Drawable Ordner.
Bitte bedenke, dass du eigentlich die Größen berücksichtigen musst. Also ein Bild mdpi, eins hdpi etc.

Jetzt würde ich an deiner Stelle den Namen des Bildes in den DrawableOrdnern in der Datenbank speichern:

PICPATH ist dann ein String.
Beim Erstellen eines Objekts nimmst du dann den Namen:
new Question(...,...,...,..., "bild1.png")

Beim setzen in die ImageView suchst du das Bild erstmal mittels des Contexts:
java - setImageResource from a string - Stack Overflow

Dann kannst du es setzen. Wie im Link gezeigt.
Ich bin mir jetzt unsicher, ob mit .png oder ohne. Kannst es ja mal einfach versuchen.
 
  • Danke
Reaktionen: Tippvehler
wäre es leichter im Assets-Ordner?

Funktionier alles :D
Ohne .png, falls es dich interessiert :)

Aber wie ist das jetzt mit dem Import?
 
Zuletzt bearbeitet:
Ungetestet und wenig Zeit:

In deiner Activity:


Code:
DbHelper db=new DbHelper(this);

InputStream is;
        try{
        AssetManager assets = mCtx.getAssets();
        is = assets.open("test1.csv");
        BufferedReader buffer = new BufferedReader(new InputStreamReader(is, "UTF-8"));

        while ((line = buffer.readLine()) != null) {
      
          
            String[] str = line.split(";");
            Question newQuestion = new Question(str[0],str[1],str[2],str[3],str[4],str[5]);
            db.addQuestion(newQuestion);
        }

        } catch (IOException e) {
            e.printStackTrace();
        }
 
  • Danke
Reaktionen: Tippvehler
ok vielen Dank

Edit:

Muss leider wieder stören... weiß nicht was ich falsch mache bzw. woher der Context kommen muss
Code:
package com.example.triviality;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;

import com.example.triviality.R;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView; 


public class QuizActivity extends Activity {
    List<Question> quesList;
    int score=0;
    int qid=0;
    int questlength=7;
    Question currentQ;
    TextView txtQuestion,txtCategory;
    RadioButton rda, rdb, rdc;
    Button butNext;
    ImageView iv;
   
   //------------------------------- Muss das hier hin? ------------------------------------------
    DbHelper db= new DbHelper(this); //Darf das schon 2x vorkommen?
    String line="";
    InputStream is;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

//---------------------------Methode mit deinem Code----------------------------

        importQuest();
      
      
        setContentView(R.layout.activity_quiz);
        DbHelper db=new DbHelper(this);
        quesList=db.getAllQuestions();
        currentQ=quesList.get(qid);
        txtCategory=(TextView)findViewById(R.id.textView2);
        txtQuestion=(TextView)findViewById(R.id.textView1);
        rda=(RadioButton)findViewById(R.id.radio0);
        rdb=(RadioButton)findViewById(R.id.radio1);
        rdc=(RadioButton)findViewById(R.id.radio2);
        butNext=(Button)findViewById(R.id.button1);
        iv=(ImageView)findViewById(R.id.flag1);
        setQuestionView();
      
        butNext.setOnClickListener(new View.OnClickListener() {      
            @Override
            public void onClick(View v) {
                RadioGroup grp=(RadioGroup)findViewById(R.id.radioGroup1);
                RadioButton answer=(RadioButton)findViewById(grp.getCheckedRadioButtonId());
                Log.d("yourans", currentQ.getANSWER()+" "+answer.getText());
                if(currentQ.getANSWER().equals(answer.getText()))
                {
                    score++;
                    Log.d("score", "Your score"+score);
                }
                if(qid<questlength){                  
                    currentQ=quesList.get(qid);
                    setQuestionView();                  
                }else{          
                    Intent intent = new Intent(QuizActivity.this, ResultActivity.class);
                    Bundle b = new Bundle();
                    b.putInt("score", score); //Your score
                    intent.putExtras(b); //Put your score to your next Intent
                    startActivity(intent);
                    finish();
                }
            }
        });
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_quiz, menu);
        return true;
    }
    private void setQuestionView()
    {
        txtQuestion.setText(currentQ.getQUESTION());
        txtCategory.setText(currentQ.getCATEGORY());
        rda.setText(currentQ.getOPTA());
        rdb.setText(currentQ.getOPTB());
        rdc.setText(currentQ.getOPTC());
      
        if(currentQ.getPICPATH().length() != 0)
        {
      
        iv.setImageResource(getImageId(this, currentQ.getPICPATH()));  
        iv.setVisibility(View.VISIBLE);
        }
        else
        {
        iv.setVisibility(View.GONE);
        }

        qid++;
        }
  
    public static int getImageId(Context context, String imageName) {
        return context.getResources().getIdentifier("drawable/" + imageName, null, context.getPackageName());
    }
  
    public void importQuest(){
      
        try{

//-------------------------- hab den Context weg gelassen, da mit Context vor dem einlesen der File eine 
// NullPionterException kam und ohne Context erst in der Schleife ----------------------------------

            AssetManager assets = getAssets();
            is = assets.open("test1.csv");
            BufferedReader buffer = new BufferedReader(new InputStreamReader(is, "UTF-8"));
      
            while ((line = buffer.readLine()) != null) {
       
           
                String[] str = line.split(";");
                Question newQuestion = new Question(str[1],str[2],str[3],str[4],str[5],str[6],str[7]);
                db.addQuestion(newQuestion);
  
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        }
  
  
}
 
Zuletzt bearbeitet:
Hi,

da du die Fehlermeldung hier nicht reingeschrieben hast, weiß ich nicht wo der Fehler ist. Hast du einen assets-Ordner erstellt und dort die Datei eingefügt?
Du kannst ja noch die anderen Varianten ausprobieren: Android path to asset txt file - Stack Overflow

Ich bin heute ab 12:00 Uhr im Urlaub und werde dir dann nicht mehr weiterhelfen können.
 
Habs mit dem Import aufgegeben, will einfach nicht.

Danke noch mal für alles :)
Schönen Urlaub
 
Zurück
Oben Unten