为什么文件管理器不能在 android kivymd 上运行?

我用它来创建文件管理器。

https://kivymd.readthedocs.io/en/latest/components/file-manager/

但它不再起作用了。我已经使用 buildozer 的 android 代码创建了应用程序。但是当点击按钮时不会在android上打开文件管理器。我还在应用设置中允许存储权限。但仍然没有打开文件管理器。

from kivy.core.window import Window
from kivy.lang import Builder

from kivymd.app import MDApp
from kivymd.uix.filemanager import MDFileManager
from kivymd.toast import toast

KV = '''
BoxLayout:
    orientation: 'vertical'

    MDToolbar:
        title: "MDFileManager"
        left_action_items: [['menu', lambda x: None]]
        elevation: 10

    FloatLayout:

        MDRoundFlatIconButton:
            text: "Open manager"
            icon: "folder"
            pos_hint: {'center_x': .5, 'center_y': .6}
            on_release: app.file_manager_open()
'''

class Example(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Window.bind(on_keyboard=self.events)
        self.manager_open = False
        self.file_manager = MDFileManager(
            exit_manager=self.exit_manager,
            select_path=self.select_path,
            preview=True,
        )

    def build(self):
        return Builder.load_string(KV)

    def file_manager_open(self):
        self.file_manager.show('/')  # output manager to the screen
        self.manager_open = True

    def select_path(self, path):
        '''It will be called when you click on the file name
        or the catalog selection button.

        :type path: str;
        :param path: path to the selected directory or file;
        '''

        self.exit_manager()
        toast(path)

    def exit_manager(self, *args):
        '''Called when the user reaches the root of the directory tree.'''

        self.manager_open = False
        self.file_manager.close()

    def events(self, instance, keyboard, keycode, text, modifiers):
        '''Called when buttons are pressed on the mobile device.'''

        if keyboard in (1001, 27):
            if self.manager_open:
                self.file_manager.back()
        return True

Example().run()

使用 kivymd 在 android 上打开文件管理器的实现是什么?

stack overflow Why is filemanager not working on android kivymd?
原文答案
author avatar

接受的答案

您需要将 self.file_manager.show('/') 更改为

self.file_manager.show(primary_ext_storage)

其中 primary_ext_storage 是您 Android 手机上的文件目录。您还需要在下面声明。

from android.storage import primary_external_storage_path
primary_ext_storage = primary_external_storage_path()

primary_external_storage_path() 返回 Android 所谓的“主要外部存储”,通常位于 /sdcard/ 并且可能可供任何其他应用程序访问。它与 Windows 上的 Documents 目录相比效果最好。

最重要的是,您需要在脚本中添加以下代码,以确保有权限访问手机上的存储空间。

from android.permissions import request_permissions, Permission
request_permissions([Permission.WRITE_EXTERNAL_STORAGE, Permission.READ_EXTERNAL_STORAGE])

不要被 primary_ext_storage 的名称混淆。它不是指您的 Android 手机 SD 卡。相反,它将指向您的内部存储。

对于Android手机上的外部存储,您可以使用

from android.storage import secondary_external_storage_path
secondary_ext_storage = secondary_external_storage_path()

答案:

作者头像

您无权查看 "/" 目录

def file_manager_open(self):
    self.file_manager.show(self.user_data_dir)
作者头像

您需要请求 ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION

def permissions_external_storage(self, *args):                  
    if platform == "android":
        PythonActivity = autoclass("org.kivy.android.PythonActivity")
        Environment = autoclass("android.os.Environment")
        Intent = autoclass("android.content.Intent")
        Settings = autoclass("android.provider.Settings")
        Uri = autoclass("android.net.Uri")
        if api_version > 29:
            # If you have access to the external storage, do whatever you need
            if Environment.isExternalStorageManager():
                # If you don't have access, launch a new activity to show the user the system's dialog
                # to allow access to the external storage
                pass
            else:
                try:
                    activity = mActivity.getApplicationContext()
                    uri = Uri.parse("package:" + activity.getPackageName())
                    intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, uri)
                    currentActivity = cast(
                    "android.app.Activity", PythonActivity.mActivity
                    )
                    currentActivity.startActivityForResult(intent, 101)
                except:
                    intent = Intent()
                    intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
                    currentActivity = cast(
                    "android.app.Activity", PythonActivity.mActivity
                    )
                    currentActivity.startActivityForResult(intent, 101)