Hello especially to the developers,
I
would like to save files in the so-called "app-specific (private) external
storage". According to Google, this does not require READ_ /
WRITE_EXTERNAL STORAGE permissions.
https://developer.android.com/reference/android/Manifest.permission.html#READ_EXTERNAL_STORAGE
The
path of the app-specific (private) external storage is:
/storage/emulated/0/Android/<packageName>/files
In
my case it is:
/storage/emulated/0/Android/data/appinventor.ai_bodymindpower.TestFileAI/files
There
are many misconceptions about the terms Internal Storage and External Storage.
Here is a very good overview on this topic:
https://www.dev2qa.com/android-read-write-external-storage-file-example/.
The
File component and the TaifunFile extension requires READ_ / WRITE_EXTERNAL
STORAGE. Therefore, the permission must be denied or previously removed from
the Manifest. These permissions should only be needed if you want to save to a non-app-specific
directory.
Steps to test the app (API ≥ 19 !):
1.
Download AIA (maybe possible later)
(Note: The new method of the TaifunTools extension (ApplicationSpecificDirectory) is not yet published. I recently received it only for test purposes from Taifun. Taifun has been helping me with my apps for several years. So I have to wait until Taifun gives me his OK to publish the aia. But you don't really need the aia for testing. So first go to step 2 and download the APK)
https://drive.google.com/file/ ... is coming later ...
2. Open AIA with AI2 or download the APK from here:
https://www.bodymindpower.de//pages/download.php3. (Create APK) install APK and open the app
Do nothing else!
4.
Check if the app-specific (private) external storage folder has been created on
your device:
Android - data - <packageName> - files - priv.txt
(If
the device has a MicroSD card, the directory should also be created on this SD
card)
5.
Press the "save file ..."
button.
If a permission is required, deny it. You should then get a message "Error 908: The permission WRITE ... has been denied ..."
6.
Click on the "read file ..." button.
Deny permission! Message: "Error: 908: The permission READ ... has been denied ... "
7. Grant permissions
now everything should work as it should do without these permissions
8. Uninstall the app
check if the app-specific (private) directory has been deleted. This is an indication that this is an app-specific (private) directory.
On Kodular and Thunkable I get similar issues. Only on AppyBuilder the app runs without permissions correctly.
(test the AppyBuilder version (APK): https://www.bodymindpower.de//pages/download.php )
Therefore, I assume that there is a bug here with App Inventor. The app-specific (private) external storage may NOT be declared correctly; see Google Developer Documentation (link see above):
"Also starting in API level 19, this permission is not required to read / write files in your application-specific directories returned by Context.getExternalFilesDir (String) and Context.getExternalCacheDir ()."
Thanks and regards,
Anke
Trying to push the limits of App Inventor!
Snippets,
Tutorials and
Extensions from
Pura Vida Apps by
Taifun.
Hello Evan,
sorry, but I will not let up yet.
It may apply in your particular case, but I do not dispute any specific case.
I do not really understand that my case should be specific.
I'm talking about the general case. For example, consider the following code:
global PublicAndPrivate = ["priv.txt", "/public.txt"]
File1.WriteFile (PublicAndPrivate [randint (1,2)], "foo")
Also, I do not understand what the Python code (random query for a single file) should explain here. The declaration of a private directory as app-specific is the question here. And this should actually be done at compile time (install-time).
Recall that the app in addition to asking user permission at runtime must also include the permission at compile time in AndroidManifest.xml.
No, as far as I know, this should be only necessary for Pre-Marshmallow devices, for API > 22 the permission are always requested at runtime. You can catch this by declaring:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="22" />
Note that I expect in the AppyBuilder case, they are just including the permission and then not asking for permission, which is something that we can do, but that is different than not including the permission at all. Note that for SDK levels before 23, the app will be granted the permission regardless of whether it is accessing private/public directories because of this.
No, the permission in this case (API < 23) is requested (only for public / non-app-specific directories) at install-time and you have to grant it with all the other permissions listed at this time. Otherwise the app is not installed.
To ensure that app-specific directories do not require any permissions, the following must be declared in the Manifest: minSdkVersion ≥ 19 .
I think, I found a workaround for this issue with another extension, but why should this not be possible with the File component?
Regards, Anke
"You absolutely need to have the permission in the manifest if you want to be able to request it at runtime; ... "
At this point you are right. Thanks for clarifying
that. So, as long as I can not write in an app-specific folder without WRITE
permissions with App Inventor, I will go ahead with my workaround to resolve
this issue (without the File compontent). Or I have to switch to AppyBuilder ...
Thanks again and regards,
Anke