Beiträge von clthaler

    die Fehlermeldung sagt es dir doch schon ziemlich genau.

    Du kannst bei ViewBindig das Onclick Tag im Xml nicht mehr nutzen.

    Das geht ja auch schon seit Fragments nicht mehr.

    ... schade, dabei fand ich das OnClick Tag bisher ganz praktisch im Vergleich zum Listener. Aber ich bin ja flexibel.


    Du scheinst noch einen sehr alten Programmierstiel zu verfolgen.


    ... ist eher die Bequemlichkeit, eine noch funktionierende Programmierung nicht zu ändern. Wenn etwas Neues für mich dazukommt, tu ich mich meist etwas schwer damit, es zu verstehen. Aber dafür gibt es ja Profis, denen ich hoffentlich auch mal "dumme" Fragen stellen darf ;)


    Danke dafür ...

    Danke für das Beispiel. Wenn ich es teils mit "ACTION_OPEN_DOCUMENT_TREE" in meinem TestCode umsetze, erhalte ich jetzt auch die gewünschte Nachfrage nach Ort und Zugriffsberechtigung.


    Nun wird mir aber auch gesagt, dass "startActivityForResult" veraltet ist und durch einen "ActivityResultLauncher" ersetzt werden sollte. Nach ein paar Recherchen habe ich nun folgenden Code:


    Ich beschränke mich darauf, erstmal nur einen Text darzustellen, möchte dann aber letztendlich per "FileOutputStream" eine einzelne Textdatei schreiben.


    Nun ist es so, dass die App stoppt und das Logcat folgendes ausgibt:


    FATAL EXCEPTION: main

    Process: clthaler.appfortest, PID: 21927

    java.lang.IllegalStateException: Could not execute method for android:onClick

    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:473)

    at android.view.View.performClick(View.java:7448)

    at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1131)

    at android.view.View.performClickInternal(View.java:7425)

    at android.view.View.access$3600(View.java:810)

    at android.view.View$PerformClick.run(View.java:28305)

    at android.os.Handler.handleCallback(Handler.java:938)

    at android.os.Handler.dispatchMessage(Handler.java:99)

    at android.os.Looper.loop(Looper.java:223)

    at android.app.ActivityThread.main(ActivityThread.java:7656)

    at java.lang.reflect.Method.invoke(Native Method)

    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)

    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

    Caused by: java.lang.reflect.InvocationTargetException

    at java.lang.reflect.Method.invoke(Native Method)

    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:468)

    at android.view.View.performClick(View.java:7448)

    at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1131)

    at android.view.View.performClickInternal(View.java:7425)

    at android.view.View.access$3600(View.java:810)

    at android.view.View$PerformClick.run(View.java:28305)

    at android.os.Handler.handleCallback(Handler.java:938)

    at android.os.Handler.dispatchMessage(Handler.java:99)

    at android.os.Looper.loop(Looper.java:223)

    at android.app.ActivityThread.main(ActivityThread.java:7656)

    at java.lang.reflect.Method.invoke(Native Method)

    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)

    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

    Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.CREATE_DOCUMENT }

    at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2067)

    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1727)

    at android.app.Activity.startActivityForResult(Activity.java:5314)

    at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:728)

    at androidx.core.app.ActivityCompat$Api16Impl.startActivityForResult(ActivityCompat.java:809)

    at androidx.core.app.ActivityCompat.startActivityForResult(ActivityCompat.java:246)

    at androidx.activity.ComponentActivity$2.onLaunch(ComponentActivity.java:243)

    at androidx.activity.result.ActivityResultRegistry$2.launch(ActivityResultRegistry.java:175)

    at androidx.activity.result.ActivityResultLauncher.launch(ActivityResultLauncher.java:47)

    at clthaler.appfortest.MainActivity.button1(MainActivity.java:52)

    at java.lang.reflect.Method.invoke(Native Method)

    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:468)

    at android.view.View.performClick(View.java:7448)

    at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1131)

    at android.view.View.performClickInternal(View.java:7425)

    at android.view.View.access$3600(View.java:810)

    at android.view.View$PerformClick.run(View.java:28305)

    at android.os.Handler.handleCallback(Handler.java:938)

    at android.os.Handler.dispatchMessage(Handler.java:99)

    at android.os.Looper.loop(Looper.java:223)

    at android.app.ActivityThread.main(ActivityThread.java:7656)

    at java.lang.reflect.Method.invoke(Native Method)

    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)

    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)


    Ich erhalte auch keine Abfrage des Ortes und der notwendigen Berechtigung, wie es bei "ACTION_OPEN_DOCUMENT_TREE" der Fall war. Und wenn ich es richtig verstehe, erhält der Launcher aufgrund dessen keine Rückgabe, die von ihm verarbeitet werden kann, was dann zu diesem Fehler führt. Die Ausnahme kann ich natürlich abfangen, aber das löst natürlich nicht das Problem.


    Gleiches passiert, wenn ich "ACTION_OPEN_DOCUMENT" verwende. Irgendwo ist im Code oder in meinem Verständnis ist also noch der Wurm drin.

    Habe mich mal gerade etwas in die Doku zu SAF vertieft. Offenbar ist diese schon ab API 19 verfügbar/nutzbar, so dass es vielleicht doch Sinn macht, darauf zurückzugreifen. Müsste dann wahrscheinlich nur die "minSDKVersion" im Manifest auf 19/21 festlegen, was aber OK ist.


    Ich bin grad soweit, dass ich über "ACTION_OPEN_DOCUMENT_TREE" und einem Intent Objekt eine URI erhalte. Bei der Auswahl des gewünschten Ordners werde ich auch wie erwartet nach meinen Rechten befragt. Soweit, so gut.


    Welche Möglichkeit habe ich nun, eine Pfadangabe zu meiner URI zu erhalten? Die Methode "getPath()" liefert mir "/tree/primary:Documents", was ich so aber nicht weiter verwenden kann ...


    Zur Erklärung: ich möchte die Daten gerne weiterhin als Paper Datenbank speichern (via Paper.bookOn), aber eben im ExternalStorage, brauche dafür aber auch eine entsprechende Pfadangabe.

    Entschuldige meine fehlende Antwort. Die hatte ich ganz vergessen ...


    Grundsätzlich möchte ich die Daten gerne in einem öffentlichen Ordner wie z.B. Documents ablegen. Denn dort hat der User auch die Möglichkeit, exportierte Daten zum erneuten Import abzulegen. Der App eigene Bereich ist meines Wissens dem normalen User nicht zugänglich.


    Ich würde mich auch erstmal auf Versionen bis API 32 beschränken. Für höhere Versionen kann ich dann immer noch eine Fallunterscheidung wie für API 23 einfügen und entsprechend behandeln. Wäre jetzt zumindest mein erster Gedanke.

    Moin alle zusammen,


    Im Rahmen einer App Entwicklung/Erweiterung möchte ich gerne durch den Nutzer eingegebene Daten, die bisher im internalStorage landen, als Backup in den externalStorage schreiben, so dass diese dann ggf. auch wieder importiert werden können. Nun ist das Thema externalStorage und damit verbundene Lese-/Schreibrechte recht neu für mich und offenbar auch etwas komplexer, als ich dachte (erste Versuche waren jedenfalls nicht erfolgreich). Daher habe ich beschlossen, bei Null anzufangen und mich stückweise dem eigentlichen Ziel zu nähern - hoffentlich mit eurer lehrreichen Unterstützung. Zum Testen habe ich mir eine einfache GUI mit mehreren Buttons und Textzeilen erstellt, so dass ich auf Knopfdruck diverse Aktionen auslösen kann (später dann das Lesen und Speichern von Dateien).


    Der erste Schritt für mich ist, die Lese- und Schreibrechte abzufragen und zu setzen.


    Dazu das Manifest:


    Und hier der Java Code:


    Hier nun mein erster Stolperstein:


    Bei Erstinstallation der App (Android Emulator in Android Studio mit der API 30/Android 11) wird auf Anfrage auch brav die Permission abgefragt und gesetzt. Aber unabhängig davon, wie der User diese setzt, findet auf Anfrage keine erneute Abfrage statt! Es sei denn, ich ändere die Rechte per Hand über die Android-Einstellungen. Eine Option "nicht mehr fragen" erscheint erst gar nicht. Bei "requestPersmissions()" würde ich eigentlich stets den entsprechenden Abfragedialog von Android erwarten. Aktuell könnte ich den User nur auffordern, dies bei Bedarf manuell in den Einstellungen zu ändern, was aber etwas ineffizient anmutet ... habe ich hier einen Fehler im Code oder nur einen Denkfehler?

    ... scheint komplexer zu sein, als ich dachte. Werde jetzt am besten mal bei Null anfangen und mich Schritt für Schritt vortasten. Das Speichern/Lesen im external Storage ist aktuell leider Neuland für mich.


    Danke für die Infos. Ich denke, ich werde da ggf. ein neuen Thread erstellen und auf gute Tips hoffen.

    Erstens hast du schon mal keine Permission die haben sich schon seit Version 6 geändert und ab 11 nur noch SAF

    ... doch, die Permission habe ich. Habe ich testweise schon abgefragt, ist nur nicht im obigen Code enthalten. Und das Schreiben und Lesen funktioniert ja auch solange ich die Textdatei nicht händisch in den entsprechenden Ordner schiebe!


    Habe obigen Code jetzt mal auf meinem Tablet ausgeführt (Android 11) und siehe da, ich kann problemlos eine händisch erstellte/kopierte Datei einlesen. Es scheint also eher ein Problem mit dem Emulator in Android Studio zu sein.

    Hallo alle zusammen,


    ich sitze gerade an einem Problem, bei dem ich aktuell leider nicht mehr weiter weiß. Ich hoffe, einer von euch kann mich auf die richtige Spur bringen.


    Ich schreibe an einer App, die unter anderen interne Daten in eine Textdatei schreiben und auch wieder auslesen soll. Das Schreiben der Textdateien ist kein Problem, Zugriffsrechte auf den Ordner (öffentlicher Ordner "Documents") habe ich manuell gesetzt bzw. prüfe ich an separater Stelle. Dateien und Unterordner werden auch als existent erkannt. Der folgende Code simuliert die gewünschte Funktion:


    Die entsprechende App zeigt hier 2 Buttons und 2 Textzeilen. Der erste Button schreibt die Textdatei, der zweite Button liest diese wieder ein und gibt den Inhalt auf die zweite Textzeile aus. Dies funktioniert auch soweit, ABER sobald ich die Textdatei händisch in den entsprechenden Ordner kopiere, wird diese nicht mehr eingelesen und die App stürzt ab (bzw. liefert eine Exception und stoppt).

    Im Debug Modus kann ich sehen, dass die kopierte Textdatei zwar als existent erkannt wird, aber kein Lesezugriff möglich ist. Ich habe hier die Vermutung, dass ein anderer Prozess die Textdatei blockiert??? Kann ich dies irgendwie ändern oder die Leserechte manuell setzen?


    Die Zugriffsrechte für die App habe ich manuell in den Android Einstellungen gesetzt. Eine entsprechende Prüfung im Code bestätigt die Lese- und Schreibrechte auch.


    Vorschläge oder Ideen?


    Danke schon mal für die Hilfe ...