无法从 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()