无法从 url link 检索图像
Can't retrieve image from a url link
我正在 Kivy 上开发一个应用程序并将其推送到 Android。在 PC 上,我的应用程序可以完美地显示来自 google firebase url 的图像。但是,在 Android phone 上,它会遇到 SSL 错误。我认为这是 buildozer 规范许可中的一个问题。我已经给了它互联网许可。我不确定显示来自网络的图像还需要什么。
这是 python 和 kv 中的代码:
Python:
cred = credentials.Certificate("json key file name")
app = firebase_admin.initialize_app(cred,{ 'storageBucket': 'link to firebase storage.appspot.com'}, name ='storage')
bucket = storage.bucket(app=app)
imageBlob = taker2.bucket.blob(str(SelectableLabel.itemkey))
self.url = imageBlob.generate_signed_url(datetime.timedelta(seconds=300), method='GET')
print(self.url)
基维:
AsyncImage:
id: image
source: root.url
错误:
[INFO ] [Factory ] 184 symbols loaded
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO ] [Text ] Provider: sdl2
[INFO ] [Window ] Provider: sdl2
[INFO ] [GL ] Using the "OpenGL ES 2" graphics system
[INFO ] [GL ] Backend used <sdl2>
[INFO ] [GL ] OpenGL version <b'OpenGL ES 3.1 V@139.0 (GIT@I8a1ccf9ecb)'>
[INFO ] [GL ] OpenGL vendor <b'Qualcomm'>
[INFO ] [GL ] OpenGL renderer <b'Adreno (TM) 418'>
[INFO ] [GL ] OpenGL parsed version: 3, 1
[INFO ] [GL ] Texture max size <16384>
[INFO ] [GL ] Texture max units <16>
[INFO ] [Window ] auto add sdl2 input provider
[INFO ] [Window ] virtual keyboard not allowed, single mode, not docked
[INFO ] [GL ] NPOT texture support is available
[INFO ] [Loader ] using a thread pool of 2 workers
[INFO ] [Camera ] Provider: android
[WARNING] [Base ] Unknown <android> provider
[INFO ] [Base ] Start application main loop
https://storage.googleapis.com/python-app-4857e.appspot.com/-LmrOE_8MwiGdeaYKJ-j?Expires=1566449320&GoogleAccessId=firebase-adminsdk-tlrv0%40python-app-4857e.iam.gserviceaccount.com&Signature=o4jTL7eKqBTl5roNiwnNTCrq15RQEms91UBuVzPzMXKUqAJHH9LcygDS1OQOKVSKInxpm%2FXvUGeEbpAWKtUq50vf14LN8FGzGJTBkvYieiHCMP4n8sD4IN%2Fgj2nbGLCdcQKyANObOzWVKOZ%2BwNs7dpAs04ZQ5RQ05CJLqQ4wLopM9R3A9zgKUnZFmHaF6FkjwaRU1ogKdA%2BmQdV%2FP2NdfJ41aKACsIEWLTYZdrL1gCrVcQ7l5%2FHBzL2yHSdMqQL%2BFAohUc2c6D2o2W7tTIHEmxLlo%2BgdLlwOth%2BG5ImYGasbgG9xwf3ROpVrGtkfrbCznhEI8DynpNuqcqAdpb%2BKxw%3D%3D
[ERROR ] [Loader ] Failed to load image <https://storage.googleapis.com/python-app-4857e.appspot.com/-LmrOE_8MwiGdeaYKJ-j?Expires=1566449320&GoogleAccessId=firebase-adminsdk-tlrv0%40python-app-4857e.iam.gserviceaccount.com&Signature=o4jTL7eKqBTl5roNiwnNTCrq15RQEms91UBuVzPzMXKUqAJHH9LcygDS1OQOKVSKInxpm%2FXvUGeEbpAWKtUq50vf14LN8FGzGJTBkvYieiHCMP4n8sD4IN%2Fgj2nbGLCdcQKyANObOzWVKOZ%2BwNs7dpAs04ZQ5RQ05CJLqQ4wLopM9R3A9zgKUnZFmHaF6FkjwaRU1ogKdA%2BmQdV%2FP2NdfJ41aKACsIEWLTYZdrL1gCrVcQ7l5%2FHBzL2yHSdMqQL%2BFAohUc2c6D2o2W7tTIHEmxLlo%2BgdLlwOth%2BG5ImYGasbgG9xwf3ROpVrGtkfrbCznhEI8DynpNuqcqAdpb%2BKxw%3D%3D>
Traceback (most recent call last):
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/urllib/request.py", line 1317, in do_open
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/http/client.py", line 1229, in request
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/http/client.py", line 1275, in _send_request
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/http/client.py", line 1224, in endheaders
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/http/client.py", line 1016, in _send_output
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/http/client.py", line 956, in send
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/http/client.py", line 1392, in connect
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/ssl.py", line 412, in wrap_socket
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/ssl.py", line 853, in _create
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/ssl.py", line 1117, in do_handshake
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1051)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/python-installs/myapp/kivy/loader.py", line 342, in _load_urllib
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/urllib/request.py", line 525, in open
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/urllib/request.py", line 543, in _open
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/urllib/request.py", line 503, in _call_chain
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/urllib/request.py", line 1360, in https_open
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/urllib/request.py", line 1319, in do_open
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1051)>
所以我的应用打开了与 firebase 服务器的连接 5 分钟。在此时间范围内,url link 将能够显示图像。并且此图像可用于在应用程序中显示。它在 PC 上完美运行。在 Android,由于 SSL 证书错误,它显示空图像。但是,如果我手动复制该错误消息中的 link 并将其粘贴到浏览器中,我会看到一个很好的图像。所以我必须在 buildozer 中设置一个新的权限,我不确定是什么。
我当前的 buildozer 权限:
Permissionsandroid.permissions = INTERNET
2019 年 8 月 23 日更新:我按照建议将 android:usesCleartextTraffic="true"
添加到 AndroidManifest.xml 文件。这并没有解决问题。我的应用程序仍然无法在 android phone 上显示来自 url 的图像。它在 PC 上运行良好。
这是我的清单文件:
<?xml version="1.0" encoding="utf-8"?>
<!-- Replace com.test.game with the identifier of your game below, e.g.
com.gamemaker.game
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.libsdl.app"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto">
<!-- OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" />
<!-- Touchscreen support -->
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<!-- Game controller support -->
<uses-feature
android:name="android.hardware.gamepad"
android:required="false" />
<!-- External mouse input events -->
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />
<!-- Allow writing to external storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Allow access to the vibrator -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- if you want to capture audio, uncomment this. -->
<!-- <uses-permission android:name="android.permission.RECORD_AUDIO" /> -->
<!-- Create a Java class extending SDLActivity and place it in a
directory under app/src/main/java matching the package, e.g. app/src/main/java/com/gamemaker/game/MyGame.java
then replace "SDLActivity" with the name of your class (e.g. "MyGame")
in the XML below.
An example Java class can be found in README-android.md
-->
<application android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:allowBackup="true"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:usesCleartextTraffic="true"
android:hardwareAccelerated="true" >
<!-- Example of setting SDL hints from AndroidManifest.xml:
<meta-data android:name="SDL_ENV.SDL_ACCELEROMETER_AS_JOYSTICK" android:value="0"/>
-->
<activity android:name="SDLActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Drop file event -->
<!--
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
-->
</activity>
</application>
</manifest>
我遇到了类似的问题,您是否尝试过将 android:usesCleartextTraffic="true"
放入您的清单中?
经过一周的研究,我终于在 https://github.com/kivy/python-for-android/issues/1827 找到了解决方案
简单地将这些行添加到 main.py
import certifi
import os
# Here's all the magic !
os.environ['SSL_CERT_FILE'] = certifi.where()
我正在 Kivy 上开发一个应用程序并将其推送到 Android。在 PC 上,我的应用程序可以完美地显示来自 google firebase url 的图像。但是,在 Android phone 上,它会遇到 SSL 错误。我认为这是 buildozer 规范许可中的一个问题。我已经给了它互联网许可。我不确定显示来自网络的图像还需要什么。 这是 python 和 kv 中的代码: Python:
cred = credentials.Certificate("json key file name")
app = firebase_admin.initialize_app(cred,{ 'storageBucket': 'link to firebase storage.appspot.com'}, name ='storage')
bucket = storage.bucket(app=app)
imageBlob = taker2.bucket.blob(str(SelectableLabel.itemkey))
self.url = imageBlob.generate_signed_url(datetime.timedelta(seconds=300), method='GET')
print(self.url)
基维:
AsyncImage:
id: image
source: root.url
错误:
[INFO ] [Factory ] 184 symbols loaded
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO ] [Text ] Provider: sdl2
[INFO ] [Window ] Provider: sdl2
[INFO ] [GL ] Using the "OpenGL ES 2" graphics system
[INFO ] [GL ] Backend used <sdl2>
[INFO ] [GL ] OpenGL version <b'OpenGL ES 3.1 V@139.0 (GIT@I8a1ccf9ecb)'>
[INFO ] [GL ] OpenGL vendor <b'Qualcomm'>
[INFO ] [GL ] OpenGL renderer <b'Adreno (TM) 418'>
[INFO ] [GL ] OpenGL parsed version: 3, 1
[INFO ] [GL ] Texture max size <16384>
[INFO ] [GL ] Texture max units <16>
[INFO ] [Window ] auto add sdl2 input provider
[INFO ] [Window ] virtual keyboard not allowed, single mode, not docked
[INFO ] [GL ] NPOT texture support is available
[INFO ] [Loader ] using a thread pool of 2 workers
[INFO ] [Camera ] Provider: android
[WARNING] [Base ] Unknown <android> provider
[INFO ] [Base ] Start application main loop
https://storage.googleapis.com/python-app-4857e.appspot.com/-LmrOE_8MwiGdeaYKJ-j?Expires=1566449320&GoogleAccessId=firebase-adminsdk-tlrv0%40python-app-4857e.iam.gserviceaccount.com&Signature=o4jTL7eKqBTl5roNiwnNTCrq15RQEms91UBuVzPzMXKUqAJHH9LcygDS1OQOKVSKInxpm%2FXvUGeEbpAWKtUq50vf14LN8FGzGJTBkvYieiHCMP4n8sD4IN%2Fgj2nbGLCdcQKyANObOzWVKOZ%2BwNs7dpAs04ZQ5RQ05CJLqQ4wLopM9R3A9zgKUnZFmHaF6FkjwaRU1ogKdA%2BmQdV%2FP2NdfJ41aKACsIEWLTYZdrL1gCrVcQ7l5%2FHBzL2yHSdMqQL%2BFAohUc2c6D2o2W7tTIHEmxLlo%2BgdLlwOth%2BG5ImYGasbgG9xwf3ROpVrGtkfrbCznhEI8DynpNuqcqAdpb%2BKxw%3D%3D
[ERROR ] [Loader ] Failed to load image <https://storage.googleapis.com/python-app-4857e.appspot.com/-LmrOE_8MwiGdeaYKJ-j?Expires=1566449320&GoogleAccessId=firebase-adminsdk-tlrv0%40python-app-4857e.iam.gserviceaccount.com&Signature=o4jTL7eKqBTl5roNiwnNTCrq15RQEms91UBuVzPzMXKUqAJHH9LcygDS1OQOKVSKInxpm%2FXvUGeEbpAWKtUq50vf14LN8FGzGJTBkvYieiHCMP4n8sD4IN%2Fgj2nbGLCdcQKyANObOzWVKOZ%2BwNs7dpAs04ZQ5RQ05CJLqQ4wLopM9R3A9zgKUnZFmHaF6FkjwaRU1ogKdA%2BmQdV%2FP2NdfJ41aKACsIEWLTYZdrL1gCrVcQ7l5%2FHBzL2yHSdMqQL%2BFAohUc2c6D2o2W7tTIHEmxLlo%2BgdLlwOth%2BG5ImYGasbgG9xwf3ROpVrGtkfrbCznhEI8DynpNuqcqAdpb%2BKxw%3D%3D>
Traceback (most recent call last):
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/urllib/request.py", line 1317, in do_open
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/http/client.py", line 1229, in request
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/http/client.py", line 1275, in _send_request
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/http/client.py", line 1224, in endheaders
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/http/client.py", line 1016, in _send_output
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/http/client.py", line 956, in send
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/http/client.py", line 1392, in connect
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/ssl.py", line 412, in wrap_socket
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/ssl.py", line 853, in _create
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/ssl.py", line 1117, in do_handshake
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1051)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/python-installs/myapp/kivy/loader.py", line 342, in _load_urllib
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/urllib/request.py", line 525, in open
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/urllib/request.py", line 543, in _open
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/urllib/request.py", line 503, in _call_chain
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/urllib/request.py", line 1360, in https_open
File "/home/hcao/Desktop/test3/.buildozer/android/platform/build/build/other_builds/python3-libffi-openssl-sqlite3/armeabi-v7a__ndk_target_21/python3/Lib/urllib/request.py", line 1319, in do_open
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1051)>
所以我的应用打开了与 firebase 服务器的连接 5 分钟。在此时间范围内,url link 将能够显示图像。并且此图像可用于在应用程序中显示。它在 PC 上完美运行。在 Android,由于 SSL 证书错误,它显示空图像。但是,如果我手动复制该错误消息中的 link 并将其粘贴到浏览器中,我会看到一个很好的图像。所以我必须在 buildozer 中设置一个新的权限,我不确定是什么。 我当前的 buildozer 权限:
Permissionsandroid.permissions = INTERNET
2019 年 8 月 23 日更新:我按照建议将 android:usesCleartextTraffic="true"
添加到 AndroidManifest.xml 文件。这并没有解决问题。我的应用程序仍然无法在 android phone 上显示来自 url 的图像。它在 PC 上运行良好。
这是我的清单文件:
<?xml version="1.0" encoding="utf-8"?>
<!-- Replace com.test.game with the identifier of your game below, e.g.
com.gamemaker.game
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.libsdl.app"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto">
<!-- OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" />
<!-- Touchscreen support -->
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<!-- Game controller support -->
<uses-feature
android:name="android.hardware.gamepad"
android:required="false" />
<!-- External mouse input events -->
<uses-feature
android:name="android.hardware.type.pc"
android:required="false" />
<!-- Allow writing to external storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Allow access to the vibrator -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- if you want to capture audio, uncomment this. -->
<!-- <uses-permission android:name="android.permission.RECORD_AUDIO" /> -->
<!-- Create a Java class extending SDLActivity and place it in a
directory under app/src/main/java matching the package, e.g. app/src/main/java/com/gamemaker/game/MyGame.java
then replace "SDLActivity" with the name of your class (e.g. "MyGame")
in the XML below.
An example Java class can be found in README-android.md
-->
<application android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:allowBackup="true"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:usesCleartextTraffic="true"
android:hardwareAccelerated="true" >
<!-- Example of setting SDL hints from AndroidManifest.xml:
<meta-data android:name="SDL_ENV.SDL_ACCELEROMETER_AS_JOYSTICK" android:value="0"/>
-->
<activity android:name="SDLActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Drop file event -->
<!--
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
-->
</activity>
</application>
</manifest>
我遇到了类似的问题,您是否尝试过将 android:usesCleartextTraffic="true"
放入您的清单中?
经过一周的研究,我终于在 https://github.com/kivy/python-for-android/issues/1827 找到了解决方案 简单地将这些行添加到 main.py
import certifi
import os
# Here's all the magic !
os.environ['SSL_CERT_FILE'] = certifi.where()