Android 使Volley完美支持自定义证书的Https
其实在最早的版本里,Volley甚至是不支持https协议的,只能跑http,当然你也可以自己修改他的源码让他支持,如今volley的代码经过一些改进以后,
已经可以完美支持https协议了,无论是在2.3版本以上还是在2.3版本以下,大家可以尝试用volley去访问github 是成功的,但是你如果用volley去访问
12306这种类似的 用自定义证书的网站 就很容易失败。那我下面就把volley 代码稍作修改,让volley也可以完美支持自定义证书的https请求。
当然代码只是展示功能使用,你们可以用更优雅的方式 ----实现一个HttpStack,然后直接传你自定义好的stack即可。我这里图简便就写了个最简单
的演示代码。其实难倒是也不难,主要还是要考虑2.3版本以上和以下的两种情况。
第一步,把你的自定义证书 拷贝到res/raw/下。

第二步,稍微修改下volley的源码
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package com.android.volley.toolbox; import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.http.AndroidHttpClient;
import android.os.Build;
import android.util.Log; import com.android.volley.Network;
import com.android.volley.RequestQueue; import org.apache.http.client.HttpClient;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams; import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory; public class Volley { /**
* Default on-disk cache directory.
*/
private static final String DEFAULT_CACHE_DIR = "volley"; private Context mContext; /**
* Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
*
* @param context A {@link Context} to use for creating the cache dir.
* @param stack An {@link HttpStack} to use for the network, or null for default.
* @return A started {@link RequestQueue} instance.
*/
public static RequestQueue newRequestQueue(Context context, HttpStack stack, boolean selfSignedCertificate, int rawId) {
File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR); String userAgent = "volley/0";
try {
String packageName = context.getPackageName();
PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
userAgent = packageName + "/" + info.versionCode;
} catch (NameNotFoundException e) {
} if (stack == null) {
if (Build.VERSION.SDK_INT >= 9) {
if (selfSignedCertificate) {
stack = new HurlStack(null, buildSSLSocketFactory(context, rawId));
} else {
stack = new HurlStack();
}
} else {
// Prior to Gingerbread, HttpUrlConnection was unreliable.
// See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
if (selfSignedCertificate)
stack = new HttpClientStack(getHttpClient(context, rawId));
else {
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}
} Network network = new BasicNetwork(stack); RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
queue.start(); return queue;
} /**
* Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
*
* @param context A {@link Context} to use for creating the cache dir.
* @return A started {@link RequestQueue} instance.
*/
public static RequestQueue newRequestQueue(Context context) {
return newRequestQueue(context, null, false, 0);
} private static SSLSocketFactory buildSSLSocketFactory(Context context, int certRawResId) {
KeyStore keyStore = null;
try {
keyStore = buildKeyStore(context, certRawResId);
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = null;
try {
tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore); } catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
sslContext.init(null, tmf.getTrustManagers(), null);
} catch (KeyManagementException e) {
e.printStackTrace();
} return sslContext.getSocketFactory(); } private static HttpClient getHttpClient(Context context, int certRawResId) {
KeyStore keyStore = null;
try {
keyStore = buildKeyStore(context, certRawResId);
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (keyStore != null) {
}
org.apache.http.conn.ssl.SSLSocketFactory sslSocketFactory = null;
try {
sslSocketFactory = new org.apache.http.conn.ssl.SSLSocketFactory(keyStore);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} HttpParams params = new BasicHttpParams(); SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", sslSocketFactory, 443)); ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry); return new DefaultHttpClient(cm, params);
} private static KeyStore buildKeyStore(Context context, int certRawResId) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null); Certificate cert = readCert(context, certRawResId);
keyStore.setCertificateEntry("ca", cert); return keyStore;
} private static Certificate readCert(Context context, int certResourceID) {
InputStream inputStream = context.getResources().openRawResource(certResourceID);
Certificate ca = null; CertificateFactory cf = null;
try {
cf = CertificateFactory.getInstance("X.509");
ca = cf.generateCertificate(inputStream); } catch (CertificateException e) {
e.printStackTrace();
}
return ca;
}
}
第三步就是调用方式稍微做下修改:
其实主要就是你如果想使用自定义的证书https的时候 第三个参数记得传true,并且把证书也传进去,
当然写的优雅的话还是最好自己写个httpstack,然后volley的源码可以不用改,只需要在使用的时候
传自己的stack即可

Android 使Volley完美支持自定义证书的Https的更多相关文章
- 使Volley完美支持自定义证书的Https
其实在最早的版本里,Volley甚至是不支持https协议的,只能跑http,当然你也可以自己修改他的源码让他支持,如今volley的代码经过一些改进以后, 已经可以完美支持https协议了,无论是在 ...
- (转载)Android快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup
[置顶] [Android]快速开发偷懒必备,一句话搞定所有ViewGroup的Adapter . 支持自定义ViewGroup 标签: androidAdapter快速开发0耦合 2016-12-1 ...
- Retrofit 2.0 超能实践(一),okHttp完美支持Https传输
http: //blog.csdn.net/sk719887916/article/details/51597816 Tamic首发 前阵子看到圈子里Retrofit 2.0,RxJava(Andro ...
- Retrofit 2.0 超能实践,完美支持Https传输
http://blog.csdn.NET/sk719887916/article/details/51597816 前阵子看到圈子里Retrofit 2.0,RxJava(Android), OkHt ...
- 让个人域名下GithubPage完美支持https
让个人域名下GithubPage完美支持https 欢迎访问完美HTTPS支持的GithubPage个人博客 : https://zggdczfr.cn/ 前言 最近笔记本挂了送去维修,耽误了我的学习 ...
- Volley框架支持HTTPS请求。
第一次写帖子,嘿嘿. 最近了解到google2013IO大会出了个网络框架,正好项目也需要用到,就看了下. 最后发现接口都是HTTPS的,但是Volley默认是不支持HTTPS,网上找了好久,都没有对 ...
- 强烈推荐:Android史上最强大的自定义任务软件Tasker
强烈推荐:Android史上最强大的自定义任务软件Taskerhttp://bbs.mumayi.com/thread-28387-1-1.html(出处: 木蚂蚁手机乐园) Android上的Tas ...
- 并发编程概述 委托(delegate) 事件(event) .net core 2.0 event bus 一个简单的基于内存事件总线实现 .net core 基于NPOI 的excel导出类,支持自定义导出哪些字段 基于Ace Admin 的菜单栏实现 第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)
并发编程概述 前言 说实话,在我软件开发的头两年几乎不考虑并发编程,请求与响应把业务逻辑尽快完成一个星期的任务能两天完成绝不拖三天(剩下时间各种浪),根本不会考虑性能问题(能接受范围内).但随着工 ...
- Android线程管理之ThreadPoolExecutor自定义线程池
前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...
随机推荐
- Android View体系
- (一)初探HTML!
想自己动手做一个个人网站,因此,最近在自学PHP,主要看韩顺平老师的教学视频..将自己学习的点点滴滴记录在博客园,希望数月之后,自己可以熟练的运用PHP,也希望各位PHP高手们给予指点,不胜感激!! ...
- js截取指定字节长度的字符串
默认的截取字符串都是根据字符长度或位置截取的,典型的两个方法是substr和substring. 这样导致的问题是截取同样长度的字符串时,多字节字符(汉字等)和单字节字符(半角英文字母.半角数字)占的 ...
- adt导入已经存在于workspace中的项目
场景: Eclipse中某android项目被delete,但是并未勾选“delete project contents from disk(cannot be undone)”.删除后,下次再想打开 ...
- TestDirector创建域或工程
一.打开TestDirector 1.打开TestDirector,进入如下页面 点击左上角"Site Administrator"进入 2.在输入框里输入正确的Site Admi ...
- Struts2笔记——第一个实例HelloWorld
1.创建新的Dynamic Web项目 ------------------------------------------ 2.struts2框架配置 ------------------- ...
- C#枚举硬件设备(升级版)
原文:C#枚举硬件设备(升级版) 先取设备类型: ; } }
- iOS:UIAlertController和UIAlertAction的详解
提示框控制器:UIAlertController 提示框按钮:UIAlertAction 功能:用来提示信息,并给出一些可以进行选择的按钮来处理相应的要求. 注意:在Xcode的iOS8 SD ...
- Spring AOP术语
1.AOP术语 1)连接点(Joinpoint) 程序执行的某个特定位置:如类开始初始化前.类初始化后.类某个方法调用前.调用后.方法抛出异常后.一个类或一段程序代码拥有一些具有边界性 ...
- mysql代码里面有中文注释导致语法错误
一个简单的创建表的代码 DROP database IF exists reg_login; CREATE database reg_login; use reg_login --用户表 create ...