一、申请APPID
微信公共平台和微博分享一样,也需要申请一个ID,来作为调起微信、分享到微信的唯一标识。
申请微信APPID可以到微信平台http://open.weixin.qq.com/app/list/?lang=zh_CN上申请。具体的申请流程网站上有很详细的介绍,我这里就仅列出一些注意事项:
(1)申请APPID时的应用名字审核通过之后将不允许更改,所以申请时的应用名字一定要提前确定好。微信官方也有详细说明,如下图:
(2)应用签名问题:应用签名一定要填写正确,否则会出现第三方应用拉不起微信的情况。
首先可以下载微信官方提供的一个签名生成工具,打开这个应用输入第三方应用的包名就能拿到用于微信的应用签名。但是这里也有需要注意的地方:
1.我们平时开发使用的keystore是C:Usersliwei.android debug.keystore,而发布正式版肯定会有一个特定的keystore(比如:XXX.keystore)。因此,我们很有必要申请两个APPID,一个用于开发测试用,另一个用于正式发版。这样能够更方便平时的开发。
2.假如想使用别人的APPID或者运行别人的demo,可以按下面的步骤来做:
在eclipse中打开window—>preferences—->Android—->build如下图所示:
将别人的C:Usersliwei.android debug.keystore(微信提供的例子中有带这个debug.keystore,所以想运行微信提供的例子要在这里加载debug.keystore),在这加载进来,就可以使用了。
(3)申请成功之后的APPID如下:
二、使用微信API接口
1、微信开放平台的一些公共类
(1)微信SDK会用到的主要类的类图
上面这张图展示的是与微信通信过程中的请求类和响应类。第三方应用通过他们
附带的message字段来携带消息传输给微信进程。其中BaseResp有个内部类是ErrCode,它里面定义了几个常量字段,当我们向微信发送请求后它会作为返回字段返回到我们的应用中来,我们可以根据这个做相应的处理(比如弹个toast来提醒用户分享的状态)。
(2)Message相关的类图
上面提到过,第三方应用是通过请求类和响应类中的message字段来和微信通信的,那么下面的图就展示了Message相关类的类图:
第三方应用和微信就是通过上面的不同种类的Message对象来与微信进行通信,从而能达到想要的效果。
(3)通信相关类
上面的IWXAPI就是所说的通信类,所有与微信进行通信的工作都是他在做,我们可以通过下面的工厂类来生成一个IWXAPI对象。旁边的IWXAPIEventHandler接口是需要我们第三方应用来实现的,如果我们想处理微信的请求信息或是我们向他发请求后他返回的标识字段,我们可以按照实现这个接口(可以参考微信开放平台文档上有详细说明http://open.weixin.qq.com/document/gettingstart/android/?lang=zh_CN)。
2.1.2微信与第三方应用通信时序图
(4)第三方应用向微信发送消息时的时序图
应用只需要进行一次注册就行了,我们可以在一个Acitivity的onCreate()中注册。然后在以后的使用中只需要封装消息,让通信类发送即可。从前面的类图中可以看到,封装消息的顺序是首先生成需要发送的媒体对象,然后将媒体对象附加到消息对象中,接着建立请求对象,最后使用通信类发送即可。
在向微信发送消息的时候,会弹出一个分享到微信的弹框,包括分享到微信之后的消息展示,都是微信自己定义的UI展示,第三方应用是无法控制的(只是对不同消息类型,微信的展示也是不同的)。
下面就对代码做简单的引导性介绍,微信平台做的还是比较不错的。举一反三,就能做出来微信的对应功能了。
其对应的代码大致如下:
注册到微信
封装Message(以WXWebpageObject 为例)和发送到微信
(5)第三方应用接收微信请求信息的时序图
微信向第三方发送的请求信息分为两种:一种是第三方应用注册到微信后在聊天界面出现的应用图标(如下图所示)。然后点击这个图标能向第三方应用发送请求,第二种是针对微信的WXAppExtendObject类型的对象的,当用户点击了微信中的消息之后,微信就会去请求第三方应用完成请求。
它的时序图如下所示:
下面对第三方应用接收微信发送的消息的代码做一些简单的介绍,按照以下步骤来就可以了。
1.在工程中建立包名.wxapi的包,其中包名只的是AndroidManifest.xml下面配置的packageName;
2.在新建的包下面新建一个WXEntryActivity类继承Activity,同时实现IWXAPIEventHandler接口(前面有提到过这个接口,用来接受微信的请求和返回信息)。
3.在onCreate()中调用 mApi.handleIntent(getIntent(),this);来等待微信的回调
4.实现IWXAPIEventHandler的onReq(微信发送请求到第三方应用时,会回调到该方法)和onResp(第三方应用发送到微信的请求处理后的响应结果,会回调到该方法)方法
5.另外需要注意在AndroidManifest.xml中配置WXEntryActivity时需要加上android:exported=”true”,主要是为了使微信进程能够调用第三方应用的进程。
其代码如下:
//在onCreate()中调用handleIntent().来等待微信进程的调用。
//微信进程请求第三方应用的回调。
//第三方应用发送Message到微信之后,微信返回的状态信息。
3.使用微信API注意事项
3.1微信公共平台问题
微信作为一个公共平台,还有一些自身的问题,下面是对我碰到的问题做一些描述:
1、
第三方应用是根据微信添加的参数isappinstalled来判断接收方手机上是否已安装了APP,但是经验证发现,微信的这个判断并不准确,即有时候用户手机上安装了APP,但是isappinstalled的值却为0;有时候没装APP,isappInstalled的值又为1。已经将这个问题反映给了微信团队。
2、
测试过程中会出现这种情况,会有个别手机会出现调不起微信客户端的情况。造成这种情况的原因是微信对缩略图的大小、title、description等参数的大小做了限制,所以有可能是大小超过了默认的范围。一般情况下缩略图超出比较常见。Title、description都是文本,一般不会超过。
3、分享到朋友圈时,是直接在第三方应用上弹出了分享框(这个有区别于分享给好友),分享完成之后,通过HOME键再回到微信,发现分享框依旧存在,并且还出现在桌面上。个人猜测,由于微信分享是新开了一个线程来处理,分享完成之后进程并没有被杀死,所以通过HOME键返回微信的时候会用到该进程。这个问题已经向微信反映。
4、通过第三方应用打开微信,假如用户没登录微信,会让用户登录微信,但是登录完成之后登录框还存在,并且这个时候其实已经登录成功了。造成这个问题的原因应该和第三个问题原因相似。
5、按照微信的要求,需要在工程中新建一个”应用包名.wxapi”的包,并在其下建立一个WXEntityActivity类。那么分享完成之后可能有两种情况发生:
(1)假如没做任何处理,那么分享完成之后回到第三方应用界面会是一个黑色的界面,啥也没有。
(2)假如在WXEntityActivity类中在IWXAPIEventHandler接口的实现方法onResp()中调用finish()方法将WXEntityActivity销毁掉,那么分享完成之后将会闪过一个黑色的界面回到第三方应用。
综上,其实我们可以发现,微信分享完成之后会到WXEntityActivity这个Activity中,第一种情况,因为WXEntityActivity没有布局文件,所以就是一个黑色的界面。第二种情况,由于finish掉了WXEntityActivity 这个Activity,所以是黑了一下。
这种情况将WXEntityActivity作为应用的界面展示就没有问题了,但是正常情况下,我们都是在已有的项目上加微信分享这个逻辑,所以,代码迁移也是影响比较大的。解决方法是可以用Android系统提供的android:theme=”@android:style/Theme.NoDisplay”。
6、可以反编译下微信的源码看看。
以上的部分图片是从其它人写的博客里copy过来的。欢迎大家交流学习。
Android 第三方应用接入微信平台研究情况分享(二)
微信平台开放后倒是挺火的,许多第三方应用都想试下,毕竟可以利用微信建立起来的关系链来拓展自己的应用还是挺不错的,可以节约很多在社交方面的开销,我最近由于实习需要也在研究这个东西,不过发现网上的相关资料还是挺少的,这里把我的整个研究情况给出来,希望可以共同学习。
二、第三方应用与微信通信的时序图
2、接收微信的请求信息
前面四步和之前的“1、向微信发送消息”是一样的,不需要重复执行,这里给出来只是为了
流程的整体性。当我们注册后,应用图标会出现在微信聊天的列表中,点击加号即可去添加,
添加后,如果聊天时点击应用图标将会回调第三方应用,如上面时序图所示。这里补充一点,
当我们向微信发消息的媒体类型是appdata类型,即WXAppExtendObject对象时,好友在
收到消息时点击消息,会出现类似的回调过程,需要修改的就是此时onReq被调用时,type
为ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX而不是ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX 。
当我们在onReq方法中接到ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX
类型的消息时,如果想要把响应发回微信,可用如下代码段来实现
可以发现响应的消息对象和发请求是一样的,下面看看效果图
这是聊天窗口,前提是你已经点击加号将应用添加到下面的列表中
此时,如果点击第三方应用,会回调我们设置好的界面
这个界面是自己定义的,你可以在接到微信的请求后自定义响应界面。
说了半天,还没说到onReq方法或是前面讲的onResp方法的由来,
也就是说如果我们想要处理给微信发请求后的回馈或是响应微信的请求
应该怎么做,我们需要下面3步操作:
a. 可以在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个
WXEntryActivity类,该类继承自Activity(当然这个路径是自定义的,随便你自己)
并在manifest文件里面加上exported属性,设置为true,例如:
<activity
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleTop" >
b. 实现IWXAPIEventHandler接口,微信发送的请求将回调到onReq方法,发送
到微信请求的响应结果将回调到onResp方法
终于出现了这两个神奇的方法,可以看看他们的大致用法
<SPAN style="FONT-SIZE: 18px; FONT-FAMILY: Microsoft YaHei"> @Override
public void onReq(BaseReq req) {
switch (req.getType()) {
case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
goToGetMsg();
break;
case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
goToShowMsg((ShowMessageFromWX.Req) req);
break;
default:
break;
}
}</SPAN>
<SPAN style="FONT-SIZE: 18px; FONT-FAMILY: Microsoft YaHei"> @Override
public void onResp(BaseResp resp) {
int result = 0;
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_OK:
result = R.string.errcode_success;
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
result = R.string.errcode_cancel;
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
result = R.string.errcode_deny;
break;
default:
result = R.string.errcode_unknown;
break;
}
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
}</SPAN>
c. 在WXEntryActivity中将接收到的intent及实现了IWXAPIEventHandler接口的对
象传递给IWXAPI接口的handleIntent方法:
api.handleIntent(intent, this);
ok,这三步可以结合时序图一起来理解,都可以一一对应的。
最后给出一些注意点,也是容易混淆的,我都写过Demo验证过了,如果大家觉得有不对的,欢迎指出,欢迎讨论
1、注册是本地注册,且只需要注册一次,但是在发送的时候微信服务器会检测第三方应用的合法性
2、说白了就是在本地第三方应用将要发送的内容先发给微信进程,微信进程收到后再将消息发给自己的微信好友
3、卸载或者反注册后,第三方应用将不会出现在本机微信的可添加应用列表中
4、使用微信开放平台发送的媒体对象中,网页,音频和视频只能是网络URL,图片可发送本地路径,本地字节数据,网络URL,文件可以发送本地字节数据和本地路径,附带在媒体对象中的字节数组,微信默认会是点击则给出下载界面,下载后存储的路径是在/sdcard/Tecent/MicroMsg/本机微信帐号(一般是一串字母数字的组合体)/attachment文件夹下,这个路径不需要自己去记录,微信会在媒体对象的filepath字段中记录,此时一定注意的是当你响应微信的show请求时,媒体对象中的filedata字段是为空的,即使你在发送的时候附带在了这个字段中,如前面所说,只能用filepath这个字段。
如果要自行处理只能是appdata类型数据,理由下面给出:
appdata类型的对象唯一特殊点就只是告诉微信这个消息点击时需要调用第三方应用,而其他类型的媒体对象被点击时所显示的是微信的默认页面
5、微信根据transaction字段决定消息在聊天框中的表现以及点击后的响应,只有appdata被点击时可以调用第三方应用的进程,所触发的方法是实现了IWXAPIEventHandler接口的类的onReq方法,类型是ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX而在微信中和好友聊天时点击第三方应用图标所所触发的方法是实现了IWXAPIEventHandler接口的类的onReq方法,类型是ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX
6、微信会根据第三方应用是否注册来给出应用安装的信息,比如传给微信好友一个音频消息时,当好友点击那个消息,微信会以一个WebView来load音频消息中的URL,不过在此前会在URL后面附加一些微信定义的信息,其中就会包括一个字段是isInstalled有关微信包装后的URL的具体格式,我们可以将网络断开,然后再去点击,这时自然就出现了那个经典界面,你也就可以看到URL的真面目了因为我自己写的demo都在实习结束后丢失了,所以给一个官方的demo下载,如果有不清楚的可以交流
谢谢合作,希望共同学习。