【问题标题】:How to get absolute path from popup (Intent.ACTION_OPEN_DOCUMENT_TREE) kivy , andoid -11如何从弹出窗口(Intent.ACTION_OPEN_DOCUMENT_TREE)获取绝对路径 kivy ,andoid -11
【发布时间】:2021-03-23 23:52:20
【问题描述】:

我是一名初级程序员,正在用 kivy 编写我的第一个应用程序。并遇到了 android - 11 (API 30) 的有限存储问题。当用户选择文件夹来保存我要存储一些数据的应用程序数据时,如何从弹出窗口中获取绝对路径。如果没有这个选项,我的应用程序在 9 anroid 上运行良好,但问题就在这里。

这是该窗口中的最少代码。如何获取绝对路径“root_id”以进一步操作此文件夹。通过在其中创建文件并在 kivy 中打开 SaveDialoga

from kivy.uix.label import Label
import os
from android import activity, mActivity
from jnius import autoclass
from kivy.app import App
from jnius import cast
from android.storage import app_storage_path, primary_external_storage_path, secondary_external_storage_path

Intent = autoclass('android.content.Intent')
DocumentsContract = autoclass('android.provider.DocumentsContract')
Document = autoclass('android.provider.DocumentsContract$Document')

class Demo(App):
    REQUEST_CODE = 42 # unique request ID
   
    def set_intent(self):
        intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        mActivity.startActivityForResult(intent, self.REQUEST_CODE)        

    def intent_callback(self, requestCode, resultCode, intent):
        if requestCode == self.REQUEST_CODE:
            msg = ""
            root_uri = intent.getData()
            print(root_uri.getPath())
            #  /tree/primary:CarInWay

            root_id = DocumentsContract.getTreeDocumentId(root_uri)
            print( root_id)
            #  primary:CarInWay

            from pathlib import Path
            p = Path(root_uri.getPath()).resolve()
            print(p, p.is_dir(), p.is_absolute())
            #  /tree/primary:CarInWay False True

            p = Path(root_id).resolve()
            print( p, p.is_dir(), p.is_absolute())
            #   /data/data/car.carinway/files/app/primary:CarInWay False True


            primary_ext_storage = primary_external_storage_path()

            data_dir = str(os.path.join(primary_ext_storage, 'CarInWay'))
            check_data_dir = os.path.exists(data_dir)
            print(data_dir , check_data_dir)
            #  /storage/emulated/0/CarInWay === True

            p = Path(primary_ext_storage + '/CarInWay')
            print('===', p, '===', p.stat().st_mode)
            #  /storage/emulated/0/CarInWay === 16832

            settings_path = app_storage_path()
            secondary_ext_storage = secondary_external_storage_path()
            print(settings_path, primary_ext_storage, secondary_ext_storage)
            #  /data/user/0/car.carinway/files /storage/emulated/0 None

    def on_start(self):
        self.set_intent()

    def build(self):
        activity.bind(on_activity_result=self.intent_callback)
        self.label = Label()

        return self.label

if __name__ == '__main__':
    Demo().run()

【问题讨论】:

  • 没有路径,因为用户不需要选择文件系统上的位置,更不用说您可以访问的位置了。
  • 对不起,我当然不完全理解android的概念。但是据我阅读文档并理解调用对话框的含义,然后用户在那里创建一个文件夹并授予在应用程序本身之外使用该应用程序的权限。据我了解,应用程序可能已经注意到数据。或者我该如何实现这一切。也许我没有正确处理这个问题
  • "然后用户在那里创建一个文件夹并授予在应用程序本身之外使用应用程序的权限。" - 是的。但是,用户创建的“文件夹”不必在用户的设备上。它可以是云存储提供商,例如 Google Drive。即使“文件夹”驻留在设备上,它也不一定代表您的应用可以访问的目录。例如,它可能由加密的文档提供商管理。
  • 我现在正在更深入地阅读论坛关于这个问题,当我不懂java时很难做到这一点。如果它是本地存储,我只会看到解决方案。请告诉我 1) 如果这不是本地存储,而是云或 sd 卡,那么是否可以通过绝对路径(或以其他方式)访问。 2)然后如何将用户的选择限制为仅限本地存储。 3)如何解决访问应用程序外部文件夹的问题,“android.permission.WRITE_EXTERNAL_STORAGE” - 不允许写入 android 11。谢谢您的帮助
  • "如果这不是本地存储,而是云或 sd 卡,那么是否可以通过绝对路径(或以其他方式)访问" -- 不。 “那么如何将用户的选择限制为仅限本地存储”——ACTION_OPEN_DOCUMENT_TREE 无法做到这一点,抱歉。

标签: python android kivy pyjnius


【解决方案1】:

对于不太准确的邮政问题,我们深表歉意。但我的问题是将数据保存在非应用程序文件夹中,这样当应用程序更新时,它们不会被覆盖。 问题的解决方法很简单。

context = autoclass('android.content.Context')
path_file = context.getExternalFilesDir(None)
path = path_file.getAbsolutePath()

这使得在 ANDROID / DATA 中创建文件夹成为可能。我可以在哪里创建和存储数据。

【讨论】:

    猜你喜欢
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 2012-08-27
    相关资源
    最近更新 更多