Jump to content
Guest

Delphi 11.3, Android 13, External Storage Schism

Recommended Posts

Guest

Here I am with my fourth topic in a very short period.

 

This past Monday I started making the necessary changes to my 2 apps which were built using Delphi 10.2 (for Android 4.4 devices) and Delphi 10.4 (for Android 8 and Android 10 devices) over to Android 13 using Delphi 11.3.  This was started about 5 years ago.

 

I was finishing up today when the door slammed in my face.  Android 13 read external storage permission has been deprecated.

 

I noticed that when I installed both apps that they show permissions for media, photos, etc. but no permissions for storage.  My 2 apps communicate with each other - one reads the others configuration file and the other reads/write to a SQLite database.  Short of having to merge both together is there a workaround.

 

Correct me if I am wrong.  When installing an app it is put in its private folder.  There is also a public folder system that should be able to contain any type of files.  Could that be a solution if the public area does not require permissions?

 

Thanks.

Share this post


Link to post

Hi,

Android 11 introduces the following changes related to storage permissions...

https://developer.android.com/about/versions/11/privacy/storage

 

 

Share this post


Link to post
Guest

Hi GSan,

 

Very interesting reading.  I love how they get your hopes up and as you read further they take away your hope.  My original message stated read, but I also need write, too.  Lot of double talk.

Share this post


Link to post
Guest

Part 1

 

Thanks GSan for the information.  The interesting thing is that my Android 10 calls those read/write external storage permissions as "storage".  My Android 13 calls those same permissions as other things that do not pertain to "storage" which means I cannot access either my configuration file for one of my apps and my database for my other app.  Also those 2 apps never hit the application store.  They are used by our customers only and we install the apps.  In my opinion Android should have made a concession/compromise for the external storage permissions to continue if the Android project configuration was set to development.  To me, they went overboard.

 

Part 2

 

Part 1 is depressing.  Part 2 is not so depressing.

 

I have worked on what I have read about for these past few days and it works.  However, I wonder when Android will shut this one off, too.

 

I have taken the route of using System.IOUtils.TPath.GetSharedDocumentsPath.

 

You create your projects the same as in the past.  Then you copy the file, database or whatever to the shared documents path.  The reason why you have to do this is because the deployment manager does not allow for setting/installing documents outside of the project.

 

The neat thing is that there are no permissions needed to be set.

 

Other logistics will come to me as I progress.  And this is much easier than having to combine both projects together which would be very time consuming.

Share this post


Link to post
Guest

By the way

 

image.thumb.png.f92f550a6f2e19262e2d98f55dcc24c5.png image.thumb.png.8c63e8a1cb29a80060cccf9244cf4760.png 

 

It does not matter whether I have the storage permissions included or omitted, this is the result.

Share this post


Link to post
Guest

Forgot to mention this change to AndroidManifest.template.xml.

 

<%uses-permission%>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>  <<< must be added - no other storage lines or permissions required

 

I am not sure how long Android will all this.
 

Share this post


Link to post

Have you considered using an external store accessed via a URI? That would have the advantage of users being able to move from one device to another and have their data follow them.

 

If you read the tea leaves, vendors are making things harder and harder to create mobile apps that follow a usage model similar to traditional desktop apps. That's forcing the data to be saved remotely. That does make it challenging to operate without internet access. But internet access is becoming pretty much ubiquitious these days, esp. for low-security needs. Just encrypt the data and save it as a blog somewhere and manage it via an in-memory DB. (Probably needs versioning and other stuff to prevent corruption, but that shouldn't be too difficult.)

Share this post


Link to post
Guest

I have moved on.  I took both apps and re-engineered them into one app.  I have a better product now.

Share this post


Link to post

I am having a similar problem updating an app that was created over 5 years ago. I followed the solutions at https://github.com/emozgun/delphi-android-SAF and implemented methods to copy a sqlite database from the Internal Storage/Documents folder (TPath.GetSharedDocumentsPath) to TPath.GetPublicPath then into the apps internal path (TPath.GetDocumentsPath). After the process, My app detects the database file but FireDac cannot open the database file. What Did I Miss? 

 

Share this post


Link to post
On 4/7/2023 at 8:44 AM, Mustafa ֍zgun said:

external store accessed via a URI https://github.com/emozgun/delphi-android-SAF

I've been testing this project and selecting a single file works and displaying the metadata works fine.

But selecting a directory (ACTION_OPEN_DOCUMENT_TREE) throws an exception and I cannot find a solution.

First chance exception at $0000006C85F59EE8. Exception class EJNIException with message 'java.lang.UnsupportedOperationException: Unsupported Uri content://com.android.externalstorage.documents/tree/primary%3ADCIM'

My goal is to list all the images with metadata on my phone from the Android MediaLibrary (https://developer.android.com/reference/android/provider/MediaStore.Images.Media)

Has anyone got a solution?

Share this post


Link to post

I also encountered the same problem, I solved it by replacing the code:

Ad := '"' + DosyaAdi(Uri) + '" '

with

If RequestCode<>Dizin_Agaci_Ac
   Then Ad := '"' + DosyaAdi(Uri) + '" '
   Else Ad := TPath.GetFileName(JStringToString(uri.getPath));

in the "OnActivityResult" procedure, but it still doesn't work, even if you give consent you can't read the files. I tried with the "Download" folder and I only get the folders contained therein.

 

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×