Beiträge von Marco Feltmann

    Ich persönlich würde dafür die Bordmittel nehmen: Kalendereintrag jährliches Ereignis.
    Dann erinnert Dich Deine Kalender App an sowas, dafür ist sie schließlich da.


    (Warum Du ein eigenes kleines 'Adressbuch' pflegst statt das systemweite Adressbuch zu benutzen erschließt sich mir allerdings nicht.)

    Beim Versuch, eine Konversation zu öffnen, bekomme ich Folgendes angezeigt:


    Fatal error: An error occured. Sorry.
    Information:


    ID: 05202ecaf20b54a513d78d32f1cc29d919fb72ed
    Bitte teilen Sie dem Betreiber die oben stehende ID mit.
    Die Fehlermeldung kann mit dieser ID über „ACP » Protokoll » Fehler“ eingesehen werden.

    Du kannst das View mit ViewGroup.removeView(View) rauswerfen und via ViewGroup.addView(View, LayoutParams) neu reinhängen.
    Deine Referenzen sind dann allerdings hinfällig, findViewById(Int) wird höchstens noch laufen, wenn Du dieselbe ID erneut vergibst und dann neu liest.


    Ich würde aus lauter Gewohnheit alle möglichen Zustände als eigenes Cell Layout anlegen und dann dynamisch laden.


    Rein, Raus, Hin und Her funktioniert unter Android meiner Meinung nach nicht so elegant.

    In der MainActivity gar nicht.


    Android hatte für die Phones bis zur letzten 2er Version nur die Möglichkeit, für jeden Screen eine Activity anzulegen.
    Mit der 3er für die Tablets kam dann das Problem, dass je nach Orientierung vielleicht ein, vielleicht zwei Screens angezeigt werden müssen. Da hat man dann die Fragmente eingeführt.
    Mit der 4er für Phones und Tablets wurden die Fragmente auch auf den Phones zur Verfügung gestellt und haben den Ansatz mit mehreren Fragmenten nahezu abgelöst.
    (Settings–Dialoge kommen meist noch in einer eigenen Activity, ansonsten werden nur Fragmente gewechselt)


    Das heißt, dass die gesamte Verwaltung Deiner ListView (und generell aller UI Elemente) in dem Fragment statt finden muss, das das ListView (oder die anderen UI Elemente) auch darstellt.
    Du kannst das an einen Service delegieren um den Datenzugriff vom Mainthread abzukoppeln, die Activity als allgemeinen Delegaten für alle ListViews einzusetzen ist aber unüblich.


    (So ist das halt, wenn man keine ViewController hat…)


    Quasi ist Deine Activity ausschließlich für das Darstellen und Auswechseln der einzelnen Fragmente da (dem UIPageViewController ähnlich), während jede dort registrierte Fragmentklasse für die Darstellung seines eigenen Inhalts selbst verantwortlich ist (ähnlich den zugewiesenen ViewControllern)
    Natürlich kannst Du bei den Fragmentklassen in Deiner Activity spezifische Properties setzen, um Einfluss auf gewisse Umstände zu nehmen.
    Die Darstellung der UI Elemente regelt aber die Fragmentklasse selbst.

    Gut, das schränkt die Fehlersuche ja schon mal ein.


    Bei mir liegen die Dinger, wo sie hingehören.

    Zitat

    ➤ ls /Develop/Android/sdk/extras/android/support/v4/
    android-support-v4.jar src


    Hast Du das SDK händisch installiert und die Angaben in Android Studio weichen von dem ab, was Du angelegt hast?


    Schau mal im Preferencesy…->appearance&behavior->system settings->android sdk nach dem Pfad in 'Android SDK Locations' und prüf mal, ob das mit Deiner Vorstellung übereinstimmt. Falls nicht: Änder den Pfad.


    Im Reiter 'SDK Tools' suchst Du, ob die 'Android Support' Dinger ein Häkchen haben.
    Falls nicht: Setzen und [Apply] klicken.

    soundPool.play(soundId, 1, 1, 0, 0, 0) ;

    Ich bin mir nicht sicher, dass das richtig sein kann.


    Zitat

    public final int play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)
    […]The playback rate allows the application to vary the playback rate (pitch) of the sound. A value of 1.0 means play back at the original frequency. A value of 2.0 means play back twice as fast, and a value of 0.5 means playback at half speed.
    […]
    rate playback rate (1.0 = normal playback, range 0.5 to 2.0)

    Da Deine Rate bei 0 liegt und damit außerhalb des Ranges ist, ist an Resultaten eigentlich alles erlaubt.
    Immerhin versuchst Du, den Titel mit 0% der Geschwindigkeit wiederzugeben.
    Wenn der den Titel normal abspielt, weil er 0 für Blödsinn hält, die Abspielzeit aber auf das definierte Minimum von von 50% setzt, muss er die halbe Zeit ja mit irgendwas auffüllen – also offenbar mit nix.


    Setz die Rate mal auf 1.
    Und es ist immer hilfreich, die Dokumentationen zu lesen. ;)

    Huch, stimmt, ist ja gar nicht static.


    Java
    long days = TimeUnit.DAYS.convert(time, TimeUnit.MILLISECONDS);

    Ein bisschen schwierig zu lesen.


    Du bist also als TimeUnit das Format an, in das Du formatieren möchtest, als ersten Parameter den Wert und als zweiten Parameter das Format des Wertes.

    Ich musste ein bisschen suchen und habe es nicht weiter getestet, aber das sieht ganz gut aus:
    https://developer.android.com/…/concurrent/TimeUnit.html


    Also quasi

    Java
    long days = TimeUnit.convert(time, TimeUnit.DAYS);
    long hours = TimeUnit.convert(time, TimeUnit.HOURS);
    long minutes = TimeUnit.convert(time, TimeUnit.MINUTES);
    long seconds = TimeUnit.convert(time, TimeUnit.SECONDS);


    Die Wochen/Jahre müsstest Du allerdings immer noch selbst aus den Tagen berechnen.
    Mit den definierten Gesetzen zur Berechnung der Schaltjahre dürfte das nicht so schwer werden.
    (%4 = Schaltjahr, %100 kein Schaltjahr, %400 Schaltjahr…)


    Im Übrigen solltest Du diese Berechnung keinesfalls jede Sekunde durchführen!


    Ich würde diese Berechnung einmal beim onResume() machen und dann die Sekundenwerte über einen Timer runterzählen.
    Wenn die Sekunden <0 würden auf 59 setzen und eine Minute abziehen und das Ganze vielleicht bis auf die Stunden hoch durchiterieren.
    Ich bezweifle, dass sich jemand ein Tablet kauft und es 7 Jahre lang gut sichtbar am Strom nur mit der App laufen lässt um zu sehen, wann sein Kredit endlich abbezahlt ist. ;)

    Vermutung: Du hast das ListView im Layout für einen der Tabs hinterlegt.
    Mutmaßlich in R.layout.dates_layout. Klingt zumindest nach einer Liste.


    Wenn Du dann im R.layout.activity_main nach der ListView suchst, wirst Du sie nicht finden.
    Da ist sie nicht. Da sind nur der tabhost und tabcontent.
    (SubView des tabcontent? Dann isses beim Einhängen der Fragmente futsch.)


    Du bräuchtest schon spezielle Subklassen Deiner Fragmente und musst dort die Verdrahtung zum UI herstellen.
    (In dem Fall kannst Du erst auf die Inhalte zugreifen, nachdem onCreateView() erfolgreich durchlaufen ist. Würde ich in der onActivityCreated() machen.)


    Infos zum Fragment und seines Lebenszyklus:
    https://developer.android.com/…android/app/Fragment.html

    In der Datasource hast Du folgendes definiert:

    Java
    private String[] columns = {
                CyclingMemoDBHelper.COLUMN_NDA,
                CyclingMemoDBHelper.COLUMN_Startpunkt,
                CyclingMemoDBHelper.COLUMN_Age,
                CyclingMemoDBHelper.COLUMN_Geschlecht,
                CyclingMemoDBHelper.COLUMN_Dauer,
                CyclingMemoDBHelper.COLUMN_Geschwindigkeit,
                CyclingMemoDBHelper.COLUMN_Streckenprofil,
                CyclingMemoDBHelper.COLUMN_Distanz
        };


    Ich hatte eigentlich gedacht, Du tippst die Tutorials ab und versuchst sie zu verstehen anstatt das einfach reinzukopieren.

    Speziell für Deine Frage bzw. Deinem Denkfehler:


    Du musst natürlich die jeweils berechneten Wert (auf Ganzzahl gerundet) von Deinem Differenzwert abziehen.


    Wenn das 6 Jahre und 48 Wochen dauert, Du die 6 Jahre aber nicht vom Differenzwert abziehst, dann sind es halt immer noch 360 Wochen statt 48 Wochen.

    Die Frage ist, WANN Du das machst.


    Du solltest das in der OnCreate machen, nachdem Du manuell das ContentView gesetzt hast.
    Eventuell hast Du auch das falsche ContentView gesetzt.


    Mehr Code der betreffenden Methode (inklusive Signatur) könnte helfen.

    Ich vermute an Hand der Quellen das Problem hier:

    Zitat

    cursor.moveToFirst();

    Leider sagt Dein LogCat Abschnitt nicht mehr aus.


    Deshalb vermute ich nur entweder in der createCyclingMemo() oder in der getAllCyclingMemos()
    Es ließt sich für mich so, als wolltest Du via cursor.moveToFirst(); das erste Element des Cursors abrufen, der exakt 0 Elemente hat.


    Werte mal den Rückgabeparameter der Funktion an beiden Stellen aus.
    Wenn da ein false zurück kommt, hat irgendwas nicht geklappt.
    Vermutlich willst Du die Daten lesen und es sind überhaupt keine da.


    Eventuell (ich kenne die Implementierung da nicht) kannst Du auch date('now') als Column eingeben.
    Das sollte zumindest immer den aktuellen Timestamp als Ergebnis zurückliefern.
    (Vielleicht musst Du das aber auch explizit über execSQL eingeben…)