如何使用Https URL从服务器(Amazon S3)加载android中的图像?

时间:2015-01-30 04:20:20

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

我是android的初学者。 我正在研究客户端代码我必须在服务器上读取图像存储并在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)

这是示例图片的公开网址:

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

使用Asynynchronusly加载图像的任何其他适用于Apache HttpClient或Async HttP客户端库的代码都会受到欢迎。 另外我不知道如何在android中进行代理设置。所以请为我做各自的参数

我尝试了以下教程,但我的图像没有显示。

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

上面的教程适用于Http URL但不适用于Https

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

4 个答案:

答案 0 :(得分:0)

请尝试此代码

  • MainActivity
  package com.example.androidhttpsdemo;

  /*
   * 
   * MainActivity.java
   * @author Santosh Shinde
   * Date: 30/01/2015 12:28:16 PM
   * 
   */
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.URL;
  import java.net.URLConnection;

  import javax.net.ssl.HttpsURLConnection;

  import android.app.Activity;
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import android.os.AsyncTask;
  import android.os.Bundle;
  import android.widget.ImageView;

  public class MainActivity extends Activity {
      //public static final String URL  ="https://googledrive.com/host/0B_DiX4MiMa3HTHdiYVRmUHBMcW8/image1.jpg";
      public static final String URL="https://s3-ap-southeast-1.amazonaws.com/edt-demo-app/app-images/Mobile.jpg";
      ImageView imageView;

      /** Called when the activity is first created. */
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          imageView = (ImageView) findViewById(R.id.ImageView1);

          // Create an object for subclass of AsyncTask
          GetXMLTask task = new GetXMLTask();
          // Execute the task
          task.execute(new String[] { URL });
      }

      private class GetXMLTask extends AsyncTask {
          @Override
          protected Bitmap doInBackground(String... urls) {
              Bitmap map = null;
              for (String url : urls) {
                  map = downloadImage(url);
              }
              return map;
          }

          // Sets the Bitmap returned by doInBackground
          @Override
          protected void onPostExecute(Bitmap result) {
              imageView.setImageBitmap(result);
              System.out.println("finished");
          }

          // Creates Bitmap from InputStream and returns it
          private Bitmap downloadImage(String url) {
              Bitmap bitmap = null;
              InputStream stream = null;
              BitmapFactory.Options bmOptions = new BitmapFactory.Options();
              bmOptions.inSampleSize = 1;

              try {
                   stream = getHttpConnection(url);
                   bitmap = BitmapFactory.
                            decodeStream(stream, null, bmOptions);
                   stream.close();
              } catch (IOException e1) {
                   e1.printStackTrace();
              }
              return bitmap;
          }

          // Makes HttpURLConnection and returns InputStream
          private InputStream getHttpConnection(String urlString)
                                              throws IOException {
              InputStream stream = null;
              URL url = new URL(urlString);
              URLConnection connection = url.openConnection();

              try {
                   HttpsURLConnection httpConnection = (HttpsURLConnection) connection;
                   httpConnection.setRequestMethod("GET");
                   httpConnection.connect();

                   if (httpConnection.getResponseCode() == HttpsURLConnection.HTTP_OK ||
                           httpConnection.getResponseCode() == HttpsURLConnection.HTTP_NOT_MODIFIED ) {

                           stream = httpConnection.getInputStream(); 
                   } else { // just in case.. 

                            //log.d("Surprize HTTP status was: " ,httpConnection.getResponseCode()); 
                           } 
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
              return stream;
          }
      }
  }

Output

答案 1 :(得分:-1)

试试这段代码......

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

答案 2 :(得分:-1)

最佳解决方案是 Android-Universal-Image-Loader,使用起来非常简单。

答案 3 :(得分:-1)

您可以简单地将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并加载Image,这个方法可以放在代码中的任何地方。

<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"/>