Eine eigene Dateiendung und kopieren von Dateien

  • Guten Morgen! ;)


    Folgendes:
    In meinem Spiel kann man selber eine "Welt" erstellen und diese auch abspeichern (das Spiel ist 2d, die Dateien haben nie mehr als 1 kb, also kein großer Aufwand). Das Funktioniert ganz toll, man kann auch immer die Dateien von der SD-Card auslesen lassen. Das große Feature an dem Ganzen ist, dass ich diese Dateien zum weiter verschicken bereitstellen möchte (egal ob per Mail oder Skype,...). Sobald ich jetzt aber nur die Datei kopiere und diese erneut in den selben Ordner speichere, ist der größte Teil (der kopierten Datei) der Welt zerstört bzw. einfach weg. Ein paar Elemente sind noch zu sehen, aber warum nur diese?


    Ist das kopieren denn so ungenau? Ich hab es noch nicht versucht, von einem Handy zum anderen zu schicken, da es ja sogar schon beim kopieren auf dem eigenen scheitert.


    Wie ich die Dateien abspeichere:


    Und das Laden sieht wie folgt aus:


    Ich bezweifle jedoch, dass es an diesen Code liegen wird, sonst würde es ja auch ohne es zu kopieren nicht funktionieren.


    Weiters würde ich gerne eine eigene Dateiendung für diese Spieldateien anlegen, damit ich aussortieren kann, welche Dateien im Spiel angezeigt werden und welche nicht, und damit man auch ohne im spiel sein zu müssen mittels Datei anklicken das Spiel gestartet wird. Bisher habe ich es mit .abcd versucht, aber gibt es hierbei denn etwas zu beachten? Wie kann ich einstellen, dass das Standardprogramm für ".abcd" Dateien mein Spiel ist?


    Ich freue mich auf Antworten :)
    MfG Salmii

  • Wie hast du kopiert? Hast du irgendein Unterschied bei der Kopie feststellen können (Größe etc.)?


    Wenn das, wie du gesagt hast, Einlesen ohne Kopieren funktionert, sollte es wirklich nicht am Code liegen. Eine schönere Variante hab ich dennoch als Tipp.
    Wenn ich das richtig sehe, dann besteht ein GraphicObject nur aus int-Werten die du in eine Datei speicherst. Da int ein primitiver Datentyp ist, ist er auch serialisierbar. D.h. du kannst dem GraphicObject ein implements Serializable hinzufügen und dann samt der ganzen ArrayList (die auch serialisierbar ist) durch ein ObjectOutputStream/ObjectInputStream schreiben bzw. lesen. Geht meiner meinung nach viel schneller und man braucht nicht alles per Hand machen. Eventuell löst dies auch dein Kopie-Problem, glaube ich aber ehrlichgesagt auch nicht.


    Für die Dateiendung musst du soweit nichts weiter beachten. Es kommt halt immer drauf an wie man Speichert bzw. Einliest. Ansonsten ist die Dateiendung eher irrelevant. Für die Auswahl eines Standartporgramms musst du einen intent-filter definieren. Bei Stackoverflow gibt es dazu bereits schon was zum nachlesen.


    block_


  • Hmm.. also ich hab bei meinem SGSII die "eigene Dateien" geöffnet, danach lang auf die Datei "getouched" und dann kam auch schon die Option "kopieren". An dem liegt's anscheinend jedoch auch nicht, habe das Handy am Computer angeschlossen und von dort aus nochmal das kopieren versucht - leider erfolglos.


    Naja, von den Objekten werden nur int variablen gespeichert, diese haben jedoch alle auch mindestens eine Bitmap zugeordnet. Vom serialisieren hab ich bisher noch nichts gehört, funktioniert sowas mit einer Bitmap denn auch? Werd mich am Abend dann mal über das Serialisieren schlau machen :P


    MFG

  • Verlass dich niemals auf hardgecodete Pfadangaben wie /sdcard/bla.


    Im schlimmsten Fall hast du keinerlei Schreibrechte auf /sdcard/ABCD.
    (Das sollte dir LogCat dann auch entsprechend mitteilen.)


    Nutze statt dessen lieber getExternalFilesDir(null);
    Manchmal liefert das null zurück, was dann immer zu Problemen führt - allerdings ist das bei mir bis jetzt nur auf seltsamen AVD passiert, nie auf dem Gerät.


    Jedenfalls sollte der dich dann in ein Verzeichnis werfen, dass du beschreiben kannst.
    Meist etwas wie /mnt/sdcard/Android/data/tld.company.app/files


    Dann sollte das Kopieren auch klappen. :)

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Naja, von den Objekten werden nur int variablen gespeichert, diese haben jedoch alle auch mindestens eine Bitmap zugeordnet. Vom serialisieren hab ich bisher noch nichts gehört, funktioniert sowas mit einer Bitmap denn auch? Werd mich am Abend dann mal über das Serialisieren schlau machen


    Bitmaps sind leider nicht serialisierbar. Diese werden auf einem anderen Weg persistent gespeichert. Die Bitmap nochmal zu speichern würde bei dir keinen Sinn haben, da, so wie ich den Code verstanden habe, durch die ID ein Bitmap aus den Resourcen bzw. Assets schon geladen wird. Habe jedoch übersehen, dass das Bitmap nach dem Laden sofort dem Objekt zugeordnet wird. Wenn du die Serialisierung ausporbieren möchtest, musst du wohl ein wenig deine Klassenstruktur verändern. Ob es dir das Wert ist, kann ich jetzt nicht sagen und du musst dich auch nicht zwingend an die Serialisierung halten ;) (Mehr Aufwand ist gewiss nicht meine Absicht für dein Ziel.)


    Dann sollte das Kopieren auch klappen. :)


    Da würde mich wundern. Das Speichern und Lesen funktionert ja. Und das Kopieren wurde auch nicht durch fehlende Rechte verhindert. Die Datei konnte ja kopiert werden, nur scheinen Teile davon danach nicht mehr vorhanden zu sein.
    Aber grundsätzlich gebe ich dir bei deiner Aussage recht!


    block_

  • Vielen Dank euch beiden! :)



    Ich habs soeben nochmal überprüft, es scheint als hätte ich mich vorher versehen? Ich rätsle gerade wirklich, wohl möglich war mein code zuvor etwas anders... Jedenfalls hab ichs gerade überprüft, catlog spuckt bei catch (IOException e) {} ein "nicht geladen" aus (was dann auch heißt, dass zuvor keinerlei Daten geladen wurden :| ). Das heißt dann wohl, dass ich tatsächlich keine Rechte auf die Datei habe.


    Ich werds dann also morgen mit getExternalFilesDir(null) probieren, wobei ich das schon schade finde - immerhin würd ich doch gern die Dateien in einem übergeordneten Ordner speichern lassen. Die Funktion, dass man die einzelnen Lvls verschicken kann, werd ich natürlich in die App einbauen, aber dann wird es nicht funktionieren, wenn die Zielperson es nicht direkt in den Zielordner einfügt, oder doch? Hättet ihr hierbei evtl. eine Lösung? Nicht zwingend ein Code, eher ein Vorschlag, wie man das Ganze unkomplizierter machen könnte? (Ein Server, der das Ganze z.B. via Facebook(Accounts) und dem ganzen Kram automatisch verschickt kommt jetzt (noch) nicht in Frage, wenn überhaupt erst dann, sollte die App dann doch ein paar Downloads bekommen)


    Kann man hierbei evtl. die Schreibrechte einräumen? Die momentan einzige Permission in der Manifest Datei ist folgende:
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


    MFG

  • Ich habs soeben nochmal überprüft, es scheint als hätte ich mich vorher versehen? Ich rätsle gerade wirklich, wohl möglich war mein code zuvor etwas anders...


    Da hilft ein SCM wie CVS, SVN oder GIT. ;)


    Jedenfalls hab ichs gerade überprüft, catlog spuckt bei catch (IOException e) {} ein "nicht geladen" aus (was dann auch heißt, dass zuvor keinerlei Daten geladen wurden :| ). Das heißt dann wohl, dass ich tatsächlich keine Rechte auf die Datei habe.


    Also zunächst mal: e ist kein dummer Jungenstreich, sondern ein Objekt vom Typ 'Exception'. Gegebenenfalls auch eines von Exception geerbten Objektes.
    Wie dem auch sei, e kann unter Anderem .toString().
    Dies zu wissen ist unglaublich wichtig. Denn damit bekommt man total hilfreiche Informationen.
    Beispielsweise 'no permission', 'file does not exist' oder Ähnliches.
    Wenn du also ganz genau wissen willst, warum Laden (und ggf. auch speichern) fehl geschlagen ist, dann gib e.toString() mit aus.


    Soweit ich die Ideologie von Android verstanden habe, möchten die nicht, dass du deine Daten irgendwo hin packst.
    Einfach, weil dann 500 Anwendungen 500 Ordner auf dem Root der SD Karte anlegen und kein Mensch mehr durchsieht. Im Allgemeinen möchte das der durchschnittliche User nicht, obgleich dir als Entwickler das sehr entgegen käme. Du kannst also nicht einfach die Schreibrechte für irgendwelche Ordner der SD-Karte übernehmen. (Vielleicht mit Jailbreak, aber das will ja keiner.)
    Es gibt wohl einige Apps, die das so machen. (Xing beispielsweise für ihre Visitenkarten, openfeint, 7digital, dsatab...)
    Mich persönlich nervt das. ;)
    Es kann aber durchaus sein, dass dein /sdcard/ das Problem ist.
    Du könntest mal versuchen, getExternalFilesDir(Environment.DIRECTORY_PICTURES)+"../ABCD" zu benutzen.
    Das sollte dann einen Pfad /mnt/sdcard/Pictures/../ABCD erzeugen, also ein /mnt/sdcard/ABCD.


    Dafür gibt es jedenfalls getExternalFilesDir(). Du kannst der Methode noch einen String-Parameter mitgeben, damit Bilder im Bilderordner, Musik im Musikordner, Klingeltöne im Klingeltonorder etc.pp. landen.
    (siehe Beispiel oben)
    Für eigene Dateien ist meines Wissens /mnt/sdcard/Android/data/com.example.myapp/files vorgesehen.


    Wenn jetzt jemand einen Ordner hat, in dem er die ganzen selbst erstellten Dateien hinlegt, dann kommst du da aus deiner App natürlich eher nicht ran.
    Wenn er die Daten statt auf /mnt/sdcard/ABCD lieber in /mnt/sdcard/Levels packen möchte, kommst du da ebenfalls nicht ran.


    Du hast also genau drei Möglichkeiten:
    a) statt dem User mitzuteilen 'Pack deine Daten nach /sdcard/ABCD' sagst du ihm 'Pack deine Daten nach /sdcard/Android/data/com.example.myapp/files/ABCD'
    b) gib ihm eine Option 'Import level data' oder 'Import level data from directory', lasse ihn manuell die Datei oder den Ordner wählen, und kopiere es dann in deiner App an den gewünschten Ort. (eventuell noch mit Option 'delete files after import')
    c) mach eine Einstellung, in der du den Ordner für die Levels angeben lässt und stelle den halt standardmäßig auf getExternalFilesDir(null)


    Es spricht natürlich gar nichts dagegen, a+b+c gleichermaßen durchzuführen. :)

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Du gibst die Fehlermeldung der Exception ja nicht aus. Tätest du dieses, sähest du den genauen Grund. ;)

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Du gibst die Fehlermeldung der Exception ja nicht aus. Tätest du dieses, sähest du den genauen Grund. ;)


    Achso, das hab ich in meinem Vorpost vergessen zu schreiben, hab das nämlich jetzt geändert und dort steht als Fehlermeldung einfach nur "File not found"... Demnach müsste ja der Pfad/Name nicht stimmen? Nur warum funktionieren dann die nicht kopierten Dateien?


    MFG

  • Dann gib doch mal mit Log.v("MyClassName", "Dateiname: "+file.getPath()) den gewünschten Namen aus. Vielleicht greifst du ja auf ein Verzeichnis statt auf eine Datei zu...


    Zugriffsrechte sind im Environment.getExternalStorageDir() normalerweise kein Problem, kann man aber auch mit file.canRead() prüfen. Interessanter wäre noch die Abfrage nach file.isDirectory() bzw. file.isFile().


    Vielleicht hilft dir auch file.length() um die Größe zu prüfen, damit du schnell siehst, ob die Datei komplett kopiert wurde. Aber das sollte eigentlich der Fall sein, sonst wäre das ein ziemlich schlimmes Problem...

  • Wenn die Zugriffsrechte nicht ausreichen, dann steht irgendwo am Ende ‚permission denied‘. Wenn das nicht da steht, dann reichen die Zugriffsrechte aus.


    Überprüf einfach mal den Pfad. Eventuell hat sich da ein / zu viel oder zu wenig eingeschlichen.


    Aber das sollte eigentlich der Fall sein, sonst wäre das ein ziemlich schlimmes Problem...


    Ich hatte mal vergessen die Puffergröße kleiner PufferArraySize wegzuschreiben. Hatte sehr kuriose Folgen, doch gefunden und geöffnet wurden die Dateien.
    0 Byte Größe heißt ja, dass die Datei zwar leer ist, doch immerhin existiert.

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

Jetzt mitmachen!

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