Android App kann nicht speichern

oder warum die Sache mit Scope Storage wichtig ist!

Bei mir kommt es häufig vor: wir haben eine Excel Tabelle / XLS CSV Datei, die der Benutzer per USB Transfer ins /Download Verzeichnis des Android Gerätes schiebt. Die Anwendung nimmt die Datei, arbeitet sie ab und stellt sie für den Rücktransport bereit. Oder zum Beispiel die AE Simple Barcode App – Strichcode einfach mit der Cam Eures Smartphones erfassen und zusammen mit Mengeneingabe als XLS CSV Datei für Excel speichern. So lassen sich leicht Bestellungen / Inventuren oder Warenbewegungen aller Art vor Ort erfassen. (AE Simple App hier.)

Damit das Ganze läuft war das bisher doch mehr oder minder einfach: Als Android Entwickler müsst Ihr im Manifest Eurer Anwendung die Rechte entsprechend anfordern. Nach der Installation Eurer Software muss der Benutzer Eurer App die Rechte auch gewähren! Nur wenn diese beiden Bedingungen erfüllt sind ist z.B der Zugriff auf Camera oder Speicher möglich.

Bild: Im Manifest Eurer Anwendung – die Rechte zum Schreiben und Lesen anfordern:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="de.terminalsystems.aedonxiestorageapp">

    <uses-permission android:name="android.permission.WRITE\_EXTERNAL\_STORAGE" />
    <uses-permission android:name="android.permission.READ\_EXTERNAL\_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />

Bild: Der Benutzer muss die Rechte gewähren

Nun schleppten uns unsere Kollegen ein Gerät mit Android 10 an – und Essig war es mit dem Speichern! Obwohl der Benutzer die Speicherberechtigung erteilt hat – die App weigerte sich  hartnäckig Daten zu speichern.

Bei näherem Suchen stellt sich heraus: Unsere Lösung war bisher gängige Praxis bis Android Version 9 / API Level 28. Ab Android Version 10 / API Level 29 hat Google sich etwas Neues überlegt: Das SCOPED STORAGE, zu deutsch: abgegrenztes Speichern.

In dürren Worten: Die Manifest Anweisung android.permission.WRITE\_EXTERNAL\_STORAGE… hat dabei keine relevante Wirkung mehr. Das Speichern wird verweigert, vollkommen egal ob der User die Rechte entsprechend vergeben hat. Ihr müsst nun in Eurer Anwendung je nachdem verfahren, ob ihr Media Daten oder NON Media Dateien speichern wollt. Wie das im Detail geht erfahrt ihr bei Google hier:

https://developer.android.com/training/data-storage/use-cases

Wir haben das zum Zeitpunkt dieser Zeilen noch nicht eingearbeitet. Deshalb belassen wir es mal bei dem Link. Stattdessen:

Übergangsweise, d.h. nur für Versionen bis Android 10 könnt Ihr dieses Verfahren noch temporär durch folgenden Eintrag im Manifest umgehen:

android:requestLegacyExternalStorage="true">

Der Application Bereich in Eurem Manifest sieht dann so oder ähnlich aus:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.AEDonxieStorageApp"
    android:requestLegacyExternalStorage="true">

Eure App sollte dann wieder in der Lage sein die Dateien zu speichern!

Allerdings Vorsicht: Diese Lösung ist lt Google nur temporär möglich, d.h. ab Android 11 wird der Parameter requestLagecaExternalStorage=”true” ignoriert und ihr müsst (!) Eure Anwendung dann auf Scope Storage umgestellt haben bzw. das Storage Access Frame Network SAF für Dateioperationen verwenden.

Text und Entwurf. (c) AE SYSTEME Testcenter
Hans-J. Walter hjw@terminal-systems.de

Hinweis: Alle Angaben ohne Gewähr. Diese Beschreibung bezieht sich auf unsere Installation und stellt keine Bewertung der verwendeten Techniken da.