新的起点

想起八年前,只身来到青岛,到现娃都能打酱油了,感觉转眼间的事.

在海尔工作八年多,差一点就能获得海尔金牌了(十年).也许是想进行一轮新的挑战,选择换份工作,换个方向.

新的起点,在PicoVR虚拟现实领域,与新的团队一起,共同创造A New Reality.

Hackpwn,Smartcare2,Markdown

我们的Smartcare在Hackpwn2015上被白冒子黑客提及,APK被反编译后分析了我们的执行流程与工作原理,但被某些媒体报道成可以被黑客任意控制家中所有电器,开门开窗。人言可畏,媒体如果都这么不负责任,胡乱来写,甚至像写神话剧本来报道科技新闻,多少人将被歪曲与误导。

Smartcare第二代也进入了最后的联合调试期,各项功能都在做最好的调整,相比第一代,更值得期待。

调整了下博客后台,之后的文章使用Markdown格式来写,再也不用担心格式乱不统一了。

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);
}

SmartCare

从14年6月开始做SmartCare的项目,差不多大半年终于上市了,京东有销

现有幸与共事多年的几个同事,专职继续做这个项目。

前途漫漫且有很多不确定性,但有我们小强的团队,相信能披荆斩棘,永往直前。

Paho Tls 双向认证

Eclipse的Paho开源项目,默认TLS只支持对MQTT服务器的单向认证,官方Service中己集成相关方法:

MqttConnectOptions conOpt;

MqttAndroidClient client;

uri = “ssl://”;

InputStream ins = this.getResources().openRawResource(R.raw.ca);//ca.bks是由ca.crt通过Keytool工具导出的

String keypassword = “123456”;

conOpt.setSocketFactory(client.getSSLSocketFactory(ins, keypassword));

实现双向认证需要自己生成SocketFactory,具体代码如下:

MqttConnectOptions conOpt;

MqttAndroidClient client;

uri = “ssl://”;

InputStream ins = this.getResources().openRawResource(R.raw.ca);//ca.bks是由ca.crt通过Keytool工具导出的

InputStream clientIns = this.getResources().openRawResource(R.raw.client); //client.p12是由clinet.crt与client.key用openssl 导出的

String keypassword = “123456”;

conOpt.setSocketFactory(get2SSLSocketFactory(clientIns,ins,keypassword,keypassword));

… …

public SSLSocketFactory get2SSLSocketFactory(InputStream clientKeyStore,

           InputStream ServerKeyStore, String clientPassword, String ServerPassword)

           throws MqttSecurityException {

       try {

           SSLContext ctx = null;

           SSLSocketFactory sslSockFactory = null;

           // for server key store

           KeyStore ts;

           ts = KeyStore.getInstance(“BKS”);

           ts.load(ServerKeyStore, ServerPassword.toCharArray());

           TrustManagerFactory tmf = TrustManagerFactory.getInstance(“X509”);

           tmf.init(ts);

           // for client key store

           KeyStore kts = KeyStore.getInstance(“PKCS12”);

           kts.load(clientKeyStore, clientPassword.toCharArray());

           KeyManagerFactory keyManager = KeyManagerFactory.getInstance(“X509”);

           keyManager.init(kts, clientPassword.toCharArray());

           // init

           ctx = SSLContext.getInstance(“tlsv1”);

           ctx.init(keyManager.getKeyManagers(), tmf.getTrustManagers(), null);

           sslSockFactory = ctx.getSocketFactory();

           return sslSockFactory;

}…

   }

其中关键在PKCS12格式证书的生成,需要使用client的crt与key

openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12

之前走了很多弯路,在这个地方使用与生成ca.bks的方法来生成client证书,总是报错:

javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x75c72988: Failure in SSL library, usually a protocol error

error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1256 0x7851af18:0x00000003)

SSL/TLS的加密码比较复杂,各种证书格式,加上需要跨平台通讯,问题比较多,在与Mosquito服务器通讯时,发现Tls的版本不对也会报错,

MqttException (0) – javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x7861ada8: Failure in SSL library, usually a protocol error

error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version (external/openssl/ssl/s23_clnt.c:741 0x71e78cf8:0x00000000)

Paho项目貌似只支持到Tlsv1,而服务器用的是Tlsv1.2,导致握手失败。

Paho使用ANT编译出错与Maven

Paho的官方库中克隆下来的mqtt client导入Eclipse竟然编译不过,给Paho Project提了一个BugBug 440052 – Paho mqttv3 client can’t be build sucessfully by defaul.

这么明显的错误,项目人员不可能不知道吧,并且他们有Daily Build,在官网都有每日编译后的版本发布。

怀疑是不是自己的编译环境有问题,仔细看了看,工程中发现Pom.xml,之前一直没接触过Maven,看了些资料发现,整个Paho项目应该是用Maven构建的,所以自己在导入Eclipse后使用ANT编译出了问题(但这的解是个问题,看官方的答复)

Maven的介绍参考这篇文章:Maven 2.0:编译、测试、部署、运行

总结下我所了解的项目编译构建工具:

1  

Make

MakeFile

C/C++

2

ANT

Build.xml

Java

3

Maven

Pom.xml

Java

4

ADT

AndroidManifest.xml

Android

5

VSTS

*.sln
*.suo

C#,VB

6

gradle

build.gradle

Java

以上可以看出来,这些工具的本质是一样的,编译规则,文件关连及项目相关信息的存储,使用工具进行编译,只是各有各的优点且都在不断进化。

可穿戴设备展

image

在青岛国际会展中心,听了一上午的大会,讲述可穿戴设备的发展,邀请嘉宾讲的风风火火,但展区确显得有些萧条,青岛这方面发展还有关注度都应该跟北上广差很多。

Android端直接使用MQTT协议与第三方PUSH服务对比

AndroidMQTT使用基于EclipsePaho项目库,Broker使用网上免费的Mosquito服务器。第三方使用Baidu云推送。从以下四个方面对比:

一,到达率对比
         在相同的网络环境(WIFI/GPRS),两者基本都能够及时收到,延迟在1S之内,测试中偶现有延时送达的,暂没有发现丢包或收不到的情况.

          二者在被进程管理软件杀死后,默认都无法自动重启,不能继续与服务器进行沟通。要做到死后重生,需要采用特殊处理,如提高Service的优先级,设置Service在内存中的驻留方式,在ServiceStop函数当中重新启动等方法。

二,所消耗的流量对比

        Android端设置心跳间隔为5分钟,测试一个小时,推送6次信息,每次平均20Bytes,检测软件上看共消耗2.3KB,按这个流量算,一个月约需要消耗1.6M的流量。

        Baidu云推送,官方给的数据是,空载流量0.8-1.2M/月。

三,功耗对比

       测试环境:使用同一台手机,仅开启Wifi(排除电话,短信等通知信息对电流的影响),设置心跳间隔为5分钟,测试其间平均发送6次推送,结果如下:

E760(Android4.0)

底电流(平均值)

10分钟平均电流(测试3轮求平均)

30分钟平均电流(测试3轮求平均)

仅开Wifi待机

4.2mA

7.2mA

6.7mA

仅开启MQTT

4.2mA

7.7mA

7.6mA

仅开启百度云推送

4.2mA

7.8mA

7.3mA

    从对比结果看,开启MQTT或云推送,对平均电流的影响不大,平均每日耗电约12~14mAh. 网上资源显示实测移动设备空载耗电每日15-50mAh。WifiGPRS3G不同网络环境可能会稍有差距。

综上:使用MQTT与第三方Push在流量及功耗上没有太多差距,测试过程中MQTT能与服务器建立稳定的长链接,并且从查找的资源看AndroidAPP基本上都是用MQTT直接做Push服务的,没有例子同时与第三方Push联合使用的,因此如果能够自建MQTT服务器的话,完成可以自己实现Push服务。

Android端第三方Push服务对比

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

 

响应速度(平均延迟)

到达率(百分比)

官方文档支持

第三方帐号

代表客户

综合评价

极光

1s

99%

支付,需要绑定

去哪,中国电信

 

百度

1s

99%

较少

支持,需要绑定CID

糗事百科

 

个推

支持,需绑定个推CID

新浪,墨迹,PPTV

 

智游

收不到

收不到

支持

 

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

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

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

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

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

出差杭州

差不多三年了,再次来到杭州,参加VIA的QiLian平台培训,严格来说算是答疑。编译,升级,驱动调试,UI修改,测试工具等内容。跟MTK相比,平台差距还有很大,很多不完善的地方,但MTK做了多少年Android,VIA的第一个AP,还能要求什么。