1. Nimm jetzt an unserem Uhans - 3. ADVENT - Gewinnspiel teil - Alle Informationen findest Du hier!

SQLite-Query Ergebnis an ListView

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von Patwerk, 14.10.2010.

  1. Patwerk, 14.10.2010 #1
    Patwerk

    Patwerk Threadstarter Neuer Benutzer

    Beiträge:
    16
    Erhaltene Danke:
    0
    Registriert seit:
    10.10.2010
    Hallo zusammen,

    ich häng hier an einem Problem bezüglich eines SQLite-Query Ergebnisses. Ich möchte mein Abfrage-Ergebnis, welches ich in einem Cursor speichere, an eine Liste binden, bin mir aber nicht sicher, ob, und wie es funktionieren kann.

    Hier mal mein Ansatz:
    Code:
    Cursor c = db.rawQuery("SELECT * FROM test_table", null);
    startManagingCursor(c);
    int Column1= c.getColumnIndex("Column1");
    int Column2= c.getColumnIndex("Column2");
    
    ListAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.two_line_list_item, c, new String[] {c.getString(Column1), c.getString(Column2)}, new int[] {android.R.id.text1, android.R.id.text2});
    setListAdapter(adapter);
    
    Der Ansatz kommt von dieser Seite:
    ListActivity | Android Developers

    Unter dem Absatz "BindingData" wird ebenfalls ein Cursor mit Daten gefüllt und dieser dann auf gleiche Art und Weise an einen ListAdapter gebunden:

    Code:
             mCursor = this.getContentResolver().query(People.CONTENT_URI, null, null, null, null);
             startManagingCursor(mCursor);
    
             // Now create a new list adapter bound to the cursor.
             // SimpleListAdapter is designed for binding to a Cursor.
             ListAdapter adapter = new SimpleCursorAdapter(
                     this, // Context.
                     android.R.layout.two_line_list_item,  // Specify the row template to use (here, two columns bound to the two retrieved cursor
     rows).
                     mCursor,                                              // Pass in the cursor to bind to.
                     new String[] {People.NAME, People.COMPANY},           // Array of cursor columns to bind to.
                     new int[] {android.R.id.text1, android.R.id.text2});
    setListAdapter(adapter);
    
    Bei mir wird aber immer folgende Exception gecatched:

    "java.lang.IllegalArgumentException: Empty bindArgs"

    Das müsste ja bedeutet, dass irgendwo versucht wird, etwas leeres zu binden.

    Weiß jemand, wo der Fehler ist, was ich anders machen könnte, oder eventuell einen ganz anderen Lösungansatz, wie ich es schaffen kann, ein Query-Ergebnis an eine Liste zu binden, sodass sich die Liste mit allen Zeilen aus dem Ergebnis füllt? (Vlt. auch nicht über ListView sondern allgemein, wie man ein SQLite Query-Ergebnis ordentlich anzeigen lassen kann.

    Viele Grüße,
    Patwerk
     
  2. enrem, 15.10.2010 #2
    enrem

    enrem Erfahrener Benutzer

    Beiträge:
    188
    Erhaltene Danke:
    13
    Registriert seit:
    17.01.2010
    Hier gibt es ein Beispiel!

    Schnipsel:RM Dictionary ? Android-Schnipsel-Wiki

    Hat deine Tabelle ein Feldattribut _id??? Wenn nicht erstelle mal eine Tabelle mit diesem Feldnamen.

    _id INTEGER PRIMARY KEY AUTOINCREMENT

    Ich glaube der Adapter oder die ListView erwartet solch ein Schlüsselfeld.

    Gruß enrem
     
    Patwerk bedankt sich.
  3. Patwerk, 15.10.2010 #3
    Patwerk

    Patwerk Threadstarter Neuer Benutzer

    Beiträge:
    16
    Erhaltene Danke:
    0
    Registriert seit:
    10.10.2010
    Hmm ne die Spalte hab ich gar nicht, werd ich gleich mal ausprobieren.
     
  4. enrem, 15.10.2010 #4
    enrem

    enrem Erfahrener Benutzer

    Beiträge:
    188
    Erhaltene Danke:
    13
    Registriert seit:
    17.01.2010
    Da bin ich mal gespannt...

    Gruß enrem
     
  5. Patwerk, 15.10.2010 #5
    Patwerk

    Patwerk Threadstarter Neuer Benutzer

    Beiträge:
    16
    Erhaltene Danke:
    0
    Registriert seit:
    10.10.2010
    Also, das mit der ID scheint wohl zu stimmen, aber der Fehler war ein anderer.

    Ich habe so versucht Daten in die Datenbank zu schreiben:

    Code:
    db.execSQL("INSERT INTO table (column1, column2)VALUES("bla", "gerät")");
    
    Das funktioniert aber nicht, denn man muss zum inserten die Methode der SQliteDatabase-Klasse ".insert(...)" benutzen. Das funktioniert auch, habe das nun mal so getestet, das ich mal den Cursor iteriert habe, und da steht auch was drin. Die Exception wird nun defenitiv an der Stelle geworfen, an der der Cursor an den ListAdapter dran geht, bekomme aber nun einen anderen Fehler.

    Hier nochmal der aktuelle Code:

    Code:
    SQLiteDatabase db;
                db = openOrCreateDatabase("TestDb.db", SQLiteDatabase.CREATE_IF_NECESSARY, null);
                db.execSQL("CREATE TABLE IF NOT EXISTS awTest" +
                        "(_id INTEGER PRIMARY KEY AUTOINCREMENT," +
                                "Name varhcar(50)," +
                                "Exp varchar(10))");
                ContentValues row = new ContentValues();
                row.put("Name", "clear");
                db.insert("awTest", "", row);
                Cursor c = db.rawQuery("SELECT * FROM awTest", null);
    
                startManagingCursor(c);
                int NameColumn = c.getColumnIndex("Name");
                int xpColumn = c.getColumnIndex("Exp");
    
                ListAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.two_line_list_item, c, new String[] {c.getString(NameColumn), c.getString(xpColumn)}, new int[] {android.R.id.text1, android.R.id.text2});
    
                setListAdapter(adapter);
    //            db.close();
    
    Exception:

    "android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1"

    hat also irwas mit der Cursorposition oder so zu tun. Funktioniert da an der stelle vlt "startmanagingcursor(c)" nicht richtig?

    Ich bin mal wieder überfragt^^

    Greets, PW:confused:
     
  6. enrem, 16.10.2010 #6
    enrem

    enrem Erfahrener Benutzer

    Beiträge:
    188
    Erhaltene Danke:
    13
    Registriert seit:
    17.01.2010
    Aus dem Stehgreif würde ich sagen du musst innen andere Hochkommas verwenden.

    Code:
    db.execSQL("INSERT INTO table ('column1', 'column2') VALUES('bla', 'gerät')");
    
    Ich habe es bei mir etwas anders gelöst. Keine Ahnung ob es dir reicht. Ich übergebe dem Adapter nur ein Feld "Auswahl". Dieses Feld erzeuge ich im SQL-String. Name und Exp setze ich mit Pipes zusammen. Der Pfeil ist optisch zum trennen.

    Code:
    initListView( "SELECT _id,  Name || ' -> ' || Exp AS Auswahl FROM awTest" );
    
    Code:
    
    private void initListView(String sql){
            
            // Abfrage erstellen. In cur ist das Ergebnis der Abfrage.
            Cursor cur = mDatabase.rawQuery(sql, null);
            
            if (cur != null) {
                startManagingCursor(cur);
                mAdapter = new SimpleCursorAdapter(this, R.layout.amp_load_list, cur,
                        new String[] { "Auswahl" }, new int[] { android.R.id.text1 });
                setListAdapter(mAdapter);
            }
        }
    
    mAdapter verwende ich im Code Private, wegen dem Requery. mAdapter.getCursor().requery(); Nach einer Änderung in der Tabelle soll sich die Listview ja aktualisieren.
     
  7. Patwerk, 18.10.2010 #7
    Patwerk

    Patwerk Threadstarter Neuer Benutzer

    Beiträge:
    16
    Erhaltene Danke:
    0
    Registriert seit:
    10.10.2010
    Hi,

    die ganze Sache hat sich erledigt. Der fehler lag woanders, und zwar bei:

    Code:
    db.execsql("INSERT INTO table(column1, column2) VALUES('1', '2')";
    
    das ist laut android framework gar nicht erlaubt. Anstatt dessen muss man die Klassen-Methode zum einfügen von daten benutzen:

    Code:
    ContentValues newRow = new ContentValues();
    newRow.put("ColumnName1", "Value");
    newRow.put("ColumnName2", "Value");
    db.insert("tablename", null, newRow);
    
    und dann der ListAdapter so wie ich ihn benutzt hatte nur beim 3. parameter, welcher ja die spalte aus dem cursor angibt muss man nicht
    Code:
    ..., new String[] {cursor.getstring(cursor.getcolumn("columnname"))},...
    
    sondern einfach den column Namen angeben

    Code:
    ..., new String[] {"columnname1"},...
    
    Aber danke dir trotzdem
     
  8. enrem, 18.10.2010 #8
    enrem

    enrem Erfahrener Benutzer

    Beiträge:
    188
    Erhaltene Danke:
    13
    Registriert seit:
    17.01.2010
    Komisch, ich habe mal ein Beispiel mit db.execsql("INSERT INTO table... usw. programmiert. Dort hatte es auch ohne die oben beschriebenen Methoden funktioniert.

    hier mein Testcode:

    Code:
    
    private boolean addRecord() {
    [FONT=verdana]    boolean success = false;
    
        // Datensätze einfügen
        success = execute("INSERT OR IGNORE INTO Tabelle1("+
                                             "'MyTextUnique','MyTextNotNull','New_Unique1','New_Unique2') "+
                                             "VALUES ('a','a','a','a')");
        if (success){
            Log.d("MyApp", "Kein Fehler mit INSERT OR IGNORE");
        }else{
            Log.d("MyApp", "Fehler mit INSERT OR IGNORE");
        }
    
        // Rückgabe -1 == Fehler, sonst die aktuelle ROWID
        long inserResult;
    
        // Noch besser geht das mit der richtigen Klasse :-)
        ContentValues values = new ContentValues();
        values.put("MyTextUnique", "b");
        values.put("MyTextNotNull", "b");
        values.put("New_Unique1", "b");
        values.put("New_Unique2", "b");
        inserResult = mDatabase.insert("Tabelle1", null, values);
    
        if (inserResult == -1){
            Log.d("MyApp", "Fehler mit inserResult in addRecord");
        }else{
            Log.d("MyApp", "Kein Fehler mit inserResult in addRecord");
        }
    
        return success;
    }
    [/FONT]
    
    Stimmt in meinem Beispiel unten hatte ich das ja so gemacht. Ist mir bei dir allerdings nicht aufgefallen.

     
    Zuletzt bearbeitet: 19.10.2010

Diese Seite empfehlen