Android Question File.DirRootExternal in Sdkversion 30?

Tjitte Dijkstra

Member
Licensed User
Longtime User
After upgrading to B4a v 11.2 I got the recommendation to change the sdkversion in the Manifest like this: android:targetSdkVersion="30"
I compiled my app and all worked fine.
If File.DirRootexternal was called from the main module it worked, but if File.DirRootexternal was called from a sub-module I got a fatal error: EACCESS(Permission denied)
What to add to the sub modules, or what else?
(If I downgrade to sdkversion 28 the problem is solved as well....)
 

Mahares

Expert
Licensed User
Longtime User
the app is in the App Store.
If the app is in the app store, you cannot use it. You have to look at post #16 by aGaraham for an alternative.
But, for those of you who want to use File.DirRootExternal with OS 11 and target SDK 30, but not for the App Store, here is attached a project that saves a string to a text file and reads it back from the file into the logs.
 

Attachments

  • ManageExternalStorageMahares020122.zip
    10.2 KB · Views: 180
Upvote 0

agraham

Expert
Licensed User
Longtime User
2. the app is in the App Store.
Then you will need to target SDK 30 and Google will not accept an app using Manage External Storage in a store app except for some very specific types of app that need it. If you don't want to use an app private folder you need to use one of the methods in the link in my post #16 above.
B4X:
rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
rp.CheckAndRequest(rp.PERMISSION_READ_EXTERNAL_STORAGE) ' YOU DON'T NEED THIS IF YOU ASK FOR WRITE_EXTERNAL_STORAGE
rp.CheckAndRequest(rp.GetSafeDirDefaultExternal("ATLAS10")) ' YOU DON'T NEED TO ASK PERMISSION FOR THIS FOLDER
 
Upvote 1

Tjitte Dijkstra

Member
Licensed User
Longtime User
The puzzle is not solved yet.
1. Where can I find library ExternalStorage?
In my IDE I don't have it:
1643804533484.png

2. In my app the individual users have their scores saved and read in the map ATLAS10 without any problem. So why not read a small text-file from the same directory as well?
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Upvote 0

Tjitte Dijkstra

Member
Licensed User
Longtime User
Anyhow it is quite strange that my app can read and write a textfile with information (name and score of a pupil) without any problem and at the same time a short textfile with information about our city or country is refused.
Because I now have the class ExternalStorage installed, I hope to proceed.
B4a is not too difficult, but these complications surprise and confuse me.
For more than 30 years I programmed some educational programs (in Turbo Pascal and Delphi) and since 2014 I wrote some apps for the Android tablet. Problems like these are unknown to me.
Imagine: my topography app teaches children to know more than 700 cities/countries/mounains etc. But they also have the opportunity to write a small textfile on one of these cities. The "scrabbook" function is much nicer than only knowing the names and the spot.
For now: I hope to take the next step and maybe I will succeed?
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
B4a is not too difficult, but these complications surprise and confuse me.
You are not the only one. Include me for one! Android started out as a reasonably open OS like Windows and Linux, but over the years privacy and security concerns have made Google progressively tighten what an app can do, at least those listed in the Store, and we seem to be getting towards an Apple style walled garden for apps that you wish to distribute to the wider public. Unfortunately Android is now the only real alternative to Apple for mobile programming - whether for private use (which all my apps are) or to publish to a wider world.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
rp.GetSafeDirDefaultExternal("ATLAS") is visible from a user's PC and would allow drag and drop.
 
Upvote 0

Tjitte Dijkstra

Member
Licensed User
Longtime User
@drgottjr:
For sure the directory ATLAS10 should be visible from a user's PC just for the opportunity for the pupils to save extra information on the names of the cities that are in the topography quiz. That's the core business of my app.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
so, use it already. you did notice the difference between File.DirRootexternal and rp.GetSafeDirDefaultExternal("ATLAS"), didn't you? and you do understand the difference, right? it's fully compliant with sdk30
 
Last edited:
Upvote 0

Tjitte Dijkstra

Member
Licensed User
Longtime User
@drgottjr:
What I do not understand is: how can I read or write to my directory ATLAS10? Very peculiar is this: all *.jpg files are handled without any problem. All files with scores of pupils are handled (read & write) without problems.
BUT: all files with a *.txt extension get the error: permission denied (Although file.exists = true)
Your remarke "fully compliant with sdk30" is hopeful, because my app makes no sense if pupils cannot add their won information to the topography app. (A free trial is in the Play Store by the name of ATLAS 9 )
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
you have to let it go. with respect, no one believes you. that was evident from the first
responses you received. you never showed code that we could run for ourselves (i
believe the apostle thomas referred to that need early on), and you never showed the log.
besides, it's irrelevant at this point.

you have boxed yourself into a corner by not having kept abreast of android's changes over the
past couple years. there were periods of grace which you allowed to pass. now you have a
big problem.

if you do not want to update your app on play, you don't have to do anything. google still allows
sdk28 apps to remain as is. of course, at some point, they may shut those apps down as well.

to publish new or to update current apps, you need sdk30. and the crux of sdk30 is the use
of "file providers" (or managers, of a sort) to access resources in public folders.

without getting into great detail, google has provided GetSafeDirDefaultExternal("ATLAS")
as a way to let you continue to put your app-related files in public direxternal (just not rootexternal).
why this is called "safe" is up for discussion. (we are, after all, dealing with a company that uses
names like "icecream sandwich", "donut" and "gingerbread" for its products.)

one of the side effects of SafeDirDefaultExternal("ATLAS") is that your users can plug their
androids into their laptops and see the atlas folder along with all the other public folders they
can see. when testing, i use it all the time. in production, everything goes into dirinternal,
which is what google has always wanted. for me, i came from an environment where it was
not possible to store private data in a publicly accessible area, so it never occurred to me to
use rootexternal.
 
Upvote 0

Tjitte Dijkstra

Member
Licensed User
Longtime User
Thanks a lot for your broad answer. I send my testprogram in a zip-file and the error message from the log as well. The advice to use Dirinternal means that users cannot add their own information, because the files have to be stored in de files-section before compilation.
My questions in CAPITALS


to publish new or to update current apps, you need sdk30. and the crux of sdk30 is the use
of "file providers" (or managers, of a sort) to access resources in public folders.
FILE PROVIDERS? WHERE CAN I FIND THEM? I START NOW WITH RESEARCHING.

without getting into great detail, google has provided GetSafeDirDefaultExternal("ATLAS")
as a way to let you continue to put your app-related files in public direxternal (just not rootexternal).
IF I USE DIREXTRENAL I GET AN ERROR: UNKNOWN IDENTIFIER.

one of the side effects of SafeDirDefaultExternal("ATLAS") is that your users can plug their
androids into their laptops and see the atlas folder along with all the other public folders they
can see. when testing, i use it all the time. in production, everything goes into dirinternal,
which is what google has always wanted. for me, i came from an environment where it was
not possible to store private data in a publicly accessible area, so it never occurred to me to
use rootexternal.
IT IS THEIR OWN TABLET, SO WHY CALL IT PUBLICLY?

I hope to solve the problem one day or another............
Cheers,
Tjitte Dijkstra 3843 NL
 

Attachments

  • ErrorOnLine62.jpg
    ErrorOnLine62.jpg
    24.5 KB · Views: 118
  • PermissionTEST.zip
    11.3 KB · Views: 131
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
The advice to use Dirinternal ...
WRONG! NOT DIRINTERNAL, IT'S SafeDirDefaultExternal("ATLAS")
time for a new eyeglasses prescription:)

it refers to a public area different from rootexternal. your users can add their files to the atlas directory (although, respectfully, users should never be allowed to create their own content without your intervention.)

in any case, i (and, perhaps, others) can look at your attachment. also, send full error log as text, not as a culled image of a snippet. it's what you don't show us that is of most interest.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
For a start this is wrong. You should be testing result as well as the permission you were requesting
B4X:
Sub Activity_PermissionResult (Permission As String, Result As Boolean)
    If Permission = rp.PERMISSION_WRITE_EXTERNAL_STORAGE Then
        ATLAS10MapMaken
    End If
End Sub
You can also use Wait For instead
B4X:
rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE) ' Implicit read capability if granted
Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
Also you don't need to test permission in your second Activity - you've already done it in Main and should rely on that.

This code is wrong. You are not requesting a valid permission type and in fact you don't need to request permission for GetSafeDirDefaultExternal anyway.
B4X:
    rp.CheckAndRequest(rp.GetSafeDirDefaultExternal("ATLAS10"))

For some reason you are setting activity height and width, this is unnecessary.
You seem to have added manifest permissions that you do not need to.


Attached is a version of your test app with a cleaned up Main and manifest. UNINSTALL YOUR APP before trying it to reset the permissions. Note that requesting PERMISSION_WRITE_EXTERNAL_STORAGE asks the user for access to "photos and media" which if you allow will return True but the ATLAS10 folder will not be created as this does not give you access to the full file system. Targeting SDK 28 it would ask for access to "photos, media and files" - note the difference - and ATLASS10 will be created.

When playing with permissions it is important to UNINSTALL youar app each time as permissions carry over installs.
 

Attachments

  • PermissionTEST2.zip
    11.2 KB · Views: 122
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
install PermissionTEST3, (base on agraham's mod of your original) attached at bottom, and run. it will, of course, "fail" because none of the files in ATLAS10 will be found. not to worry.

from your pc/laptop turn on usb file sharing on the device. referring to image 1.png
1.png



you should see the app listed in its private folder. if you double click on "files", you should see ATLAS10.

on my pc/laptop i created Mergelland.jpg and Harderwijk.txt. i saved them to the ATLAS10 folder. you may do the same on your own (just make sure to name them correctly). or i am including my content files in the zip archive for your convenience. drag them to the ATLAS10 folder. (refer to attached image 2.png)

2.png


now run the app again. you should see something similar to attached image 3.png.
3.png


it's sideways and truncated - not my problem.
 

Attachments

  • PermissionTEST3.zip
    33.2 KB · Views: 120
Last edited:
Upvote 0

Mahares

Expert
Licensed User
Longtime User
I also have a fully functional projects sitting for several hours ago with all the files in DirAssets and copied automatically to File.DirExternal after you receive permission. I did not want to post it yet untill you had a chance to digest the other two projects. No errors at all. It woks on a device with OS 11, but you must set your target SDK to 28. I hope you will not need it. But if you continue to have problems, I can post it.
Here you are being treated like a prince by several members. We just want you to succeed and be happy. If you posted your project days ago, this thread would not be topping 40 posts by now.
 
Upvote 0

Tjitte Dijkstra

Member
Licensed User
Longtime User
For a start this is wrong. You should be testing result as well as the permission you were requesting
B4X:
Sub Activity_PermissionResult (Permission As String, Result As Boolean)
    If Permission = rp.PERMISSION_WRITE_EXTERNAL_STORAGE Then
        ATLAS10MapMaken
    End If
End Sub
You can also use Wait For instead
B4X:
rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE) ' Implicit read capability if granted
Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
Also you don't need to test permission in your second Activity - you've already done it in Main and should rely on that.

This code is wrong. You are not requesting a valid permission type and in fact you don't need to request permission for GetSafeDirDefaultExternal anyway.
B4X:
    rp.CheckAndRequest(rp.GetSafeDirDefaultExternal("ATLAS10"))

For some reason you are setting activity height and width, this is unnecessary.
You seem to have added manifest permissions that you do not need to.


Attached is a version of your test app with a cleaned up Main and manifest. UNINSTALL YOUR APP before trying it to reset the permissions. Note that requesting PERMISSION_WRITE_EXTERNAL_STORAGE asks the user for access to "photos and media" which if you allow will return True but the ATLAS10 folder will not be created as this does not give you access to the full file system. Targeting SDK 28 it would ask for access to "photos, media and files" - note the difference - and ATLASS10 will be created.

When playing with permissions it is important to UNINSTALL youar app each time as permissions carry over installs.
Thanks so far,
I tried your version and I got the same error as before:

Error occurred on line: 50 (TEST)

java.lang.RuntimeException: Object should first be initialized (TextReader).

at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:67)

at anywheresoftware.b4a.objects.streams.File$TextReaderWrapper.ReadLine(File.java:641)

at Permission.Test.test$ResumableSub_Button1_Click.resume(test.java:503)

at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)

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

at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)

at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)

at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)

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

at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)

at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)

at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)

at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267)

at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:137)

at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)

at anywheresoftware.b4a.keywords.Common$1.onClick(Common.java:490)

at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:188)

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

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

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

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

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

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

** Activity (test) Pause, UserClosed = true **
 
Upvote 0

Tjitte Dijkstra

Member
Licensed User
Longtime User
install PermissionTEST3, (base on agraham's mod of your original) attached at bottom, and run. it will, of course, "fail" because none of the files in ATLAS10 will be found. not to worry.

from your pc/laptop turn on usb file sharing on the device. referring to image 1.png
View attachment 125158


you should see the app listed in its private folder. if you double click on "files", you should see ATLAS10.

on my pc/laptop i created Mergelland.jpg and Harderwijk.txt. i saved them to the ATLAS10 folder. you may do the same on your own (just make sure to name them correctly). or i am including my content files in the zip archive for your convenience. drag them to the ATLAS10 folder. (refer to attached image 2.png)

View attachment 125159

now run the app again. you should see something similar to attached image 3.png.
View attachment 125160

it's sideways and truncated - not my problem.
Your enhancements might be a step forward. If I copy the files to Android/data/Permission.Test/files/ATLAS10 all works fine. (In the original version only the pictures and the individual scores were loaded; not the *.txt files.) But a path so long, might be too difficult for children of 10-12 years or their teachers as well. So, now I am curious to find a way to move the files that are dropped in /ATLAS10 to the directory mentioned above. The study goes on, because the possibility to add your own information to the topography app is a key feature, (since 1992!)
 
Upvote 0

Tjitte Dijkstra

Member
Licensed User
Longtime User
I also have a fully functional projects sitting for several hours ago with all the files in DirAssets and copied automatically to File.DirExternal after you receive permission. I did not want to post it yet untill you had a chance to digest the other two projects. No errors at all. It woks on a device with OS 11, but you must set your target SDK to 28. I hope you will not need it. But if you continue to have problems, I can post it.
Here you are being treated like a prince by several members. We just want you to succeed and be happy. If you posted your project days ago, this thread would not be topping 40 posts by now.
Mahares,
You write "all the files in DirAssets copied automatically to File.DirExternal." How can that be done?
You also write "must set your target SDK to 28." But in that case the app cannot posted to the Play Store, I think? My app is not used all over the world, but in >100 primary school.
Maybe you can post your "fully functional project?"
Best regards,
Tjitte Dijkstra, The Netherlands
 
Upvote 0
Top