Volley 开启对Https的支持,并且忽略对Hostname的检查

直接上代码:

mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext(),
new HurlStack(null, newSslSocketFactory()));

详见这篇文章,这里不在重复.

但仍有报错,

java.io.IOException: Hostname ... was not verified

证书的Hostname与实际的不匹配,历史原因不能修改证书。

别外的解决方法是让Https忽略对Hostname的Verify。但对Volley来说尝试了多种方法都不行。

之前一直使用的是apache的SSLSocketFactory,org.apache.http.conn.ssl.SSLSocketFactory

可以调用 setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER)来进行设置。

但Vollley中HurlStack使用的是 javax.net.ssl.SSLSocketFactory,没有找到可以进行设置的地方。

无耐之下,只能修改Volley的原代码,基于官方6.11日版本:

修改com.android.volley.toolbox.HurlStack的openConnection()

编译并导入测试可以正常通信,如相关资料所说,此法仅用于测试,正式使用还是很危险的。

// use caller-provided custom SslSocketFactory, if any, for HTTPS
if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) {
    ((HttpsURLConnection)connection).setHostnameVerifier(new HostnameVerifier() {
        @Override
        public boolean verify(String arg0, SSLSession arg1) {
            return true;
        }
    });
    ((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory);
}

Android端第三方Push服务对比

对比了现在比较流行的几款第三方Push服务,对比结果汇总如下:

 

响应速度(平均延迟)

到达率(百分比)

官方文档支持

第三方帐号

代表客户

综合评价

极光

1s

99%

支付,需要绑定

去哪,中国电信

 

百度

1s

99%

较少

支持,需要绑定CID

糗事百科

 

个推

支持,需绑定个推CID

新浪,墨迹,PPTV

 

智游

收不到

收不到

支持

 

响应速度与到达率为平均值,不同的地方,时间段,网络接入方式可能结果不同。目前测试的地点有青岛,杭州,网络有EGDA,WIFI。对比测试在同一手机,同一网络环境下进行。

测试过程中均有发现,无法收到Push消息及延迟问题,极光与百度会好些,发生的概率较小。

这些第三方都有自己的帐号系统,要做到准确推送,需要把这些第三方的帐号与咱们的帐号匹配。

    以JPush为例这个绑定有两个基本思路:
      1. 把绑定关系保存到 JPush 服务器端
      2. 把绑定关系保存到开发者应用服务器中
    前者,就是这里要说到的:别名与标签的功能。
    后者,则是 JPush 提供的另外一套 RegistrationID 机制。这套机制开发者需要有应用服务器来维护绑定关系,不适用于普通开发者。

综上,使用第三方推送服务,优势是使用简单,有较完善的SDK。缺点是:服务器端不可控,且需要自己做与第三方的帐号绑定。

Android与Server的交互方式

Android客户端与服务器交互方式,基于两种通信协议,四类通信方式,如下图:


【Socket与HTTP两种连接协议的区别】

1.HTTP连接使用的是”请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。

2.socket是可以监听,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。保持客户端与服务器数据的实时与同步。

【四种连接方式的区别】

1.Socket,Android端SDK原生支持,服务器端无论是Java还是.NET都有接口,需要注意的地方与普通基于Socket网络编程的一样。

2.Http/HttpClient, Android端SDK原生支持,服务器端也无其它要求,ASP,JSP,PHP都能够处理,典型的框架如SSH-JSON。Java技术的服务器主要使用HttpServlet,.net技术的服务器对应HttpHandle,但处理起来没有那么Java那么直观。Http/HttpClient可采用的数据格式协议可以是简单的String类型,也可以是JSON或XML。

3.xml rpc是使用http协议做为传输协议的rpc机制,使用xml文本的方式传输命令和数据。Android本身并不支持XML-RPC协议, 需要下载相关工具, http://code.google.com/p/android-xmlrpc/downloads/list 服务器端可参考此文章,http://www.ibm.com/developerworks/cn/webservices/ws-xml-rpc/

4.WebService,Android本身也不支持基于SOAP的WebService,需要下载相关工具http://code.google.com/p/ksoap2-android/,服务器端支持的应该比较多,如基于.NET可以使用WCF,基于Java的Axis2,Apche CXF等。

5.restful,Android可以使用Http/HttpClient接口,Server使用ASP.NET Web API实现方式。

【使用场景】

跟据两种连接协议的特点来区分,如想做一个即时聊天程序,最好使用Socket,作一个发布类的应用可以使用基于HTTP协议的各种方式,像WordPress使用的XML_PRC.

GMS引起的待机时间短

近日尼日利亚客户反馈,手机在当地纯待机也只有45个小时,我们在实验室测试的待机电流约为10mA,1800mah的电池,理论时间应该在180小时左右,这差距也有点小大了。

从客户反馈的MTK Log中看到:

03-12 15:50:56.351 248 490 D PowerManagerService: acquireWakeLock flags=0x1 tag=DownloadManager

03-12 15:50:56.359 377 17849 V DownloadManager: initiating download for http://www.gstatic.com/android/keyboard/dictionarypack/metadata.json

03-12 15:50:56.359 377 17849 I DownloadManager: Initiating request for download 161369

03-12 15:50:56.359 377 17849 D libc-netbsd: getaddrinfo: www.gstatic.com return error = 0x8 >>

03-12 15:50:56.360 377 17849 D Proxy : prefProxy:DIRECT@

03-12 15:50:56.361 377 17849 W DownloadManager: Aborting request for download 161369: no network connection available

PowerManagerService
一直在持续的获取wakeLock,从Log上看no network connection available,没有网络为什么还在不停的尝试去下载呢。

Google了一下gstatic网站是干吗用的,发现也有人遇到类似的问题,大体上是讲用于获取输入法扩展包的一个地方。想到输入法扩展包,设置当中看到确实有这么一项。但查代码没有发现原生的AndroidInputMethode有此模块。后来突然想到是后来添加了GMS包,里面的LatinImeGoogle覆盖掉了原生的LatinIme,并且多了一个APK“LatinImeDictionaryPack”

删除此DictionaryPack问题得以解决,现在待机能有10~20个小时(还有差距,看来引起功耗大的问题不止一个)。

这应该是GMS包的一个Bug,在stackoverflow有人也问题了,4.0之后的GMS包应该解决了这个问题。

手机定位技术(大话基站LBS,GPS,AGPS,WIFI定位区别)

关于基站,GPS,AGPS,GPS-ONE区别,网上有是一堆文档,这里另一视角来说明:

(Android的CDMA手机,支持GPS,AGPS,使用百度地图)

A.XX新买了一台手机(还没来得急办卡),此时开机,打开百度地图,无法获取位置信息。

1.打开GPS,经过长时间的搜星,定位成功。此为GPS定位。

2.关闭GPS,打开Wifi,连接家里的无线路由,百度地图定位成功。此为WIFI定位

3.若同时打开GPS与Wifi,则先进行Wifi定位,待GPS定好后,使用GPS定位。

B.XX终于办了卡,然后开机,打开百度地图(离线地图,未开2G/3G数据业务,未开GPS,未开Wifi),无法定位。

1.仅打开数据业务,定位成功,此为基站定位

2.又打开GPS,精确定位成功,则为AGPS定位。(网络辅助GPS定位)

总结一下,定位是按最快原则选择的。若同时开启,使用顺序如下,最终还是得靠GPS来准确定位。

WIFI > LSB > AGPS > GPS

参考文档:

科普知识:GPS,AGPS,LBS,wifi,BDS定位介绍和区别

自动编译打包的bash脚本

最近在调试一个项目,频繁的在mming,snod,copy-img,挺不方便的,写一个脚本来的快。之前用的脚本倒挺多,自己写倒挺少挺短,这次来个稍微长点的,用习惯了C++,java,感觉脚本的语法不够直观,甚至还不如Python。

#!/bin/bash

#debug app framework jni hal,snod and copy to img folder

继续阅读自动编译打包的bash脚本

GMS包与Android版本序列号

我们MT6517的项目要做国外的市场,要求在原有版本基础上添加GMS包.(理论上现有方案需要过CTS与GTS,之后向Google申请,由Google正式Release GMS包给到厂商)

同时有两个项目,一个是HE-E700,另一个叫N7100,其中N7100是从HE-E700中Fork出来的一条分支.奇怪的事情发生了,按同样的流程移植GMS包,N7100可以正常使用Google Play等服务,但HE-E700这个分支却一直报错,”意外停止”,”服务器错误”等.

花了几天的时间调试,查找问题,GoogleBaidu都没能找到原因.后来只好用比较土的办法,用二分法逐个版本验证,逐步缩小提交的范围.其间两台服务器编译了N个版本.

最终找到了原来最意想不到的地方,竟然是版本号的差异倒置.即给手机的序列号命名中,不允许有”-“号,即不能是HE-E700,只能是E700.(空格也不行.)

在devs.c的文件中 memcpy(serial_number, “HE-E700”, 8);

KSOAP2—WCF

Android想要调用WebService,两种方式,其一HttpGet,HttpPost,Restful协议,其二是通过开源的第三方组件KSOAP2.几天的尝试过程中遇到了种种挫折,但最后也终于调通了,给有兴趣的朋友分享下,以免多走弯路.

1. 使用VS2012新建WCF,默认是基于.NET4.5,实践证明各个版本的KSOAP2(包括最新的3.0.0-RC.4),都无法成功,会报各种错误. 继续阅读KSOAP2—WCF

Android添加缅语字体与Root

缅甸的客户要求手机内置缅语与输入法,小语种在android源码中没有添加.客户给出了相关的APK.其中一个是缅甸语键盘输入法,直接安装即可,但此时在编辑界面输入时无缅语输出.还有一个APK,安装运行自动重启,此时再次输入即可以正常显示缅文.

但此APK需要有Root权限,即使编译为ENG版本,依然提示设备未Root.这里省过千言万语的寻找root的过程(MTK的E-Service不回答此类Root问题),直接给出最终的Root方案.

继续阅读Android添加缅语字体与Root