Beiträge von UweApps

    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.

    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 kanns nicht lassen, da mal zurückzuargumentieren... *liebguck*


    Zum Glück ist die SQLiteDB recht tolerant, was den Umfang von INTEGER betrifft - long passt da problemlos rein.


    Und weil ich weiß, dass die interne Darstellung bei Java (und Unix, Perl, C++) immer ein long ist, plädiere ich für INTEGER.


    Außerdem ist die Datenbank von Marco ja nicht für die Öffentlichkeit, oder??


    Sorry - bin halt Ingenieur und darum mehr Praktiker als Theoretiker. *grinz*


    Aber ich muss dir recht geben, wenn ich mit anderen Datenbanken arbeite, wo auch mal andere Leute mit zu tun haben, benutze ich immer die DATETIME-Fields.


    *auchklugscheissenkann* :*

    Ups - da hab ich die Doku wohl zu wenig gelesen - hab das DATETIME nicht gefunden... :-[


    NACHTRAG: Jetzt hab ich mir die Doku auch mal angeschaut - die speichern das Datum auch nur als String und machen ein paar kleine Funktionen dazu.
    Da gefällt mir ein long dann doch besser, weil die Umwandlungen entfallen bei der Übernahme in Date/Calendar.


    OK - aber die Probleme bei der Umstellung wird Marco trotzdem lösen müssen, denn einfach so einen TEXT in DATETIME umwandeln geht nicht, das muss erst in ein Date-Objekt rein...

    Meine erste Idee wäre, dem EditText ein setDrawableLeft zu geben und beim Editieren dann einfach wieder auf null setzen. Versuchen kann man es ja mal... ^^


    Ansonsten fällt mir ein, dass StateListDrawables so etwas vielleicht auch können könnten - aber das ist nur eine Vermutung...

    Hallo Marco,


    das Thema Datum will ich auch noch mal als Tutorial bauen - gerade im Zusammenspiel mit der SQLiteDB gibt es dort ein paar Schwierigkeiten, weil die DB kein Date-Field unterstützt, dafür sind die Integerfelder groß genug für long-Values.
    KORREKTUR: es gibt in der SQLiteDB Funktionen für Datumsangaben - ich lasse meine Speicherung als INTEGER aber stehen. (Danke @killphil / s.u.)


    Typischer Anfängerfehler: du hast das Datum als String in der Datenbank gespeichert und ärgerst dich jetzt mit den ganzen Datumsangaben rum.


    Zunächst der Hinweis: du brauchst eine neue DB-Version und den onUpgrade der Datenbank um die Inhalte des Datumsfeldes umzustellen - aber dazu später mehr.


    Datum als long speichern:
    Die Klassen Date und Calendar können beide auf eine long-Variable umgerechnet werden: dateObj.getTime() oder calendarObj.getTimeInMillis() - diese Zahl kannst du wunderbar in der DB als INTEGER speichern und sortieren.
    Wenn du deine Daten wieder ausliest, dann musst du mit new Date(longvalue) bzw. calendarObj.setTimeInMillis(longvalue) diese Zahl wieder in deine Objekte schreiben.


    Datumsangaben nutzen:
    Du möchstest eine Grafik darstellen mit Datumsangaben auf der X-Achse - das wird eng, wenn du immer dd.mm.yyyy anzeigen willst. OK - du könntest senkrecht schreiben, aber sinnvoller ist es, nur den dd.mm anzuzeigen. Hängt davon ab, wieviele Einträge du darstellen willst.
    (Nebeninfo: Zeichnen eines guten Koordinatensystems war Teil meiner Diplomarbeit vor 25 Jahren, damals in FORTRAN und so was wie LineGraphView musste ich komplett selber aus Linien und Texten zusammensetzen).


    Primärschlüssel SQLiteDB:
    Der Primärschlüssel deiner DB sollte bitte definiert werden als BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT" - die SQLiteDB mag gerne _id als Primärschlüssel. Danach kannst du dann auch sortieren und vor allem kannst du mit diesem long-Value sehr gut in deinem Programm umgehen - da könntest du Geschwindigkeit gewinnen.


    Für alle, die mal eine Datenbank-Vorlesung gehört haben:
    ja, es gibt andere Verfahren für Primärschlüssel - aber die SQLiteDB ist nur eine einfache Datenbank und sollte nicht mit zu viel Abstraktion gesehen werden - es geht hier ja um den schnellen Einsatz in Android und nicht um ausgefeilte Datenbank-Konzepte. ;)


    Und was ist mit onUpgrade?
    Deine Kunden haben schon Daten gespeichert und möchten die auch gerne behalten - du musst die Umstellung der Datenbank (_id zufügen und füllen, Datumsangaben von TEXT auf INTEGER umstellen) also mit den alten Daten machen.
    Dazu solltest du am besten eine neue Tabelle anlegen und die alte als "Datenmüll" bis zur übernächsten Datenbankversion noch behalten, dann kannst du sie löschen.
    In dem onUpgrade musst du dann die Daten der alten Tabelle auslesen (mit den alten Methoden) und in die neue Tabelle schreiben (mit neuen Methoden, aber_id wird bei INSERT automatisch gesetzt, also nicht in den Values für db.insert() einbauen - einfach weglassen, die _id kommt als Ergebnis vom insert und kann im Datensatz nachgetragen werden).
    Bevor du das aber in onUpgrade alles implementierst, mach dir lieber eine eigene Funktion, die die Daten überträgt. Diese Funktion kannst du dann so lange testen, bis deine Daten korrekt übernommen werden.
    Dann mache die Anpassung für die Release-Version und teste die auch gründlich! Die Kunden werden es dir danken...


    Fehlermeldung mit Cursor:
    Du musst einen Cursor auch wieder mit close() schließen - und wahrscheinlich hast du viel zu viele Cursor geöffnet, normalerweise sollte man den Cursor nur öffnen, Daten übernehmen und dann close.
    Man kann auch direkt auf dem Cursor arbeiten, aber die Zugriffsmethoden für die Felder sind sehr unhandlich, darum lieber in eine eigene Datenstruktur übernehmen (und diese Daten dann auch die ganze Zeit nutzen und eher selten neu laden).
    @killphil: Danke für die Cursor-Fehlermeldung - die hatte ich nicht gefunden - konnte das noch ergänzen. :*


    LG
    Uwe

    Dann kann das noch irgendwo in den Zwischenspeichern von Eclipse hängen.


    Mach doch mal Project - Clean... *däumchendrück*


    Wenn das nicht hilft, dann ein neues Projekt anlegen und die Klassen und Resourcen rüberkopieren.

    Du hast im Pfad zweimal knueppel - hast du beim kopieren was falsch gemacht??


    Irgendwie scheint dein Eclipse-Workspace und die Verzeichnisse nicht zu passen...

    Da fällt mir auf, dass die angemeckerte Resource "/knueppel/res" heißen soll - das scheint mir ziemlich falsch.


    Wo hast du den so eine Resource verwendet???

    sorry, ich hatte noch eine Einstellung übersehen - in linearLayout3 muss stehen android:layout_width="wrap_content"


    Und wenn du sowieso nur die beiden Elemente brauchst, dann ist der linearLayout3 überflüssig, oder?


    Probiere mal dies hier:

    ArrayList ist kein Array - darum machst du schon mit new ArrayList<Button>(100); zuviel des Guten - lass die 100 einfach weg, die ArrayList wird schon noch wachsen. ^^


    Du kann Elemente einfach zufügen mit:


    Java
    inside1Buttons.add(myNewButton);


    Das ist ja der Hauptvorteil von ArrayList im Vergleich zu Arrays - es kann wachsen!!!


    Und mit

    Java
    Iterator<Button> buttonIterator = inside1Buttons.iterator();


    bekommst du einen hübschen Iterator...

    Probiere doch mal folgendes:
    dem TextView ein android:layout-weight="1" geben
    beim linearLayout3 die android:gravity entfernen.


    Ich hab die Vermutung, du willst mit gravity="right" das Element nach rechts verschieben - das geht aber nicht, diese Sache muss von dem Element darüber (linearLayout2) gesteuert werden. Und das geht am besten, wenn der TextView sich den Platz nimmt, den er braucht.
    Wenn du Elemente relativ zu einander positionieren willst, geht auch RelativeLayout, aber das ist meistens viel zu kompliziert für einfache Strukturen.


    Aber noch eine Nebenfrage: brauchst du das Image als Button oder darf ich auch auf den Text klicken?
    Dann kannst du dem TextView auch ein android:drawableRight="@drawable/recordbutton" geben und hast nur ein Element statt drei.
    Der TextView braucht dann aber android:layout_width="match_parent".

    Dann versuche doch verher noch mal in Eclipse einen Refresh der Packageliste - findest du im rechts-Klick auf Projekt...


    Achja - da gibt es noch was:
    in der Package-Liste ganz oben ist ein kleiner Button mit so komischen Kringeln - hast du da schon mal drauf geklickt?
    Der Button arbeitet mit der Mylin-Taskliste zusammen und schränkt den View ein auf die aktuelle Aufgabe...
    Wenn du mit der Maus auf das Projekt oder einen Ordner kommst, erscheint dann ein kleines +-Symbol hinter dem Eintrag?

    Das ist schon fast egal - du hast ja mit dem Codebeispiel alle Teile in der Hand und musst dann gucken, wo du das Drawable auf der Oberfläche anzeigst.


    Fast alle Widgets kennen setBackgroundDrawable() - dann hast du das Bild auch auf dem Schirm. ;)

    Du greifst da auf zwei verschiedene Sachen zu:
    R.array.widgetimg ist ein Array (von Strings),
    R.drawable.img1 etc. werden im Android als (irgendwelche) int gespeichert.


    Du musst also eine Datenstruktur speichern, z.B. HashMap<String, Integer> mit der Zuordnung des Strings und der Drawable-Resource-ID.


    Wenn du so eine HashMap aufgebaut hast, kannst du mit folgenden Befehlen weiterkommen (in sinnvoller Kombination - ich habs nicht getestet):


    Java
    int pos = spinner.getSelectedItemPosition();
    String selectedItem = getResources().getStringArray(R.array.widgetimg)[pos];
    int drawableId = myHashMap.get(selectedItem);
    myImageView.setImageDrawable(getResources().getDrawable(drawableId));


    Das hätte ich auch alles in einen Befehl packen können, aber so ist es schon unübersichtlich genug... ^^


    Wenn du das im OnItemSelectedListener vom Spinner verarbeitest, bekommst du pos schon mal gratis geliefert...

    Startest du direkt mit dem Run-Button von Eclipse?
    Probiere auch mal mit dem Pfeilchen daneben die Liste aufzuklappen und mach mal Run Configurations...
    Schau mal, was als Target für dein Projekt eingestellt ist - vielleicht macht das Ärger.


    Nachfrage zu deinem Screenshot: was meinst du denn da genau?
    Da fehlt m.E. ein res-Ordner und eine Manifest. Ist das überhaupt ein Android-Projekt???

    Hallo Pille,


    hab gestern ähnliche Sachen für mein Projekt ausprobiert und folgendes festgestellt:


    Der Aufruf von bindService legt zwar die Verbindung an, aber weil der Ablauf beim Starten eines Service etwas komplizierter ist, dauert es noch etwas, bis der Service "oben" ist.


    Du kannst auf den Service erst zugreifen, wenn die Activity vollständig gestartet ist - im Service gibt es beispielsweise noch einen Callback onActivityStarted().


    Versuche doch einmal, deine Methode checkForNewPackages() über einen onClickListener von der Oberfläche zu starten, dann ist die Activity mit allem erst mal fertig und der Service kommt mit seinen "Restarbeiten" auch endlich zum Zuge (der Emulator hat nur eine CPU).


    Vielleicht hilft dir auch die Darstellung in der Android-Doku.


    Und schau dir mal an, ob startForeground() für den Service etwas bringt - ich hab das aber noch nicht probiert.


    LG
    Uwe

    Ich hab dir ja auch nur die Teile gezeigt, die sich mit dem StringBuffer beschäftigen - die ganze restliche Logik hab ich aus Platzgründen weggelassen. ;)


    Aber vom Ablauf sollte folgendes passieren:


    Den StringBuffer neu anlegen in startElement().


    Dann füllen lassen im characters() - können ja mehrere Teile kommen. Aber keine weitere Auswertung in characters().


    Diese Auswertung machst du in endElement() - denn erst dann sind die Zeichen komplett da.


    Wenn dein Dokument aber zwischen Tags manchmal noch Text enthält, musst du auch in startElement() gucken, ob der StringBuffer schon wieder was hat und auswerten.


    Viele Beispiele im Internet mache die Auswertung in characters - bei englischen Texten geht das auch meistens gut, weil keine Umlaute vorkommen. Aber der korrekte Weg ist, im characters() nur zu sammeln was wichtig ist und im endElement() (evtl. auch im startElement()) dann den gelesenen Inhalt verwursten.

    TableRow brauchst du gar nicht, das geht besser mit LinearLayout (mit orientation horizontal):


    HTML
    <LinearLayout
                  android:layout_width="fill_parent" 
                  android:layout_height="wrap_content" 
                  android:orientation="horizontal" >
    ... deine Felder ...
    </LinearLayout>


    Und noch ein Tipp: du solltest in deinen EditText-Feldern statt android:text besser android:hint einsetzen, dann kommt der Hinweis in grauer Schrift. B-)


    Und die Einstellungen zu gravity und layout_gravity brauchst du gar nicht - lasse sie lieber weg...