2017-02-10 5 views
2

私のアプリはHTTPSソースからの画像、Solar Dynamics Observatoryを使用しています。これらの画像は、Android版のAPI 21(5.0)で正常に読み込まれています(API 20も同様です)。 API 19にAPI 16(。私は私のアプリのために設定分API)からAndroidのバージョンの画像はここでのイメージのロードのコードですが、それはかなり基本的です - あなたが見ることができるように古いデバイスでPicassoライブラリのTLS 1.2を有効にする方法はありますか?

Picasso.with(this) 
       .load("https://sdo.gsfc.nasa.gov/assets/img/latest/latest_2048_HMIIC.jpg") 
       .placeholder(R.drawable.placeholdernew) 
       .error(R.drawable.errornew) 
       .into(mImageView, new com.squareup.picasso.Callback() { 
        @Override 
        public void onSuccess() { 
         mAttacher = new PhotoViewAttacher(mImageView); //this adds the zoom function after the picture is loaded successfully, so the user couldn't zoom the placeholder or error picture :) 
        } 

        @Override 
        public void onError() { 
         Log.d("Pic Error", "Loading Error"); 
        } 
       }); 

、エラーはありません私のコードで(私は思う:P)。私はSSLLabsサイトでSDOサイトをチェックしました。このサイトでは、このSDOサーバーはAPI 20より古いAndroidデバイスでTLSハンドシェイクを受け付けていないと言いました。古いAndroidバージョンでPicassoでTLS 1.2を有効にする方法はありますか?助けていただければ幸いです!事前に感謝:)

+2

OkHttpを追加した場合、[いくつかの回答](http://stackoverflow.com/q/28943660/115145)に記載されているようにTLS 1.2をサポートするようにOkHttpを設定し、Picassoに 'OkHttpClient '。私は来週初めにこのコードを試してみるつもりです。これをテストするのに役立つので、実際のURLを含めてくれてありがとうございます。 – CommonsWare

+0

ありがとうございます。画像をテストしたい場合は、太陽画像をクリックしてください(問題があれば私のアプリで2048画像と512画像を使用しています)。私は今コードを待っています:) – Hamstersztyk

答えて

4

まあ、これは動作しますが、それは醜いです。プロジェクトの依存関係で

、追加します。

compile 'com.squareup.picasso:picasso:2.5.2' 
compile 'com.squareup.okhttp3:okhttp:3.6.0' 
compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.0.2' 

を(あなたはすでに私はちょうどあなたが最新バージョンであることを確認していますpicassoライン—を有していてもよい)

次に、このクラスを追加(this answerに基づく)プロジェクト:

public static class TLSSocketFactory extends SSLSocketFactory { 

    private SSLSocketFactory internalSSLSocketFactory; 

    public TLSSocketFactory(SSLSocketFactory delegate) throws 
     KeyManagementException, NoSuchAlgorithmException { 
     internalSSLSocketFactory = delegate; 
    } 

    @Override 
    public String[] getDefaultCipherSuites() { 
     return internalSSLSocketFactory.getDefaultCipherSuites(); 
    } 

    @Override 
    public String[] getSupportedCipherSuites() { 
     return internalSSLSocketFactory.getSupportedCipherSuites(); 
    } 

    @Override 
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) 
     throws IOException { 
     return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose)); 
    } 

    @Override 
    public Socket createSocket(String host, int port) throws IOException { 
     return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); 
    } 

    @Override 
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException { 
     return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort)); 
    } 

    @Override 
    public Socket createSocket(InetAddress host, int port) throws IOException { 
     return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); 
    } 

    @Override 
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { 
     return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort)); 
    } 

    /* 
    * Utility methods 
    */ 

    private static Socket enableTLSOnSocket(Socket socket) { 
     if (socket != null && (socket instanceof SSLSocket) 
     && isTLSServerEnabled((SSLSocket) socket)) { // skip the fix if server doesn't provide there TLS version 
     ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.1", "TLSv1.2"}); 
     } 
     return socket; 
    } 

    private static boolean isTLSServerEnabled(SSLSocket sslSocket) { 
     System.out.println("__prova__ :: " + sslSocket.getSupportedProtocols().toString()); 
     for (String protocol : sslSocket.getSupportedProtocols()) { 
     if (protocol.equals("TLSv1.1") || protocol.equals("TLSv1.2")) { 
      return true; 
     } 
     } 
     return false; 
    } 
    } 

(そのクラスがpublic staticあり、そのため指名打者でありますピカソを使用しているクラスでは、

次に、あなたはそれが)、スタンドアロンのクラスにしたい場合は、単にstaticを取り除く—何か他のものの内部のネストされたクラスであることをgned、this issue commentに基づいて、このメソッドを追加します。

public X509TrustManager provideX509TrustManager() { 
    try { 
     TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
     factory.init((KeyStore) null); 
     TrustManager[] trustManagers = factory.getTrustManagers(); 
     return (X509TrustManager) trustManagers[0]; 
    } 
    catch (NoSuchAlgorithmException exception) { 
     Log.e(getClass().getSimpleName(), "not trust manager available", exception); 
    } 
    catch (KeyStoreException exception) { 
     Log.e(getClass().getSimpleName(), "not trust manager available", exception); 
    } 

    return null; 
    } 

最後に、このコードは正常に画像をダウンロードしてください:

SSLContext sslContext=SSLContext.getInstance("TLS"); 
    sslContext.init(null, null, null); 
    SSLSocketFactory noSSLv3Factory; 

    if (Build.VERSION.SDK_INT<=Build.VERSION_CODES.KITKAT) { 
     noSSLv3Factory=new TLSSocketFactory(sslContext.getSocketFactory()); 
    } 
    else { 
     noSSLv3Factory=sslContext.getSocketFactory(); 
    } 

    OkHttpClient.Builder okb=new OkHttpClient.Builder() 
     .sslSocketFactory(noSSLv3Factory, provideX509TrustManager()); 
    OkHttpClient ok=okb.build(); 

    Picasso p=new Picasso.Builder(getActivity()) 
     .downloader(new OkHttp3Downloader(ok)) 
     .build(); 

    p.load(
     "https://sdo.gsfc.nasa.gov/assets/img/latest/latest_2048_HMIIC.jpg") 
     .fit().centerCrop() 
     .placeholder(R.drawable.owner_placeholder) 
     .error(R.drawable.owner_error).into(icon); 

(あなたのプロジェクトのための正しいものと私fit()と後続の呼び出しを交換する場所)

NASAサーバーをメンテナンスしている人がいる場合は、SSLサポートをアップグレードする必要があります。言ってるだけ'。

+0

うわー、ありがとう!私は明日にそれをテストし、それが動作しているかどうかをお知らせします:) – Hamstersztyk

+0

もう一度、画像の読み込みは実際に古いデバイスで動作していますありがとう! :) – Hamstersztyk

関連する問題