Beiträge von Marco Feltmann

    Ordnerupload ist nicht so einfach.
    Im Dateisystem gibt es eigentlich zwei Arten von Dateien: Dateien und Ordner.
    Ordner sind auch nur Dateien, die zwei besondere Eigenschaften haben: ein parent und mehrere Children.


    Es ist also gar nicht möglich, einfach nur einen Ordner hochzuladen.
    Du musst die komplette Ordnerstruktur (idealerweise ohne parent) hochladen.


    Also den aktuellen Ordner (current), all seine Kinder (children) sowie all deren Kinder (grandchildren) und deren Kinder (grandgrandchildren) und so weiter.
    Ergo benötigst Du eine rekursive Uploadfunktion.


    Nun hast Du weiterhin das Problem, dass während des rekursiven Uploads irgendwas schief gehen kann. Internet weg. Serverplatte voll. Nutzer muss sich gegen Angriff eines Flugsauriers wehren und wirft dem das Smartphone an den Kopf, wodurch es sich ausschaltet. Irgendwas halt.


    Auf den Fall eines Abbruchs musst Du also auch sauber reagieren können. Und der Nutzer möchte dann idealerweise an dem Punkt weiter machen, an dem er unterbrochen wurde.
    (Beispielsweise fünf Tage nach der Sache mit dem Flugsaurier – der arme Mensch, diese ganzen Interviews und Termine…)


    ownCloud, DropBox, Google Drive und Konsorten arbeiten ja mit den selben Problemen nach den selben Prinzipien.
    Wenn das also mehr so eine Privatsache ist, solltest Du vielleicht über eine ownCloud Installation nachdenken.
    Die kannst Du ja über deren API ansteuern.


    Und wenn es wirklich unbedingt sein muss, kannst Du an Hand derer Implementierung ungefähr sehen, was da auf Dich zu kommt, wenn Du auch so einen Sync Service schreiben willst.
    ownCloud Klassendiagramm


    Die Sache mit dem Flugsaurier ;)

    Naja, in Java für den Desktop nutzt Du ja Swing für so User Interface Krams.


    Tatsächlich sind diese Fragmente mit etwas mehr Hirnschmalz verbunden als normale Views.
    Als Android aber für Tablets raus kam musste man halt fest stellen, dass man nur mit Activities nicht weit kommt. Dementsprechend finde ich die Integration der Fragmente auch noch nicht soooo 100%ig gut gelungen. iOS ist da mit seinen View Controllern einige Schritte weiter, allerdings nutzen die den Kram seit den ersten Versionen genau so, wie sie auch heute noch sind.


    Wenn sich das nach 'Anfänger' anhört, ist das doch legitim. So heißt ja das Unterforum auch. ;)
    Tatsächlich sind das aber Erfahrungen, die man selbst erst einmal sammeln musste. ^^


    Nein, das ist eine Komponente, die mit Deinem Programm mitinstalliert wird und auf die andere Programme zugreifen können, wenn sie wissen wie damit zu kommunizieren ist.
    Dann ist es eine Schnittstelle zwischen den PBM und den Apps. So wie Android selbst ContentProvider für Kalender, Kontakte, Medien etc.pp. bietet.

    +hm+
    Ich weiß nicht, ob Du einfach so den PagerAdapter hinter dem View austauschen kannst.
    Auch bin ich mir nicht sicher, ob Du in dem Fall nicht noch irgendwie dem UI erklären musst sich neu zu zeichnen.


    Ganz davon abgesehen bin ich mir aber sicher, dass der Ansatz so der falsche Ansatz ist.
    Du verknüpfst die Werte eines Datenmodells direkt mit einer bestimmten UI Darstellung, nämlich einem eigenen PagerAdapter.
    Damit verstößt Du einerseits gehörig gegen das MVC Pattern und andererseits erhöht sich dann mit jedem Klick der Speicherverbrauch Deiner App.
    UI Elemente sind 'teuer' (in Bezug auf die zur Generierung notwendige Systemleistung) und Du erstellst halt fröhlich mit jedem Klick einen neuen ViewPager, der von support.v4.view abgeleitet ist und damit ein UI Element darstellt. Klar, GC räumt das irgendwann weg, hoffentlich. Du weißt halt nur nicht, wann dieses 'irgendwann' ist.
    (Selbst wenn Du bereits existierende ViewPagerAdapter wiederverwendetest, hättest Du immer noch 5x 4 unterschiedliche, also 5 identische Views statt insgesamt 4 unterschiedliche Vies – und es werden immer nur maximal die 4 angezeigt.)


    Ich würde zunächst (ganz langweilig und trocken, weil man nix sieht) einen ContentProvider für die angeschlossenen PBM erstellen.
    (ContentProvider deshalb, weil Du dann damit auch von anderen Apps auf dieselben PBM und ihre Daten zugreifen kannst, ohne die Implementierung da nachbauen zu müssen. Beispielsweise ein Hilfstool zu Deiner App, die nur Geräteinformationen der PBM ausliest, eine Installation Deiner App aber voraussetzen soll.)


    Wenn dieser beispielsweise 'public ArrayList getConnectedPBM()' implementiert, kannst Du das Resultat als Quelle für Deine Auswahl nutzen.
    Noch einen Callback eingerichtet, der Dich über neu angeschlossene oder getrennte PBM informiert, dann kannst Du Änderungen auch ziemlich zeitnah im UI anzeigen.


    Naja, und wenn sich die Auswahl ändert, gibst Du den PBM an der Position in der Liste an den PagerAdapter weiter, der dann all seine Fragmente über die Änderung informiert und +zack+ stehen die neuen Daten wo sie hingehören.


    [Für Testzwecke sollte der Titel des Pagers angepasst werden. Also statt statisch 'Eingang' dynamisch 'PBM One: Eingang'. Idealerweise stammt das aus einem PBM Objekt über den Getter 'public string getTitle()']

    Also für mich sieht das so aus, als wären die Fragmente, die Du anlegst, ziemlich allgemein gehaltene Fragmente.
    Ich sehe nirgendwo, wie diese auf ihre Daten zugreifen.


    Vermutlich nutzen sie alle dieselbe Datenquelle, welche von dem Wechsel der BPM nichts mit bekommt.
    Hier hilft bestimmt der Einsatz des Debuggers. :)

    Zitat

    Ist es also möglich auch eine Activity anstelle eine Fragments am Platz von Fragment B anzeigen zu lassen?


    Nein, ist es nicht.


    Du kannst Fragmente im Code schachteln.
    Via XML klappt das nicht so gut, aber im Code geht das.


    Sprich: links hast Du Dein ListFragment, rechts ein Fragment mit einem ViewPager.


    Zitat

    Diese ganze Geschichte mit der flexiblen UI scheint ausschließlich auf Fragmenten zu basieren, stimmt das so?


    Ja, das stimmt so.


    Da Fragmente vom prinzipiellen Aufbau den Activities ähnlich sind, dürfte sich Dein Wissen mit den Activities auch auf Fragmente ummünzen lassen.

    Schade, dass die Editoransicht die Formatierung des Quelltextes immer so zerreißt…


    Irgendwie sieht es für mich so aus, als bautest Du ein Tutorial nach und wüsstest nicht, wie man Fehler im Code aufspürt.


    Wie genau meinst Du denn 'Lösungsvorschlag, der leider nicht klappt'?


    Ich stell mir bei solch detaillierter Fehlerbeschreibung immer vor, wie jemand mit seinem Auto zur KFZ Werkstatt fährt, aus dem tadellos aussehenden Wagen steigt, dem Mechaniker den Schlüssel und die Papiere zuwirft und im Gehen 'Ist kaputt.' sagt. ;)

    Zur Antwort
    Es ist sicherlich nicht Aufgabe des UI (darum handelt es sich beim XML ja im Großen und Ganzen) irgendwelche Validierungen durchzuführen.
    Natürlich gibt es ein Max Value für einen Slider. Das hat Gründe, die im UI zu finden sind: wie soll die Position des Sliders korrekt angezeigt werden, wenn es keine obere Grenze gibt?


    Eine Validierung ist das Ganze allerdings nicht. Niemand hindert irgendwen daran, hinten rum den Slider mal eben auf 150% seines Maximalwertes zu setzen.


    Validierung von Eingaben ist immer Aufgabe der Instanz, die die Eingaben übernimmt und persistiert.


    Damals™, als es noch überhaupt keine vorgefertigten UI-Elemente für Preferences gab, musste man auch alles von Hand machen.
    Die UI-Elemente sind nur dazu da, einem ein bisschen Arbeit abzunehmen – nicht um alle Arbeit abzunehmen.


    Eine gute Idee wäre also die Erstellung eigener Preference Subklassen (BoundedNumberPreference oder sowas), die dann die Funktionalität um den Editor entsprechend implementieren. Die Android Sourcen vor Allem zur TwoStatePreference dürften eine gute Anlaufstelle dazu bieten.


    Zum Post Skriptum:
    Keine Ahnung welche Art von Ton und Niveau Du erwartet hast, wenn Du drei Beiträge zu Preferences aufmachst, wovon zwei thematisch ähnlich sind.
    Zusätzlich ist der Informationsgehalt Deiner Themen sehr gering und die Formulierung mitunter umständlich.


    Auf mich wirkt das Ganze nach jemandem, der mit enormen Druck im Rücken an ein für ihn neues Projekt gesetzt wurde. Und nun versucht derjenige, möglichst zügig die Sachen umgesetzt zu bekommen ohne sich allzu sehr selbst damit beschäftigen zu müssen.


    Ich persönlich agiere immer so wie mein Gegenüber. Ist die Fragestellung schwammig, mehrdeutig, fordernd oder kompliziert formuliert, sind meine Antworten entsprechend schwammig, wenig hilfreich, fordernd oder schwer verständlich formuliert.
    Wenn ich denn überhaupt eine Antwort gebe. Diesen Thread habe ich zunächst überhaupt nicht beantworten wollen, weil mir die Zeit und mittlerweile auch die Nähe zu Android fehlt, mich mit solchen uneindeutig formulierten Anfragen zu beschäftigen.


    Da Du aber nicht müde wurdest weitere zu ähnlichen Themen zu eröffnen, niemand anderes geantwortet hatte und die Frequenz Deiner Fragen darauf schließen ließ, dass Du statt selbst Dinge zu probieren lieber auf andere wartest, habe ich mich zu entsprechenden Kommentaren bewegen lassen.


    Wenn Du der Auffassung bist, dass Dir meine Art und Weise nicht passt, so steht es Dir frei mich zu ignorieren.
    (Sofern Du mir diese Auffassung mitteilst spare ich mir Zeit und Mühen Deine Fragen zu lesen und zu beantworten.)


    Wenn Du allerdings der Auffassung bist, dass meine Art und Weise Dir zuwider ist und garantiert auch Ton und Niveau des Forums widerspiegeln, dann kann Dir wohl niemand helfen. :P

    Die Besonderheit bei den Preference XML ist, dass sie an spezielle Preference–Objekte gekoppelt sind, die von Preference erben.


    Die Konvertierung in boolean nimmt beispielsweise die TwoStatePreference Instanz (von der beispielsweise die CheckboxPreference und SwitchPreference erben) direkt vor. Dazu mappt sie vermutlich die Methode getBoolean() des Editors auf ihre 'checked' Property.


    Mir persönlich ist keine mitgelieferte Instanz der Preference bekannt, die Zahlwerte sowie Minimum– und Maximumwerte anbietet.
    Ebenso fällt mir persönlich kein adäquater Standardfall ein, der derartige Werte benötigen könnte.
    (Timeouts, Retries etc.pp. sind nach meinem Verständnis allerdings auch kein Standardfall)


    Insgesamt scheint mir die XML Implementierung bei Android ziemlich stiefmütterlich, doch immerhin ist sie in den repräsentierenden Objekten einigermaßen gut dokumentiert.


    Wie dem auch sei:

    • ich kenne keine von Android gelieferten Preference, die mit Zahlwerten agiert
    • dementsprechend wird Dir eine Nutzung des zur Preference gehörenden Editiors immer Strings zurückliefern
    • sofern die Preference kein internes Mapping für den Editor bereit stellt und beispielsweise auch boolean liefert
    • wobei ich nur zwei Preferences kenne, die das tun

    In dem Fall könntest Du Dich mal in ein Override von onApplyTheme() reinhängen und schauen, ob und wie das Theme übernommen wurde.


    Eventuell ist es auch möglich, dass die betreffenden falsch dargestellten Elemente irgend welche Styles benutzen, die durch Dein Theme nicht abgedeckt sind.


    Leider geht aus Deinen Posting nicht hervor, ob das ganze generell bei keiner PreferencesActivity funktioniert oder nur beim Wechseln des Themes in der dazugehörigen Acitivity fehl schlägt.

    Infos darüber findest Du in den bekannten öffentlichen Quellen.


    Natürlich steht in einem XML alles als String drin, das ist auf Grund des Formats auch anders gar nicht möglich.
    Das XML stellt ja nur eine Repräsentation der jeweiligen Preference Objekte dar.


    Wenn Du etwas Anderes benötigst als Dir angeboten wird, dann erstelle Dir eigene Preference Objekte die das tun, was Du möchtest.
    Dann hast Du natürlich keine XML Datei.


    Andererseits ist Programmierung was Anderes als Elemente irgendwo hin ziehen und hoffen, dass das läuft.
    Da ist bei Abweichungen von Standardfällen Handarbeit von Nöten.

    Die generierten Standard-Edit-Funktionen sind für Standardanwendungsfälle da.
    Du möchtest einen Anwendungsfall realisieren, der vom Standard abweicht.


    Du wirst nicht umhin kommen, das im Code zu realisieren.


    Insgesamt frage ich mich sowieso, warum Du offenbar so eine Angst davor hast die Dinge im Code zu regeln.

    Theoretisch kannst Du anfangen einen (S)FTP Server oder einen SSH Client zu implementieren.
    Vielleicht kannst Du auch das XMPP Protokoll umbiegen.


    HTTPPost ist schon das Sinnvollste.


    Es ist eine doofe Idee, das Passwort im Klartext verschlüsselt irgendwo abzulegen. Einfach weil im Zweifelsfall immer noch der Anwender seine Daten selbst auslesen kann.
    Ein wenig klüger ist es, den auf Serverseite generierten Hash abzuspeichern.
    Noch besser ist es natürlich, die Verwaltung des Ganzen dem System zu überlassen. Ich weiß nur nicht, ob unter Android irgendwas dafür vorgesehen ist.
    Unter iOS hat man jedenfalls die Keychain. Die für java.security.keychain scheint allerdings zur Zertifikate und Ähnliches zu bunkern, keine normalen Kennwörter.
    Eventuell findest Du ja was zu dem Thema.


    Ansonsten: rausfinden wie Benutzername und Passwort für das Login verschlüsselt werden, eingegebene Werte genau so verschlüsseln und in den SharedPreferences sichern.

    Synchronisation ist generell eine eher schwierige Sache.
    Einfacher wäre es vermutlich, wenn die Datenbank auf dem Gerät immer die Inhalte der Webdatenbank annimmt.
    (Synchronisation bedeutet, dass beide Datenbanken ihre Daten miteinander abgleichen…)


    Bei derartigen Konstrukten hast Du immer das Problem, dass es einen Zeitpunkt ohne Daten geben kann.
    Beispielsweise nachdem Du die alte Datenbank weggeworfen hast, die neue Datenbank aber noch nicht wieder zur Verfügung steht. Oder wenn der Nutzer die App aufs Gerät geladen hat und vor dem ersten Start die Internetverbindung deaktiviert hat.


    Im Prinzip solltest Du über einen ContentProvider im Hintergrund die Datenbank (neu) befüllen, alte Elemente als 'veraltet' markieren und dazugehörige Dateien vom Dateisystem löschen und wenn alles geklappt hat die als 'veraltet' markierten Elemente aus der lokalen Datenbank löschen.


    Schwierig ist hierbei lediglich die Kommunikation zwischen App und Web. Es ist im Prinzip eine schlechte Idee, einmal die komplette Datenbank herunterzuladen und umzuschichten. Sinnvoller wäre es wohl, über ein PHP Script die relevanten Datenbankinhalte als JSON zu übergeben, die Datenbank zu befüllen und während des Befüllens zu prüfen, ob die gewünschte Datei schon auf dem Gerät existiert – im Bedarfsfall dann löschen.


    Auf jeden Fall solltest Du irgend einen Indikator mitgeben, über den ermittelt werden kann, ob die Datenbank überhaupt neue Inhalte hat.

    Wie Deine XML aussieht hängt davon ab, wie Du das ganze Drumherum gestalten möchtest.


    Du musst lediglich eine View definiert haben, in der Du die ganzen Checkboxen reinhauen möchtest.


    Im Prinzip kannst Du Dir die Sache mit den XML eigentlich auch sparen. Sie sind nur ein Weg, die UI Erstellung aus dem Code rauszuziehen und gleich eine Vorschau zu bieten. Aber es ist völlig ersetzbar. Wenn Du setView statt mit der Ressource mit einer Instanz von View aufrufst, läuft das genauso.
    Nur musst Du halt dann das View komplett selbst im Code erstellen.


    Also: XML UI = statisch. Code UI = dynamisch. ;)