cursorindexoutofboundsexception

  • Hi alle zusammen,


    ich bin gerade dabei mir eine Datenbank für eine Fussballmannschaft anzulegen.
    Da ich das das erste Mal mache, habe ich das mit diesem Tutorial gemacht:
    http://www.youtube.com/watch?v=7vPCmJn_XFk
    Ich habe eientlich alles so gemacht wie im Tutorial aber ich kriege eine "android.database.CursorIndexOutOfBoundsException Index 0 requested, with a size of 0" Exception.
    Hier mein Code:


    Sieht jemand einen Fehler?
    Für eure Hilfe bin ich sehr dankbar!
    Gruß


    M3doXX

  • Du hast zwar nicht geschrieben, wo der Fehler auftritt, aber ich tippe mal auf die Methode createEntryPlayer - dort machst du zwar moveToFirst, aber du hast nicht geschaut, ob überhaupt etwas im Cursor drin ist. Das sagt nämlich die Fehlermeldung: du willst auf den Eintrag mit der Nummer 0 zugreifen, es sind aber gar keine Einträge da...


    Komischerweise passiert das, nachdem eigentlich der Insert gelaufen sein sollte - ist die Datenbank überhaupt mit den Feldern angelegt?


    Was hat die insertId für einen Wert? Sollte eigentlich eine kleine positive Zahl sein...


    Du kannst vor dem moveToFirst noch einbauen:

    Java
    if (cursor.getCount() == 0) {
    	Log.w("PlayerDataSource.createEntryPlayer()","keine Daten gefunden");
    	return null;
    }


    Dann bekommst du zwar woanders eine NullPointerException - aber du solltest vor allem schauen, was mit der Datenbanktabelle los ist...

  • Ich weiß auch nicht genau wo der Fehler auftritt, aber ich habe deinen Codeschnipsel vor den beiden moveToFirst-Zeilen eingefügt und der Fehler ist weg.
    Jetzt hab ich allerdings das nächste Problem. Beim Klick auf den Button zum speichern geschieht nichts, bzw es wird nichts angezeigt.
    Also entweder funktioniert das Speichern nicht oder das Anzeigen. Ich hänge das Anzeigen auch mal dran, vielleicht sieht ja jemand einen Fehler...


    Team.java


    Das ist also die Activity, in der die Tabelle in einer ListView ausgegeben werden soll.
    Und da noch die Frage war ob die Tabelle überhaupt angelegt wurde, hänge ich den Teil auch nochmal dran:


    MySGLiteHelper.java:



    Also weiß jemand obs am Speichern oder am Ausgeben liegt?

  • Da du sowieso keine Daten in der Datenbank hast - zumindest siehst du keine - sollten wir die Datenbank einfach mal neu anlegen (dafür gibt's ja Upgrade).


    Aber Vorsicht: du hast im onUpgrade einen Fehler in der DROP TABLE: da muss PLAYER stehen statt SCANITEM...


    Und im create table schreibe bitte _id statt ID - so hat SQLite es lieber.


    Jetzt kannst du die DATABASE_VERSION auf 2 setzen und die App neu starten.


    Und dann schau dir bitte die Log-Ausgaben an, dort solltest du die Warnmeldung "Upgrading database from version 1 to 2, ..." sehen.


    Und wenn der Datensatz dann gelesen werden soll, müsste die Warnung und "keine Daten gefunden" im Log stehen.

  • Also ich hab jetzt nochmal ausgeführt und der Log sagt mir das die Meldung "keine Daten gefunden" aus der PlayerDataSource.java kommt.
    Das heißt das der Cursor immer noch falsch ist. Die Meldung kommt von dem Code-Schnipsel den UweApps als erstes gepostet hat!
    Hier nochmal der gesamte Code aus der PlayerDataSource.java:



    Was mache ich falsch?
    Übrigens: Das mit dem ID auf _id ändern hat nicht ganz geklappt, danach hat er eine Fehlermeldung ausgegeben, deshalb habe ich erstmal noch das ID beibehalten.
    Gruß


    M3doXX

  • OK, dann fällt mir noch was anderes ein: du speicherst und lädst gleich nacheinander - vielleicht hat Android da im Hintergrund aber noch nicht alles wirklich gespeichert.


    Kannst du die Warnmeldung noch mal etwas erweitern, dann wissen wir wenigstens, ob gespeichert wurde oder nicht:

    Java
    Log.w("PlayerDataSource.createEntryPlayer()","keine Daten gefunden, ID=" + insertId);


    Wenn dort -1 steht, ist nichts gespeichert worden, dann muss irgendwas mit der Datenbank falsch sein.


    Aber ich hoffe mal, dass du eine kleine Zahl angezeigt bekommst, dann wurde nämlich gespeichert, aber die Daten sind noch nicht wieder zum Lesen bereit.
    In diesem Fall empfehle ich dir, die Daten nicht gleich nach dem Speichern wieder zu laden.
    Versuch das doch mal mit 'nem OnClickListener auf irgendeinem View-Element.


    *däumchendrück*

  • OK - also bei -1 kommt garantiert auch kein Datensatz raus, denn die ID sollte eigentlich nicht erscheinen.


    Einen Fehler hab ich gefunden, bitte entscheide dich, ob du MAIL oder EMAIL als Feldname verwendest. ;)


    Aber daran kann es eigentlich nicht liegen, denn er sollte dir trotzdem den Datensatz speichern - denke ich mal.


    Schauen wir uns mal das create table an.
    Die SQLiteDB-Doku empfiehlt folgende Feldtypen: TEXT, NUMERIC, INTEGER, REAL, NONE - kannst du bitte in deinem create-Statement die Typen in Großbuchstaben schreiben und INTEGER statt int (obwohl es eigentlich auch so funktionieren sollte, aber versuchen kann man es ja mal).


    Außerdem empfehle ich noch mal dringend, _id als Feldname zu verwenden, auch Android empfiehlt das und es gibt sogar die Konstante BaseColumns._ID (mit dem Inhalt "_id") um die Bedeutung mal klar hervorzuheben...


    Auch das CREATE TABLE und PRIMARY KEY AUTOINCREMENT darf gerne in Großbuchstaben.


    Und dann noch mal die Datenbankversion hochsetzen und genau schauen, ob es bei der Warnmeldung zum DB-Upgrade noch irgendwelche anderen Meldungen von der Datenbank gibt.


    Ich drücke weiter die Daumen!!!

  • So habe nochmal alle deine Ideen ausprobiert und es gibt eine gute Nachricht und eine schlechte!
    Die Gute: Es scheint jetzt zu funktionieren mit dem Speichern
    Die Schlechte: Ich kriege eine Fehlermeldung wegen der ID.
    Eine android.database.sqlite.SQLiteExeption: No such column ID, while compiling [...] WHERE ID=3.
    Es scheint zu funktionieren nur er findet die ID Zeile nicht mehr weil ich sie in _id umbenannt habe.
    Gibt es eine Möglichkeit die Datenbank einmal komplett zurückzusetzen? Also das ich auch die Datenbankversion wieder auf "1" setzten kann?
    Ich bin nämlich schon bei Version "4".
    Aber erstmal ein riesiges Dankeschön bis hierhin, UweApps!!!!
    Gruß


    M3doXX


    Edit: Habe das ID Problem gelöst. Jetzt kommt ein "Bad request for field slot 0,5. numRows = 1, numColumns = 5
    Es ist doch echt verhext...

  • Du musst natürlich auch in deinen Abfragen das "ID" ersetzen durch "_id" - die Spalte ID gibt es ja nicht mehr. Aber das hast du ja wohl schon gelöst.


    Nun meckert er wegen der Abfrage - da muss doch in den Log-Ausgaben eine Zeile drin sein, die sich auf deine App bezieht und da steht eine Zeilennummer.
    Wenn du dort doppelt klickst, dann kommst du an die Zeile, wo das Problem liegt.


    Aber ich glaub, ich weiß schon wo das Problem liegt: du hast in der Definition von allColoumns das Feld "_id" vergessen!!! :P


    Und wenn du dann auf den Cursor zugreifst, gibt es keine 5. Spalte...


    Diesmal drück ich keine Daumen - die sind schon ganz rot... *lol*

  • So jetzt ist der Fehler auch weg, aber wenn ich auf Speichern klicke geschieht nichts...
    Ich weiß nicht ob es gespeichert wird oder nicht, da in der "Ausgabe" nichts sehe...
    Ich hänge nochmal die aktualisierten Dateien an:
    MySQLiteHelper.java:


    PlayerDataSource.java:


    Add_Player.java



    Ausgabe in Team.java:



    Also ich bin echt am verzweifeln hier^^
    Aber nochmals Allerbesten Dank für deine geduld UweApps!!!

  • Stimmt - du solltest die Ausgabemeldung noch mal etwas erweitern, dann weißt du mehr:


    Java
    if (cursor.getCount() == 0) {
    	Log.w("PlayerDataSource.createEntryPlayer()","keine Daten gefunden, ID=" + insertId);
    	return null;
    } else {
    	Log.v("PlayerDataSource.createEntryPlayer()","Daten gefunden, ID=" + insertId);
    }


    Nun solltest du auf jeden Fall eine Meldung bekommen - und endlich mal die kleinen Zahlen sehen, auf die wir schon so lange warten. ;)


    Ich hab den Code immer noch nicht in ein eigenes Projekt eingebaut, darum stochere ich etwas rum - aber du lernst vielleicht auch was dabei.


    Der nächste Schritt wäre dann ein Schritt, den wir schon hatten: mach dir mal einen onClickListener auf ein View-Element und versuche dort, den Datensatz auszulesen. Wenn du genug Log-Meldungen im Code verteilt hast, dann solltest du was sehen...

  • OK es sieht ganz gut aus...Er gibt im Log aus: Daten gefunden, ID=16 ;)
    Dann liegt es wohl an meiner Ausgabe Team.java...

    Zitat

    Der nächste Schritt wäre dann ein Schritt, den wir schon hatten: mach
    dir mal einen onClickListener auf ein View-Element und versuche dort,
    den Datensatz auszulesen. Wenn du genug Log-Meldungen im Code verteilt
    hast, dann solltest du was sehen...

    Ich weiß noch nicht genau was du damit meinst...

  • Du kannst z.B. den addplayer.setOnClickListener erweitern und dort bevor du den Intent startest.


    Aber ich hab noch eine bessere Idee: eigentlich sollte da ja was in ListTeam passieren - bau doch dort mal ein oder zwei Log-Ausgaben rein und lass dir PlayerList.size() anzeigen - dann weißt du, wie viele Datensätze gespeichert sind.
    Dann kannst du mal die Log-Ausgabe anpassen und mal einzelne Daten ausgeben - nur mal zum testen...


    Wenn da was drin sein sollte, dann müßte dein ListView das ja hoffentlich auch anzeigen.


    Und schau noch mal nach, wo das ListTeam aufgerufen wird - da hab ich nämlich nichts gefunden - im onCreate könntest du das eintragen.

  • Ich kriegs nicht gebacken...
    Das PlayerList.size() wollte ich durch einen Toast ausgeben, funktioniert aber nicht.
    Die ListTeam rufe ich nun in der onCreate auf, wobei ich nicht genau wusste welcher Parameter darein gehört...
    Bin also noch auf dem Stand wie vorher...
    Hier der abgewandelte Code:


  • So ich bin jetzt wieder einen Schritt weiter aber noch nicht am Ziel ^^
    Also der Toast gibt aus "android.content.res.Resources$NotFoundExeption:StringresourceID#0x14"
    Aber in der listView wird jetzt was angezeigt! Das ist ja schonmal ein Fortschritt ;) Allerdings werden nur Einträge wie dieser angezeigt: "manager.scg.Entry@405b9cb0"
    Ein weiterer Forschritt: Wenn ich etwas speichere, dann gibt er im Log aus: "Daten gefunden, ID=21"
    Wenn jetzt noch aus diesem "manager.scg.Entry@405b9cb0" meine Eingaben werden dann bin ich vorerst da wo ich hinwollte ;)

  • Wieso findet der denn eine String-Resource nicht? Hmm. Mach doch noch mal Project - Clean...


    Aber die Daten sind schon mal da und 21 Datensätze sind ja auch schon mal was.


    Die komische Ausgabe passiert, weil du ein Objekt ausgibst und nicht den Inhalt des Objekts. Allerdings weiß ich nicht, warum das ein manager.scg ist...


    Aber im Adapter musst du was ändern: da schreibst du Team.this - schreibe stattdessen mal PlayerList - denn die Daten willst du ja ausgeben, oder?? ;)

  • Project -clean hat nichts gebracht..
    Und wenn ich PlayerList anstelle von team.this einfüge dann kriege ich einen "The constructor ArrayAdapter<Entry>(List<Entry>, int, List<Entry>) is undefined" Fehler...
    Achja: und manager.scg ist mein package...weiß nicht ob dir das weiterhilft?!


    EDIT: Ich bin fast am Ziel meiner Träume ;)
    Ich habe festgestellt, dass ich aus dem Tutorial -warum auch immer- eine Methode vergessen habe undzwar die toString():


    Java
    @Override
    	public String toString() {
    		
    		return String.format("%s %s %d", name, lastname, _id);
    	}


    Das einzige Problem ist das er anstatt den Strings name und lastname nur "null" ausgibt. Die _id wird richtig ausgegeben in der listView...
    Woran kann das liegen das er mir die integers ausgibt aber die Strings nicht???

  • naja - dann werden name und lastname wohl leer sein, denke ich mal.


    Ich hab deine Klasse Entries im Visier, die hab ich aber hier noch nicht gesehen.


    Aber du lädst die Daten vom Cursor mit entry.setName() etc. - gibt es auch entry.getName()??? Das könnte dir helfen...


    Oder sind tatsächlich keine Daten gespeichert worden - das kannst du im createEntryPlayer() ja mal mit einem kleinen Log.v() rausfinden...
    Vielleicht hast du die Daten ja gar nicht aus den Eingabefeldern ausgelesen. O:-)

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!