kivy buildozer UrlRequest 在 android 上使用 Python3 失败

kivy buildozer UrlRequest fails on android with Python3

提问人:Inaimathi 提问时间:11/14/2023 最后编辑:Inaimathi 更新时间:11/15/2023 访问量:43

问:

我已经阅读并尝试了 kivy buildozer android https 请求失败的解决方案,但 Python3 可能会改变事情?

我正在尝试运行一个 ;当我在笔记本电脑上运行它时,它工作正常,但是当我尝试在我的 Android 设备上运行它时,我一直看到日志行UrlRequestpython main.py

11-14 10:12:14.202  6785  6939 I python  : [INFO   ] REQ   ERROR -- <UrlRequestUrllib(Thread-1, started daemon 517489732944)> <<[Errno 7] No address associated with hostname>>

并且标签小组件不会按预期更改文本。如果我更改为 ,并将必要的 wod 添加到文件中,我会得到更长但不是特别有用的信息UrlRequestUrlRequestRequestsbuildozer.spec

11-14 10:21:32.098  7626  7719 I python  : [INFO   ] [REQ   ERROR -- <UrlRequestRequests(Thread-1, started daemon 517496282448)> <<HTTPSConnectionPool(host='www.google.com', port=443)] Max retries exceeded with url: / (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x787e579ba0>: Failed to resolve 'www.google.com' ([Errno 7] No address associated with hostname)"))>>

我已经按照 https://buildozer.readthedocs.io/en/latest/installation.html 的安装说明进行了操作(包括先安装,并只是为了好好衡量)。buildozerlibssl-devbuildozer android clean

最小可重现误差为:

# main.py

import kivy

kivy.require('2.2.1') # replace with your current kivy version !

import markdownify
from kivy.app import App
from kivy.logger import Logger
from kivy.network.urlrequest import UrlRequest
from kivy.uix.label import Label


class HelloApp(App):
    def build(self):
        lbl = Label(text="Placeholder Text")
        def _setlbl(new_text):
            Logger.info("REQ   callback started. Setting label text...")
            lbl.text = new_text
            Logger.info("REQ   text set")
            return new_text
        url = "https://www.google.com/"
        Logger.info("REQ Running UrlRequest...")
        UrlRequest(
            url,
            on_success=lambda req, res: _setlbl("Got a response!"),
            on_failure=lambda req, res: Logger.info(f"REQ   FAIL -- {req} {res}"),
            on_error=lambda req, err: Logger.info(f"REQ   ERROR -- {req} <<{err}>>")
        )
        Logger.info("REQ   request started...")
        return lbl


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

# buildozer.spec (with a giant pile of comments removed)
[app]

# (str) Title of your application
title = My Application

# (str) Package name
package.name = myapp

# (str) Package domain (needed for android/ios packaging)
package.domain = org.test

# (str) Source code where the main.py live
source.dir = .

# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,kv,atlas,ttf

# (list) List of inclusions using pattern matching
#source.include_patterns = assets/*,images/*.png
source.include_patterns = fonts

# (str) Application versioning (method 1)
version = 0.26

# (list) Application requirements
# comma separated e.g. requirements = sqlite3,kivy
requirements = openssl,hostpython3,python3,kivy

# (list) Supported orientations
# Valid options are: landscape, portrait, portrait-reverse or landscape-reverse
orientation = landscape, portrait

# change the major version of python used by the app
osx.python_version = 3

# Kivy version to use
osx.kivy_version = 1.9.1

#
# Android specific
#

# (bool) Indicate if the application should be fullscreen or not
fullscreen = 0

# (list) Permissions
# (See https://python-for-android.readthedocs.io/en/latest/buildoptions/#build-options-1 for all the supported syntaxes and properties)
android.permissions = android.permission.INTERNET #, (name=android.permission.WRITE_EXTERNAL_STORAGE;maxSdkVersion=18)

# (list) The Android archs to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64
# In past, was `android.arch` as we weren't supporting builds for multiple archs at the same time.
android.archs = arm64-v8a, armeabi-v7a

# (int) overrides automatic versionCode computation (used in build.gradle)
# this is not the same as app version and should only be edited if you know what you're doing
# android.numeric_version = 1

# (bool) enables Android auto backup feature (Android API >=23)
android.allow_backup = True

#
# iOS specific
#

# (str) Path to a custom kivy-ios folder
#ios.kivy_ios_dir = ../kivy-ios
# Alternately, specify the URL and branch of a git checkout:
ios.kivy_ios_url = https://github.com/kivy/kivy-ios
ios.kivy_ios_branch = master

# Another platform dependency: ios-deploy
# Uncomment to use a custom checkout
#ios.ios_deploy_dir = ../ios_deploy
# Or specify URL and branch
ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
ios.ios_deploy_branch = 1.10.0

# (bool) Whether or not to sign the code
ios.codesign.allowed = false


[buildozer]

# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 2

# (int) Display warning if buildozer is run as root (0 = False, 1 = True)
warn_on_root = 1

我在这里做错了什么?

编辑:

添加运行时权限请求本身并不能解决问题。如果我添加

from kivy.utils import platform

Logger.info(f"PLATFORM {kivy.utils.platform}")
if platform == 'android':
    Logger.info("  ON ANDROID - REQUESTING PERMISSIONS")
    from android.permissions import Permission, request_permissions
    Logger.info("    imported permission things...")
    perms = [Permission.INTERNET]
    Logger.info(f"   asking for `{perms}`...")
    res = request_permissions(perms, None)
    Logger.info(f"    permissions requested {res} ...")

在现有的导入和声明之间,我可以看到每个单独的日志行命中终端,但它仍然会导致请求错误。main.pyHelloApp

完整的日志转储为:

11-14 14:32:56.597 20951 21073 I python  : Initializing Python for Android
11-14 14:32:56.597 20951 21073 I python  : Setting additional env vars from p4a_env_vars.txt
11-14 14:32:56.597 20951 21073 I python  : Changing directory to the one provided by ANDROID_ARGUMENT
11-14 14:32:56.597 20951 21073 I python  : /data/user/0/org.test.myapp/files/app
11-14 14:32:56.597 20951 21073 I python  : Preparing to initialize python
11-14 14:32:56.597 20951 21073 I python  : _python_bundle dir exists
11-14 14:32:56.597 20951 21073 I python  : calculated paths to be...
11-14 14:32:56.597 20951 21073 I python  : /data/user/0/org.test.myapp/files/app/_python_bundle/stdlib.zip:/data/user/0/org.test.myapp/files/app/_python_bundle/modules
11-14 14:32:56.597 20951 21073 I python  : set wchar paths...
11-14 14:32:56.723 20951 21073 I python  : Initialized python
11-14 14:32:56.723 20951 21073 I python  : AND: Init threads
11-14 14:32:56.724 20951 21073 I python  : testing python print redirection
11-14 14:32:56.727 20951 21073 I python  : Android path ['.', '/data/user/0/org.test.myapp/files/app/_python_bundle/stdlib.zip', '/data/user/0/org.test.myapp/files/app/_python_bundle/modules', '/data/user/0/org.test.myapp/files/app/_python_bundle/site-packages']
11-14 14:32:56.727 20951 21073 I python  : os.environ is environ({'PATH': '/sbin:/system/sbin:/product/bin:/apex/com.android.runtime/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin', 'ANDROID_BOOTLOGO': '1', 'ANDROID_ROOT': '/system', 'ANDROID_ASSETS': '/system/app', 'ANDROID_DATA': '/data', 'ANDROID_STORAGE': '/storage', 'ANDROID_RUNTIME_ROOT': '/apex/com.android.runtime', 'ANDROID_TZDATA_ROOT': '/apex/com.android.tzdata', 'EXTERNAL_STORAGE': '/sdcard', 'ASEC_MOUNTPOINT': '/mnt/asec', 'BOOTCLASSPATH': '/apex/com.android.runtime/javalib/core-oj.jar:/apex/com.android.runtime/javalib/core-libart.jar:/apex/com.android.runtime/javalib/okhttp.jar:/apex/com.android.runtime/javalib/bouncycastle.jar:/apex/com.android.runtime/javalib/apache-xml.jar:/system/framework/QPerformance.jar:/system/framework/UxPerformance.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/android.test.base.jar:/system/framework/tcmiface.jar:/system/framework/telephony-ext.jar:/system/framework/WfdCommon.jar:/system/framework/qcom.fmradio.jar:/system/framework/com.nxp.nfc.nq.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar', 'DEX2OATBOOTCLASSPATH': '/apex/com.android.runtime/javalib/core-oj.jar:/apex/com.android.runtime/javalib/core-libart.jar:/apex/com.android.runtime/javalib/okhttp.jar:/apex/com.android.runtime/javalib/bouncycastle.jar:/apex/com.android.runtime/javalib/apache-xml.jar:/system/framework/QPerformance.jar:/system/framework/UxPerformance.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/android.test.base.jar:/system/framework/tcmiface.jar:/system/framework/telephony-ext.jar:/system/framework/WfdCommon.jar:/system/framework/qcom.fmradio.jar:/system/framework/com.nxp.nfc.nq.jar', 'SYSTEMSERVERCLASSPATH': '/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar:/system/framework/com.android.location.provider.jar', 'DOWNLOAD_CACHE': '/data/cache', 'ANDROID_SOCKET_zygote': '18', 'ANDROID_SOCKET_usap_pool_primary': '19', 'ANDROID_ENTRYPOINT': 'main.pyc', 'ANDROID_ARGUMENT': '/data/user/0/org.test.myapp/files/app', 'ANDROID_APP_PATH': '/data/user/0/org.test.myapp/files/app', 'ANDROID_PRIVATE': '/data/user/0/org.test.myapp/files', 'ANDROID_UNPACK': '/data/user/0/org.test.myapp/files/app', 'PYTHONHOME': '/data/user/0/org.test.myapp/files/app', 'PYTHONPATH': '/data/user/0/org.test.myapp/files/app:/data/user/0/org.test.myapp/files/app/lib', 'PYTHONOPTIMIZE': '2', 'P4A_BOOTSTRAP': 'SDL2', 'PYTHON_NAME': 'python', 'P4A_IS_WINDOWED': 'True', 'KIVY_ORIENTATION': 'LandscapeLeft Portrait', 'P4A_NUMERIC_VERSION': 'None', 'P4A_MINSDK': '21', 'LC_CTYPE': 'C.UTF-8'})
11-14 14:32:56.727 20951 21073 I python  : Android kivy bootstrap done. __name__ is __main__
11-14 14:32:56.727 20951 21073 I python  : AND: Ran string
11-14 14:32:56.727 20951 21073 I python  : Run user program, change dir and execute entrypoint
11-14 14:32:57.057 20951 21073 I python  : [INFO   ] [Logger      ] Record log in /data/user/0/org.test.myapp/files/app/.kivy/logs/kivy_23-11-14_1.txt
11-14 14:32:57.058 20951 21073 I python  : [INFO   ] [Kivy        ] v2.2.1
11-14 14:32:57.059 20951 21073 I python  : [INFO   ] [Kivy        ] Installed at "/data/user/0/org.test.myapp/files/app/_python_bundle/site-packages/kivy/__init__.pyc"
11-14 14:32:57.059 20951 21073 I python  : [INFO   ] [Python      ] v3.10.10 (main, Nov 14 2023, 02:57:53) [Clang 14.0.6 (https://android.googlesource.com/toolchain/llvm-project 4c603efb0
11-14 14:32:57.060 20951 21073 I python  : [INFO   ] [Python      ] Interpreter at ""
11-14 14:32:57.061 20951 21073 I python  : [INFO   ] [Logger      ] Purge log fired. Processing...
11-14 14:32:57.062 20951 21073 I python  : [INFO   ] [Logger      ] Purge finished!
11-14 14:32:59.358 20951 21073 I python  : [INFO   ] [Factory     ] 190 symbols loaded
11-14 14:32:59.878 20951 21073 I python  : [INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2 (img_pil, img_ffpyplayer ignored)
11-14 14:33:00.246 20951 21073 I python  : [INFO   ] [Text        ] Provider: sdl2
11-14 14:33:00.251 20951 21073 I python  : [INFO   ] PLATFORM android
11-14 14:33:00.252 20951 21073 I python  : [INFO   ]   ON ANDROID - REQUESTING PERMISSIONS
11-14 14:33:00.256 20951 21073 I python  : [INFO   ]     imported permission things...
11-14 14:33:00.256 20951 21073 I python  : [INFO   ]    asking for `['android.permission.INTERNET']`...
11-14 14:33:00.375 20951 21073 I python  : [INFO   ]     permissions requested None ...
11-14 14:33:00.455 20951 21073 I python  : [INFO   ] [Window      ] Provider: sdl2
11-14 14:33:00.495 20951 21073 I python  : [INFO   ] [GL          ] Using the "OpenGL ES 2" graphics system
11-14 14:33:00.504 20951 21073 I python  : [INFO   ] [GL          ] Backend used <sdl2>
11-14 14:33:00.505 20951 21073 I python  : [INFO   ] [GL          ] OpenGL version <b'OpenGL ES 3.2 [email protected] (GIT@389f9e1, I4b4012dc33, 1609770135) (Date:01/04/21)'>
11-14 14:33:00.506 20951 21073 I python  : [INFO   ] [GL          ] OpenGL vendor <b'Qualcomm'>
11-14 14:33:00.506 20951 21073 I python  : [INFO   ] [GL          ] OpenGL renderer <b'Adreno (TM) 508'>
11-14 14:33:00.507 20951 21073 I python  : [INFO   ] [GL          ] OpenGL parsed version: 3, 2
11-14 14:33:00.507 20951 21073 I python  : [INFO   ] [GL          ] Texture max size <16384>
11-14 14:33:00.507 20951 21073 I python  : [INFO   ] [GL          ] Texture max units <16>
11-14 14:33:00.632 20951 21073 I python  : [INFO   ] [Window      ] auto add sdl2 input provider
11-14 14:33:00.634 20951 21073 I python  : [INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
11-14 14:33:00.825 20951 21073 I python  : [INFO   ] REQ Running UrlRequest...
11-14 14:33:00.829 20951 21073 I python  : [INFO   ] REQ   request started...
11-14 14:33:00.831 20951 21073 I python  : [WARNING] [Base        ] Unknown <android> provider
11-14 14:33:00.832 20951 21073 I python  : [INFO   ] [Base        ] Start application main loop
11-14 14:33:00.842 20951 21073 I python  : [INFO   ] [GL          ] NPOT texture support is available
11-14 14:33:00.914 20951 21073 I python  : [INFO   ] REQ   ERROR -- <UrlRequestUrllib(Thread-1, started daemon 517499501904)> <<[Errno 7] No address associated with hostname>>
蟒蛇 安卓 python-3.x kivy

评论


答:

0赞 John Anderson 11/15/2023 #1

除了在 spec 文件中,您还需要在 python 代码中包含运行时权限请求,如下所示:permissions

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

请参阅文档。这是我使用过的一个例子:

from kivy.utils import platform
if platform == 'android':
    perms = ['android.permission.INTERNET']
    from android.permissions import request_permissions
    request_permissions(perms, None)

这应该在您执行任何涉及网络的操作之前运行。你可以把它放在你的开头,它不必在任何类中。main.py

评论

0赞 Inaimathi 11/15/2023
这本身似乎并不能解决问题;编辑问题以显示尝试。
0赞 John Anderson 11/15/2023
看看这个stackoverflow问题这个问题。
1赞 Inaimathi 11/15/2023 #2

看起来这里的实际解决方案是向 中的行和行添加权限。换句话说,原始版本的修复增量如下所示INTERNETACCESS_NETWORK_STATEandroid.permissionsbuildozer.spec

@@ -93,7 +93,7 @@ fullscreen = 0
 
 # (list) Permissions
 # (See https://python-for-android.readthedocs.io/en/latest/buildoptions/#build-options-1 for all the supported syntaxes and properties)
-android.permissions = android.permission.INTERNET
+android.permissions = android.permission.INTERNET,android.permission.ACCESS_NETWORK_STATE
 
 # (list) features (adds uses-feature -tags to manifest)
 #android.features = android.hardware.usb.host

通过该更改,该应用程序开始在 Android 上运行。我可以看到文本作为回调的一部分发生了变化,输出如下所示Labellogcat

11-14 23:41:12.404  2489  2598 I python  : [INFO   ] REQ Running UrlRequest...
11-14 23:41:12.406  2489  2598 I python  : [INFO   ] REQ   request started...
11-14 23:41:12.409  2489  2598 I python  : [WARNING] [Base        ] Unknown <android> provider
11-14 23:41:12.409  2489  2598 I python  : [INFO   ] [Base        ] Start application main loop
11-14 23:41:12.418  2489  2598 I python  : [INFO   ] [GL          ] NPOT texture support is available
11-14 23:41:12.857  2489  2598 I python  : [INFO   ] REQ   callback started. Setting label text...
11-14 23:41:12.857  2489  2598 I python  : [INFO   ] REQ   text set

这正是我所期待的。我不认为这在任何地方都有明确记录,包括在 python-for-android 权限文档中。所以它有时会发生。