提问人:Inaimathi 提问时间:11/14/2023 最后编辑:Inaimathi 更新时间:11/15/2023 访问量:43
kivy buildozer UrlRequest 在 android 上使用 Python3 失败
kivy buildozer UrlRequest fails on android with Python3
问:
我已经阅读并尝试了 kivy buildozer android https 请求失败的解决方案,但 Python3 可能会改变事情?
我正在尝试运行一个 ;当我在笔记本电脑上运行它时,它工作正常,但是当我尝试在我的 Android 设备上运行它时,我一直看到日志行UrlRequest
python 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 添加到文件中,我会得到更长但不是特别有用的信息UrlRequest
UrlRequestRequests
buildozer.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 的安装说明进行了操作(包括先安装,并只是为了好好衡量)。buildozer
libssl-dev
buildozer 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.py
HelloApp
完整的日志转储为:
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>>
答:
除了在 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
评论
看起来这里的实际解决方案是向 中的行和行添加权限。换句话说,原始版本的修复增量如下所示INTERNET
ACCESS_NETWORK_STATE
android.permissions
buildozer.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 上运行。我可以看到文本作为回调的一部分发生了变化,输出如下所示Label
logcat
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
权限文档中。所以它有时会发生。
评论