Android Emulator未使用https连接到本地托管的Web服务

Android Emulator未使用https连接到本地托管的Web服务,android,web-services,https,ssl-certificate,Android,Web Services,Https,Ssl Certificate,我试图使用https安全连接调用本地网络上托管的Web服务,首先它给出了异常,即主机名未解析,因此我使用了ip地址而不是名称,现在我收到以下错误: 获取标记时出错。=javax.net.ssl.SSLException:证书中的主机名不匹配:= 我已经将中间证书和根证书添加到android可信列表中 有谁能给我一个解决方案,让我在本地网络上使用主机名而不是ip地址访问安全托管的Web服务吗?我曾经在我的同事正在做的一个项目中看到类似的错误,我们发现的原因是,如果你试图从主ui线程进行网络调用,a

我试图使用https安全连接调用本地网络上托管的Web服务,首先它给出了异常,即
主机名未解析
,因此我使用了ip地址而不是名称,现在我收到以下错误:

获取标记时出错。=javax.net.ssl.SSLException:证书中的主机名不匹配:=

我已经将中间证书和根证书添加到android可信列表中


有谁能给我一个解决方案,让我在本地网络上使用主机名而不是ip地址访问安全托管的Web服务吗?

我曾经在我的同事正在做的一个项目中看到类似的错误,我们发现的原因是,如果你试图从主ui线程进行网络调用,android系统会阻止它,尽管这项功能是无效的后来引入API,与以前一样,它工作正常。这样做是为了减少主ui线程的压力,因此我们创建了一个单独的服务,然后在其中提供了一个asynctask来进行网络调用。我不记得引入它的确切API级别,但您可以随时在goggle中检查它,以及您使用的API级别?

正如其他人提到的,您需要一些东西才能连接您的web服务:
-emulator需要知道您需要连接到的服务器的IP地址
-通过HTTPS连接的服务器名称URL必须解析为SSL证书的域

为此,您需要:

  • 装载模拟器分区
    可写
从桌面shell(例如linux,但在windows上类似,并假设Android sdk安装在
/Android sdk
)上):

其中NexusS是设备的AVD名称。您必须从命令行启动模拟器,否则在以后的步骤中会出现错误

现在打开另一个shell终端并获取emulator/system/etc/hosts文件:

cd /android-sdk/platform-tools
./adb remount
./adb pull /system/etc/hosts /tmp/
重新装载
是将分区设置为可写的。上面的
pull
命令将主机文件复制到桌面的
/tmp/hosts

从桌面编辑/tmp/hosts文件以符合您的需要,即如果Web服务为,IP为192.168.1.10:

127.0.0.1      locahost
192.168.1.10   www.example.com
然后将其推回模拟器:

cd /android-sdk/platform-tools
./adb push /tmp/hosts /system/etc/
您现在应该可以连接到web服务了

请注意,在使用自签名证书的情况下,仍然可能存在错误

下图是编辑
主机
文件之前的图像:

编辑后:

您应该使用主机名验证程序对给定主机信任android

HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 30000);
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

DefaultHttpClient httpClient = new DefaultHttpClient();

SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(httpClient.getParams(), registry);
DefaultHttpClient client = new DefaultHttpClient(mgr, httpClient.getParams());

// Set verifier      
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

现在,客户端对象上执行所需的请求。

检查此…@Dark Rider我正在尝试调用托管在本地网络而不是我的系统上的Web服务。此外,我无法从emulator浏览器查看它。请查看此链接以了解DNS查找失败的原因:请使用与主机名匹配的本地DNS,以便将主机名与此内部IP匹配。(一个主机文件可能就足够了)SSL握手将永远无法工作,除非证书的通用名称与您服务的域名匹配。。。它在web浏览器中工作的原因是,您可以覆盖安全设置,但是,在代码中,无法说“请接受此名称不匹配”。您可以在本地计算机上创建与证书的通用名称匹配的DNS(主机名)条目。。。或者创建一个证书,该证书的通用名称是您的IPAddress@Vikram好啊当我们收到这个问题时,我的朋友正在使用API级别2.3。我不确定它包含在哪个API级别中,因此您可以尝试看看它是否以这种方式对您有效。请务必让我知道它是否解决了您的问题。。。
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 30000);
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

DefaultHttpClient httpClient = new DefaultHttpClient();

SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(httpClient.getParams(), registry);
DefaultHttpClient client = new DefaultHttpClient(mgr, httpClient.getParams());

// Set verifier      
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);