android环境,使用URLconnetion下载https图片异常的解决方法

参考:http://m.blog.csdn.net/blog/telenewbie/44815035

问题产生的原因是https网站的证书不是Android所信任的证书。解决方案之一是去android授权的证书发证机构申请正式证书。

另外一种就是修改客户端代码,强制通过所有证书为信任。这样做会有安全漏洞的问题。

代码在Android 4.0.3的三星手机测试通过。

代码:


HttpDownloader.java


=====================================================


package com.we8log.democert;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.CertificateException;


import java.security.cert.X509Certificate;

import javax.net.ssl.*;

import android.util.Log;

public class HttpDownloader {  
    private URL url=null;  
    FileUtils fileUtils=new FileUtils();  
    public int downfile(String urlStr,String path,String fileName)  
    {  
        if(fileUtils.isFileExist(path+fileName))  
            {return 1;}  
        else{  
          
        try {  
            InputStream input=null;  
            input = getInputStream(urlStr);  
            File resultFile=fileUtils.write2SDFromInput(path, fileName, input);  
            if(resultFile==null)  
            {  
                return -1;  
            }  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
          
        }  
        return 0;  
    }  
  //由于得到一个InputStream对象是所有文件处理前必须的操作,所以将这个操作封装成了一个方法  
       public InputStream getInputStream(String urlStr) throws IOException  
       {       
           InputStream is=null;  

                url=new URL(urlStr);
                trustAllHosts(); // 开启全部证书信任
                HttpURLConnection urlConn=(HttpURLConnection)url.openConnection();  
                is=urlConn.getInputStream();  
                  

            return is;  
       }  
       
       final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
           
           public boolean verify(String hostname, SSLSession session) {
               return true;
           }
       };
      
       /**
        * Trust every server - dont check for any certificate
        */
       private static void trustAllHosts() {
           final String TAG = "trustAllHosts";
           // Create a trust manager that does not validate certificate chains
           TrustManager[] trustAllCerts = new TrustManager[] {
                   new X509TrustManager() {
                       public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                               return new java.security.cert.X509Certificate[] {};
                       }

               public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                   Log.i(TAG, "checkClientTrusted");
               }

               public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                   Log.i(TAG, "checkServerTrusted");
               }
           }
                  
           };
        
           // Install the all-trusting trust manager
           try {
               SSLContext sc = SSLContext.getInstance("TLS");
               sc.init(null, trustAllCerts, new java.security.SecureRandom());
               HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
           } catch (Exception e) {
               e.printStackTrace();
           }
       }


=======================================================================================

package com.we8log.democert;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.os.Environment;

public class FileUtils {  
    
    private String SDPATH="";  
 
    public String getSDPATH() {  
        return SDPATH;  
    }  
    public FileUtils() {  
        //SDPATH =this.getApplicationContext().getFilesDir()+"/";
        //得到当前外部存储设备的目录  
        // /SDCARD  
        //SDPATH =Environment.getRootDirectory()+"/";
        //SDPATH = Environment.getDataDirectory()+"/";
        //SDPATH = Environment.getExternalStorageDirectory() + "/";  
    }  
    /**
     * 在SD卡上创建文件
     *  
     * @throws IOException
     */  
    public File creatSDFile(String fileName) throws IOException {  
        File file = new File(SDPATH + fileName);  
        file.createNewFile();  
        return file;  
    }  
      
    /**
     * 在SD卡上创建目录
     *  
     * @param dirName
     */  
    public File creatSDDir(String dirName) {  
        File dir = new File(SDPATH + dirName);  
        dir.mkdir();  
        return dir;  
    }  
 
    /**
     * 判断SD卡上的文件夹是否存在
     */  
    public boolean isFileExist(String fileName){  
        File file = new File(SDPATH + fileName);  
        return file.exists();  
    }  
      
    /**
     * 将一个InputStream里面的数据写入到SD卡中
     */  
    public File write2SDFromInput(String path,String fileName,InputStream input){  
        File file = null;  
        OutputStream output = null;  
        try{  
//            creatSDDir(path);  
            //file = creatSDFile(path + fileName);  
            file = creatSDFile(fileName);  
            output = new FileOutputStream(file);  
            byte buffer [] = new byte[4 * 1024];  
            while((input.read(buffer)) != -1){  
                output.write(buffer);  
            }  
            output.flush();  
        }  
        catch(Exception e){  
            e.printStackTrace();  
        }  
        finally{  
            try{  
                output.close();  
            }  
            catch(Exception e){  
                e.printStackTrace();  
            }  
        }  
        return file;  
    }  

====================================================================


package com.we8log.democert;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

    public class MainActivity extends Activity {  
      
        private Button downfile=null;  
        Context context=this;
        @Override  
        public void onCreate(Bundle savedInstanceState) {
            
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);  
            downfile=(Button)findViewById(R.id.downfile);  
            downfile.setOnClickListener(new View.OnClickListener() {  
 //           downfile.setOnClickListener(new View.OnClickListener() {  
                  
                @Override  
                public void onClick(View v) {  
                    // TODO Auto-generated method stub  
                    HttpDownloader httpDownLoader=new HttpDownloader();  
                      int result=httpDownLoader.downfile("https://test.xianrongwang.com/Lemon/data/upfiles/imagScrollpic/atis/null_scrollpic_new_1446011696.png", "", context.getFilesDir()+"/test.png");
 
                   // int result=httpDownLoader.downfile("http://avatar.csdn.net/5/7/2/1_zzp_403184692.jpg", "", context.getFilesDir()+"/test.jpg");
                      if(result==0)  
                      {  
                          Toast.makeText(MainActivity.this, "下载成功!", Toast.LENGTH_SHORT).show();  
                      }  
                      else if(result==1) {  
                          Toast.makeText(MainActivity.this, "已有文件!", Toast.LENGTH_SHORT).show();  
                    }  
                      else if(result==-1){  
                          Toast.makeText(MainActivity.this, "下载失败!", Toast.LENGTH_SHORT).show();  
                      }   
                }  
            });  
        }  
      
        @Override  
        public boolean onCreateOptionsMenu(Menu menu) {  
            //getMenuInflater().inflate(R.menu.activity_main, menu);  
            return true;  
        }  
    } 


=====================================================================



activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

 <Button android:id="@+id/downfile"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="rtrtrtrtrtrt9"/>
    
</RelativeLayout>



=============================================================================
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.we8log.democert" >

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
         >
        <activity
            android:name="com.we8log.democert.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


===================================================


似乎还有第三种解决办法:


android手机自带导入用户的证书。


但是作者没有实验成功,可能因为实验服务器的证书格式不是安卓手机支持的格式。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值