問題描述
我有 這個小應(yīng)用程序,我想要重寫它以使用對隱私更友好的最佳實踐,例如存儲訪問框架.
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.
如何在 Python
(Kivy) 中做到這一點?我在網(wǎng)上搜索并沒有找到任何使用 Python
的教程或示例.我對 Java
和 Kotlin
知之甚少.所以,我想閱讀 Python
中的示例.
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
.
我想替換這段代碼:
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)
推薦答案
Scoped Storage帶來兩大變化:
- 首先,您不再可以通過文件的路徑訪問文件.相反,您需要使用它的 Uri.
- 其次,如果你想修改一個不是你的應(yīng)用創(chuàng)建的文件,你需要征求用戶的許可.
默認情況下,您有權(quán)訪問其他應(yīng)用無法訪問的特定應(yīng)用文件夾.但是,如果您需要在另一個位置讀取/寫入文件,則必須明確要求它們.范圍存儲類似于訪問數(shù)據(jù)庫.您請求 Android API 執(zhí)行操作,系統(tǒng)會為您執(zhí)行.
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.
類似問題:
Github 中有一個類似情況的未解決問題.
There's an open issue in Github that resembles a similar situation.
https://github.com/kivy/buildozer/issues/1304
有用的資源:
我找不到任何官方文檔,但 Robert Flatt 有一個使用范圍存儲的實驗性存儲庫.
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
他提供了 storage.py 實現(xiàn)用于訪問此應(yīng)用程序公共存儲的數(shù)據(jù)庫的 API 的類.提供的共享存儲操作是 insert()
、delete()
和 recieve()
,這些在此應(yīng)用的私有存儲和共享存儲之間復(fù)制文件.
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.
代碼重構(gòu)建議:
Scoped Storage 不僅限于詢問文件權(quán)限,因此您需要以這種方式遷移所有文件操作.
Scoped Storage isn't limited to asking the file permission only, hence you need to migrate all of your file operations this way.
- 來自 Android API 29+ WRITE_EXTERNAL_STORAGE"許可是多余的.由于您將通過 MediaStore/SAF 使用存儲,因此您不再需要此權(quán)限.
- 每當(dāng)您執(zhí)行文件操作時,請檢查 Android 版本,如果低于 29,請繼續(xù)使用現(xiàn)有代碼.否則,使用 storage.py 類讀取/寫入文件.
- 如果您已經(jīng)將數(shù)據(jù)存儲在應(yīng)用目錄之外,則還需要將它們移動到應(yīng)用目錄內(nèi)的文件夾中.
使用 storage.py 類的示例:
#######################
#
# 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')
#
#######################
詳細說明在這里.
這篇關(guān)于Python 中的存儲訪問框架的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!