【问题标题】:How to load image in android from server(Amazon S3) with Https URL?如何使用 Https URL 从服务器(Amazon S3)加载 android 中的图像?
【发布时间】:2015-03-29 12:46:51
【问题描述】:

我是安卓的初学者。 我正在处理客户端代码,我必须读取服务器上存储的图像并将其显示在 imageview 中。 我参考了一些 stackoverflow 问题,但无法成功。 我用 HttpsURLConnection 类做了简单的纯 java 程序我从服务器得到了一些二进制响应图像,用纯 java 代码就可以了。 但是当我在 android 中尝试同样的事情时,我得到了例外:

01-29 18:39:28.199: WARN/System.err(2045): java.io.IOException: SSL handshake failure: I/O error during system call, Unknown error: 0
01-29 18:39:28.249: WARN/System.err(2045):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.nativeconnect(Native Method)
01-29 18:39:28.249: WARN/System.err(2045):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:316)
01-29 18:39:28.249: WARN/System.err(2045):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.getSecureSocket(HttpConnection.java:168)
01-29 18:39:28.249: WARN/System.err(2045):     at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:399)

这是我的示例图片的公共 URL:

https://s3-ap-southeast-1.amazonaws.com/edt-demo-app/app-images/Mobile.jpg

在纯 java 中对我来说可以正常工作的代码如下:

package com.psl.dao; 
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;

mport javax.net.ssl.HttpsURLConnection;

   public class HttpsClient{

   public static void main(String[] args)
   {
        String url = "https://s3-ap-southeast-1.amazonaws.com/edt-demo-app/app-images/Mobile.jpg";
        try {
            new HttpsClient().print(url);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
   }


   public void print(String url)throws Exception
   {
     String httpsURL = url;
     URL myurl = new URL(httpsURL);



     System.setProperty("https.proxyHost", "puproxy.company.co.in");
     System.setProperty("https.proxyPort", "8080");

     HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection();
     System.out.println(con.toString());
     InputStream ins = con.getInputStream();
     InputStreamReader isr = new InputStreamReader(ins);
     BufferedReader in = new BufferedReader(isr);

     String inputLine;

     while ((inputLine = in.readLine()) != null)
     {
       System.out.println(inputLine);
     }

     in.close();
   }    
}

然后我参考了一些 android 教程并在我的 android 应用程序中尝试了以下代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class TestSSL {

    public static void main(String[] args) throws Exception {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        } };
        // Install the all-trusting trust manager
        final SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };


        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

        System.setProperty("https.proxyHost", "puproxy.company.co.in");
       System.setProperty("https.proxyPort", "8080");

        URL url = new URL("https://s3-ap-southeast-1.amazonaws.com/edt-demo-app/app-images/Mobile.jpg");
        URLConnection con = url.openConnection();
        final Reader reader = new InputStreamReader(con.getInputStream());
        final BufferedReader br = new BufferedReader(reader);        
        String line = "";
        while ((line = br.readLine()) != null) {
            Log.d("tag",line+"");
        }        
        br.close();
    } // End of main 
} // End of the class //

但我得到了上面所说的异常:

01-29 18:39:28.199: WARN/System.err(2045): java.io.IOException: SSL handshake failure: I/O error during system call, Unknown error: 0

欢迎使用异步加载图像与 Apache HttpClient 或 Async HttpClient 客户端库一起正常工作的任何其他代码。 另外我不知道如何在android中进行代理设置。所以请用各自的参数为我做这件事

我已尝试按照教程进行操作,但我的图像未显示。

http://javatechig.com/android/download-image-using-asynctask-in-android

上述教程适用于 Http URL 但不适用于 Https

我希望上面教程中的代码适用于 HTTPS URL 暂时考虑服务器证书对我来说并不重要。

【问题讨论】:

标签: java android https amazon-s3 android-asynctask


【解决方案1】:

请试试这个代码

  • 主要活动
包 com.example.androidhttpsdemo; /* * * MainActivity.java * @作者桑托什·辛德 * 日期:2015 年 1 月 30 日下午 12:28:16 * */ 导入 java.io.IOException; 导入 java.io.InputStream; 导入 java.net.URL; 导入 java.net.URLConnection; 导入 javax.net.ssl.HttpsURLConnection; 导入android.app.Activity; 导入android.graphics.Bitmap; 导入android.graphics.BitmapFactory; 导入android.os.AsyncTask; 导入android.os.Bundle; 导入android.widget.ImageView; 公共类 MainActivity 扩展 Activity { //公共静态最终字符串 URL ="https://googledrive.com/host/0B_DiX4MiMa3HTHdiYVRmUHBMcW8/image1.jpg"; 公共静态最终字符串 URL="https://s3-ap-southeast-1.amazonaws.com/edt-demo-app/app-images/Mobile.jpg"; 图像视图图像视图; /** 在第一次创建活动时调用。 */ @覆盖 公共无效 onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView = (ImageView) findViewById(R.id.ImageView1); // 为 AsyncTask 的子类创建一个对象 GetXMLTask 任务 = 新的 GetXMLTask(); // 执行任务 task.execute(new String[] { URL }); } 私有类 GetXMLTask 扩展 AsyncTask { @覆盖 受保护的位图 doInBackground(String... urls) { 位图映射 = null; 对于(字符串网址:网址){ 地图=下载图片(网址); } 返回地图; } // 设置 doInBackground 返回的位图 @覆盖 protected void onPostExecute(位图结果){ imageView.setImageBitmap(结果); System.out.println("完成"); } // 从 InputStream 创建 Bitmap 并返回它 私人位图下载图像(字符串网址){ 位图位图=空; 输入流流 = null; BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inSampleSize = 1; 尝试 { 流 = getHttpConnection(url); 位图 = 位图工厂。 解码流(流,空,bmOptions); 流.close(); } 捕捉(IOException e1){ e1.printStackTrace(); } 返回位图; } // 创建 HttpURLConnection 并返回 InputStream 私有 InputStream getHttpConnection(String urlString) 抛出 IOException { 输入流流 = null; URL url = 新 URL(urlString); URLConnection 连接 = url.openConnection(); 尝试 { HttpsURLConnection httpConnection = (HttpsURLConnection) 连接; httpConnection.setRequestMethod("GET"); httpConnection.connect(); if (httpConnection.getResponseCode() == HttpsURLConnection.HTTP_OK || httpConnection.getResponseCode() == HttpsURLConnection.HTTP_NOT_MODIFIED ) { 流 = httpConnection.getInputStream(); } else { // 以防万一.. //log.d("奇怪的 HTTP 状态是:" ,httpConnection.getResponseCode()); } } 捕捉(异常前){ ex.printStackTrace(); } 返回流; } } }

【讨论】:

    【解决方案2】:

    试试这个代码...

                 try  
                 { 
                      InputStream imageURL = new URL (url).openStream();  
                      bitmap = BitmapFactory.decodeStream(imageURL);   
                 } 
                 catch (Exception e) 
                 { 
                     e.printStackTrace();
                 }  
    

    【讨论】:

      【解决方案3】:

      最好的解决方案是 Android-Universal-Image-Loader,使用非常简单。

      【讨论】:

        【解决方案4】:

        您可以简单地将 build.gradle 中的 dataBinding 设置为 true 添加 Glide Lib 以很好地加载图像

        android {
           compileSdkVersion 25
           buildToolsVersion '25.0.3'
        
           dataBinding {
               enabled = true
           }
        ...
        }
        

        并创建一个BindingAdapter,这将覆盖当前方法(在这种情况下 android:src="...") 并加载图像。

        @BindingAdapter("android:src")
        public static void setImageUrl(ImageView imageView, String url) {
            Context context = imageView.getContext();
            Glide.with(context).load(url).into(imageView);
        }
        

        现在你可以简单地在xml中传递一个url,它会加载图片,这个方法可以放在代码中的任何地方。

        <ImageView
          android:id="@+id/status_avatar"
          android:layout_width="64dp"
          android:layout_height="64dp"
          android:src="http://knightwise.com/wp-content/uploads/2014/02/android-apple-wallpaper.jpg"/>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-09-22
          • 1970-01-01
          • 2016-06-23
          • 2015-09-06
          • 1970-01-01
          • 1970-01-01
          • 2015-09-18
          相关资源
          最近更新 更多