{"id":2354,"date":"2021-10-03T13:18:01","date_gmt":"2021-10-03T13:18:01","guid":{"rendered":"https:\/\/www.art-events.de\/weblog\/?p=2354"},"modified":"2021-10-03T18:36:37","modified_gmt":"2021-10-03T18:36:37","slug":"android-10-oder-11-die-uri-stirbt-schneller-als-mancher-denkt","status":"publish","type":"post","link":"https:\/\/www.art-events.de\/weblog\/android-10-oder-11-die-uri-stirbt-schneller-als-mancher-denkt\/","title":{"rendered":"Android 10 oder 11 &#8211; Die URI stirbt schneller als mancher denkt"},"content":{"rendered":"<p><strong>Android 10 oder 11 &#8211; die Sache mit der Artikeldatei.<\/strong><\/p>\n<p><strong>Oder: die URI lebt k\u00fcrzer als Mancher glaubt<\/strong><\/p>\n<p>Ich habe das Verfahren seit Jahren und in unz\u00e4hligen Anwendungen verwendet: der Benutzer l\u00e4dt (per USB \/ FTP o.\u00e4) Artikeldatei \/ Artikelliste in sein Android Ger\u00e4t &#8211; und die App hat sofort Zugriff auf die dort gespeicherten Informationen.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large\" src=\"https:\/\/www.terminal-systems.de\/images\/211003-android1.jpg\" width=\"263\" height=\"413\" \/><\/p>\n<p>Nach Eingabe einer Artikelnummer k\u00f6nnen so z.b. Artikeltexte, Lagerorte, Best\u00e4nde uvam angezeigt werden und stehen dem User bei der Nutzung der App zur Verf\u00fcgung. Voraussetzung: Name der Artikeldatei muss der Anwendung bekannt sien. Beispiel: Wenn die App z.b. eine Liste mit dem Namen ARTIKEL.TXT erwartet, l\u00e4dt der Anwender diese Liste per USB in das Smartphone &#8211; und die App kann jederzeit nachschauen.<\/p>\n<p>Der Vorteil dieser Konstruktion: Die Artikelliste kann jederzeit im lfd Betrieb ausgetauscht werden, ohne dass der Benutzer es merkt. Die App greift jeweils zur Laufzeit auf die Informationen zu und pr\u00e4sentiert so immer einen stabilen Zustand.<\/p>\n<p>Bis Android 10 bot sich hierf\u00fcr das leicht erreichbare Verzeichnis \\DOWNLOADS an. Der Anwender kann es per USB \/ FTP schnell adressieren. Die App kann die Daten lesen und nutzen. In der App Programmierung waren das lediglich im Manifest zu ber\u00fccksichtigen.<\/p>\n<blockquote>\n<pre>&lt;uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" \/&gt;\r\n&lt;uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" \/&gt;<\/pre>\n<pre>android:requestLegacyExternalStorage=\"true\"<\/pre>\n<\/blockquote>\n<p>&nbsp;<\/p>\n<p>Mit Einf\u00fchrung Android 11 gibt es bei diesem Konzept Schwierigkeiten. Zuallererst: den ganzen o.a. Permission-Krempel im Manifest ben\u00f6tigt man nicht mehr! Das Sicherheitskonzept ab Android 11 (eine Anwendung hat keinen Zugriff auf Daten u. Dateien, die von einer anderen Anwendung erstellt wurden) verhindert, dass eine separat per USB \/ FTP gespeicherte Datei ARTIKEL.TXT von der Anwendung genutzt werden kann.<\/p>\n<p>Um die Artikelliste auch in Android 11 zu verwenden, wird zuk\u00fcnftig das Google Storage Access Frame Network SAF verwendet. Hierbei sind Intent f\u00fcr die Aktionen <code class=\"language-plaintext highlighter-rouge\">ACTION_OPEN_DOCUMENT<\/code>, <code class=\"language-plaintext highlighter-rouge\">ACTION_CREATE_DOCUMENT<\/code> und Uri notwendig, die von der Anwendung f\u00fcr Dateiopperationen bereit gestellt wird.<\/p>\n<p>In der Praxis kann dann der App Benutzer seine Artikelliste erst mal selbst ausw\u00e4hlen und so f\u00fcr die Anwendung freigeben. Der Vorteil au\u00dfer Datensicherheit: man muss sich nicht mehr nur auf lokale Dateien beschr\u00e4nken, sondern kann auch Daten in der Cloud ausw\u00e4hlen und freigeben \/ mit anderen Dateinamen oder Speicherverzeichnissen arbeiten.<\/p>\n<p>Doch f\u00fcr meine aktuelle Aufgabe ist der Vorteil erst mal keiner.<\/p>\n<p>Mein bisheriges Verfahren l\u00e4uft nicht mehr. Ich k\u00f6nnte jetzt auf die Idee kommen: Unterm Strich ist die Uri nur ein String. Also einmal irgendwo im Programm die Datei freigeben, dann den String nehmen, speichern und ihn in der App in den Activities verwenden, wo er ben\u00f6tigt wird. Bsp: in einer Activity A Settings w\u00e4hlt der Nutzer die Artikeldatei aus, die Uri wird erzeugt, in Preferences gespeichert und in einer Activity B Datenerfassung verwendet.<\/p>\n<p>Nette Idee. Speichern in Activity A in geht auch:<\/p>\n<blockquote>\n<pre>SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);\r\nSharedPreferences.Editor e = prefs.edit();\r\ne.putString(\"Uri4ArtFile\", uri.toString());\r\ne.apply();<\/pre>\n<\/blockquote>\n<p>Laden in Activity B dann z.B:<\/p>\n<blockquote>\n<pre>SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);\r\nUri uri = Uri.parse (prefs.getString(\"URIArtFile\", \"\"));<\/pre>\n<\/blockquote>\n<p>Doch das Ergebnis in der Praxis: Geht nicht! Zur Laufzeit gibt es einen Absturz. In Activity B erh\u00e4lt die Anwendung ein Permission Denied Problem! Die Artikeldaten stehen nicht zu Verf\u00fcgung.<\/p>\n<p>Fakt: Die normale Uri schafft es nicht \u00fcber die Lebensdauer einer Activity hinaus! Mit diesem Problem\u00a0 haben sich schon andere besch\u00e4ftigt, z.b. in diesem Text hier: <a href=\"https:\/\/commonsware.com\/blog\/2016\/08\/10\/uri-access-lifetime-shorter-than-you-might-think.html\" target=\"_blank\" rel=\"noopener\">https:\/\/commonsware.com\/blog\/2016\/08\/10\/uri-access-lifetime-shorter-than-you-might-think.html<\/a><\/p>\n<p>Wenn also aktuelle Artikeldaten ben\u00f6tigt werden, m\u00fcssen unter Android 11 andere Konzepte erstellt werden! (Die der \u00dcbersichtlichkeit halber in anderen Beitr\u00e4gen aufgef\u00fchrt werden.) Was bis dato aber noch funktioniert, zumindest solange ich die betreffende App nicht im App Store ver\u00f6ffentliche: f\u00fcr Dateien konsequent ein eigenes Verzeichnis verwenden und in der App Target SDK29 eintragen. Dann klappt es mit Android 10 Funktionen auch auf Android 11 Ger\u00e4ten. Und die L\u00f6sungen f\u00fcr SDK30 (Android 11) kommen dann sp\u00e4ter.<\/p>\n<blockquote><p>compileSdkVersion 29<br \/>\nminSdkVersion 19<br \/>\ntargetSdkVersion 29<\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<p>Anzeige:<br \/>\n<a href=\"https:\/\/www.terminal-systems.de\/wp\/\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-2330 size-full\" src=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/09\/210909-anzeige1.jpg\" alt=\"\" width=\"1800\" height=\"600\" srcset=\"https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/09\/210909-anzeige1.jpg 1800w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/09\/210909-anzeige1-300x100.jpg 300w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/09\/210909-anzeige1-1024x341.jpg 1024w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/09\/210909-anzeige1-768x256.jpg 768w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/09\/210909-anzeige1-1536x512.jpg 1536w, https:\/\/www.art-events.de\/weblog\/wp-content\/uploads\/2021\/09\/210909-anzeige1-1568x523.jpg 1568w\" sizes=\"auto, (max-width: 1800px) 100vw, 1800px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large\" src=\"https:\/\/www.terminal-systems.de\/images\/20080607hjwx-204.jpg\" width=\"204\" height=\"153\" \/><\/p>\n<p>Text und Entwurf. (c) AE SYSTEME Testcenter, Hans-J. Walter<br \/>\nHans-J. Walter ist Programmierer f\u00fcr Windows DOT.NET und Android und als Senior Chef Entwickler bei AE SYSTEME www.terminal-systems.de in Burgdorf \/ Hannover t\u00e4tig. <a href=\"mailto:hjw@terminal-systems.de\">hjw@terminal-systems.de<\/a><\/p>\n<p><em>F\u00fcr diese und alle nachfolgenden Seiten gilt ebenso der obligatorische Hinweis: Alle Angaben ohne Gew\u00e4hr. Bilder und Codes zeigen Beispiele. Diese Beschreibung bezieht sich auf unsere Installation und stellt keine Bewertung der verwendeten Techniken da. Fehler und Irrt\u00fcmer vorbehalten!<\/em><\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Android 10 oder 11 &#8211; die Sache mit der Artikeldatei. Oder: die URI lebt k\u00fcrzer als Mancher glaubt Ich habe das Verfahren seit Jahren und in unz\u00e4hligen Anwendungen verwendet: der Benutzer l\u00e4dt (per USB \/ FTP o.\u00e4) Artikeldatei \/ Artikelliste in sein Android Ger\u00e4t &#8211; und die App hat sofort Zugriff auf die dort gespeicherten [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33,34],"tags":[],"class_list":["post-2354","post","type-post","status-publish","format-standard","hentry","category-android","category-programmierung","entry"],"_links":{"self":[{"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/posts\/2354","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/comments?post=2354"}],"version-history":[{"count":0,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/posts\/2354\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/media?parent=2354"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/categories?post=2354"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.art-events.de\/weblog\/wp-json\/wp\/v2\/tags?post=2354"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}