Reputation: 3692
I have this small application and I'd like to rewrite it to use more privacy-friendly best practices, such as the Storage Access Framework.
How to do it in Python
(Kivy)? I searched the web and haven't found any tutorial or examples with Python
. I know only very little Java
and Kotlin
at all. So, I would like to read the examples in Python
.
I would like to replace this code:
request_permissions([Permission.WRITE_EXTERNAL_STORAGE,
Permission.READ_EXTERNAL_STORAGE])
try:
if autoclass('android.os.Build$VERSION').SDK_INT >= 29:
Context = autoclass('android.content.Context')
self.working_directory = os.path.join(Context.getExternalFilesDir(None).getAbsolutePath(), "tdg_articles")
self.data_dir = os.path.join(Context.getExternalFilesDir(None).getAbsolutePath(), "nltk")
else:
Environment = autoclass('android.os.Environment')
self.working_directory = os.path.join(Environment.getExternalStorageDirectory().getAbsolutePath(), "tdg_articles")
self.data_dir = os.path.join(Environment.getExternalStorageDirectory().getAbsolutePath(), "nltk")
except:
self.working_directory = os.path.join(App.get_running_app().user_data_dir, "tdg_articles")
self.data_dir = os.path.join(App.get_running_app().user_data_dir, "nltk")
if not os.path.exists(self.working_directory):
os.makedirs(self.working_directory)
if not os.path.exists(self.data_dir):
os.makedirs(self.data_dir)
os.chdir(self.working_directory)
Upvotes: 4
Views: 2377
Reputation: 389
So if you want to access permission in kivy, the easiest way is to place the permissions in the permissions field in buildozer.spec file. You just need to place the permissions WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE in the buildozer file. Refer the kivy and buildozer docs. Or if you want to call the ask for permission from within the app, you can also use pyjnius library.
Upvotes: 0
Reputation: 11873
Scoped Storage brings two major changes:
By default, you are given access to an app-specific folder that can't be accessed by others apps. However, if you need to read/write the files in another location you have to explicitly ask for them. The scoped storage is similar to accessing a database. You request the Android API to perform the action and the system does it for you.
Similar Issues:
There's an open issue in Github that resembles a similar situation.
https://github.com/kivy/buildozer/issues/1304
Useful Resources:
I couldn't find any official documentation, but there's an experimental repository by Robert Flatt that uses the scope storage.
https://github.com/Android-for-Python/Storage-Example
He provided the storage.py class that implements an API for database access of this app's public storage. The shared storage operations provided are insert()
, delete()
, and recieve()
, these copy files between this app's private and shared storage.
Suggestions for the code refactoring:
Scoped Storage isn't limited to asking the file permission only, hence you need to migrate all of your file operations this way.
Examples of using the storage.py class:
#######################
#
# Examples:
# Where txt_file could be PrivateStorage().getFilesDir() + 'text.txt'
# and so on.
# All methods take a required file name, and optional directory parameters.
#
# Insert:
# SharedStorage().insert(txt_file, 'Documents')
# SharedStorage().insert(txt_file, sub_dir= 'a/b')
# SharedStorage().insert(txt_file, 'Downloads')
# SharedStorage().insert(jpg_file, 'Pictures')
# SharedStorage().insert(mp3_file)
# SharedStorage().insert(ogg_file, 'Music')
#
# Retrieve:
# path = SharedStorage().retrieve('test.txt')
# path = SharedStorage().retrieve('test.txt', 'Documents', 'a/b')
#
# Delete:
# SharedStorage().delete('test.mp3', 'Music')
#
# Retrieve from another app's storage (requires READ_EXTERNAL_STORAGE) :
# SharedStorage().retrieve('10_28_14.jpg', 'DCIM', '2021_03_12',
# 'CameraXF')
# SharedStorage().retrieve('10_33_48.mp4', 'DCIM', '2021_03_12',
# 'CameraXF')
#
#######################
Detailed instructions are given here.
Upvotes: 3
Reputation: 1263
After my research you should go with Pyjnius and directly access the SAF class from Python. Kivy also have some documentation pertaining to this: https://kivy.org/doc/stable/guide/android.html#pyjnius.
Upvotes: 2