【问题标题】:kivy android : write public fileskivy android:编写公共文件
【发布时间】:2014-10-09 21:39:33
【问题描述】:

我正在使用 Kivy 编写一个 Android 应用程序,并希望该应用程序写入 android 文件系统、一些 PUBLIC 目录/文件。

目前,如果我的应用程序写入一个文件(使用 Python),该文件可以被 android 本地文件管理器读取,但不能被我的计算机 mtp 读取(这些文件不会出现在 InternalStorage 中)。 adb shell 可以看到这些文件。

[编辑] 解决方案可能是使用带有 Pyjnius 的 MediaScannerConnection 扫描文件以查找 mtp,但是如我的下一个答案所示,它对我不起作用。 [/编辑]

在我看来,我正在寻找与此处描述的 Java getSharedPreferences 的等效项:http://developer.android.com/guide/topics/security/permissions.html

我认为 buildozer 规范中有一个类似的选项:此处描述的 android.private_storage 字段:https://raw.githubusercontent.com/kivy/buildozer/master/buildozer/default.spec

但是,我没有让它工作......也许我没有正确使用 buildozer 命令:在规范“android.private_storage = False”中设置后,我尝试了几个命令,如“buildozer android release - -dir public my_dir" 或 "buildozer android release --public my_dir" 等...,没有成功。

【问题讨论】:

  • 或多或少已解决:这显然是 mtp 中的一个已知错误:某些文件,取决于它们的编写方式(我使用的是 Python“打开”指令)直到您重新启动后才会显示设备。事实上,重启设备确实有帮助。我仍然不确定如何使用 buildozer private_storage 选项。
  • 私有存储只是一个布尔切换,用于存储应用数据的位置——如果为真,它会像普通应用一样进入 /data/data/...。如果为 False,则将 python 的东西放在外部存储目录中,以便您可以更轻松地编辑/访问它 - 前者是正常的,也是默认的。
  • 很有趣,谢谢您
  • MoriB 发布您的评论作为答案并接受它。在 stackoverflow 中被认为是一种很好的做法

标签: android python kivy mtp pyjnius


【解决方案1】:

我一直在尝试使用 Pyjnius 中的 MediaScannerConnection 使文件无需重置即可查看,但没有成功。在文件系统中写入文件后,目标是扫描它们。这是运行但没有任何明显效果的代码。

from jnius import autoclass , cast
from jnius import PythonJavaClass, java_method

PythonActivity = autoclass('org.renpy.android.PythonActivity')
activity = cast('android.app.Activity', PythonActivity.mActivity)
context = activity.getApplicationContext()

MediaScannerConnection = autoclass('android.media.MediaScannerConnection')
MediaScannerConnection.scanFile(context,successFiles,None,None)   #successFiles is a list of absolute paths of files on Android

我也一直在尝试使用 scanFile 方法的其他重载形式,但我无法正确定义所需的接口:

class OnScanCompletedListener(PythonJavaClass):
    __javainterfaces__ = ['android.media.MediaScannerConnection$OnScanCompletedListener']


    @java_method('(Ljava.lang.String;Landroid.net.Uri;)V')
    def onScanCompleted(self, path, uri):
        pass

    @java_method('()V')
    def onMediaScannerConnected(self):
        pass


MediaScannerConnection = autoclass('android.media.MediaScannerConnection')
mediaScannerConnectionListener = OnScanCompletedListener()
mScanner = MediaScannerConnection(context,mediaScannerConnectionListener)
mScanner.connect()
for thefile in successFiles:
    mScanner.scanFile(thefile,None) 

【讨论】:

    【解决方案2】:

    或多或少已解决:这显然是 mtp 中的一个已知错误:某些文件,取决于它们的编写方式(我正在使用 Python“打开”指令)在您重新启动设备之前不会显示。事实上,重启设备确实有帮助。

    【讨论】:

    • 这不是bug而是特性:MTP数据库需要用媒体扫描器刷新。启动设备会运行媒体扫描仪,这就是它有帮助的原因。在 Android Java 中,您可以使用 MediaScannerConnection 来刷新数据库;不知道如何在 Kivy 中做到这一点。
    • 谢谢拉阿尔托。我猜你的意思是在新文件上调用 scanFile 方法。我会尝试用 Kivy 的 Pyjnius 来调用它。
    猜你喜欢
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 2015-05-07
    • 2017-03-13
    • 1970-01-01
    • 2011-09-25
    • 2012-11-28
    • 1970-01-01
    相关资源
    最近更新 更多