http://blog.csdn.net/lowprofile_coding/article/details/78004224
微信sdk现在支持Android Studio在线引用了,之前都是添加jar的方法。需要访问微信的接口获取用户信息,所以把我们之前封装的okhttp也一起在线引用。okhttp需要在自定义的Application中初始化这个我就不贴代码了。之前已经讲过很多次。在app/build.gradle文件dependencies标签中加入以下两行代码:
compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
compile 'com.ansen.http:okhttpencapsulation:1.0.1'
需要用到网络,所以在AndroidManifest.xml文件中加入网络权限:
<uses-permission android:name="android.permission.INTERNET" />
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录之后信息在这里显示"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_nickname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="昵称:"/>
<TextView
android:id="@+id/tv_age"
android:layout_below="@+id/tv_nickname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="年龄:"/>
</RelativeLayout>
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="微信登录"/>
<Button
android:id="@+id/btn_share_friend_circle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="分享到朋友圈"/>
<Button
android:id="@+id/btn_share_friend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="分享给好友"/>
<Button
android:id="@+id/btn_pay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="微信支付"/>
</LinearLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
布局文件很简单,就LinearLayout里面放了几个TextView,跟几个按钮。
WeiXin.java 用于EventBus来传送消息,微信sdk有个很奇怪的地方,就是不管登录、分享、支付之后都得用一个Activity来接收,所以我们还得从接收的那个activity把结果信息通过EventBus传递给MainActivity。虽然用广播也能实现,但是个人喜欢用EventBus,使用灵活。简单轻量。
public class WeiXin {
private int type;
private int errCode;
private String code;
public WeiXin() {
}
public WeiXin(int type,int errCode, String code) {
this.type = type;
this.errCode=errCode;
this.code = code;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public int getErrCode() {
return errCode;
}
public void setErrCode(int errCode) {
this.errCode = errCode;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
Constant.java 常量类,微信appid跟secret的值用两个常量保存。为了保护隐私这两个值我已经修改过。
public class Constant {
public static String WECHAT_APPID="wxda6db2aec81389af";
public static String WECHAT_SECRET="8fed5a2d510022587ef8a6194c965be3";
}
MainActivity.java 全部代码贴出来比较乱,暂时贴出MainActivity部分代码。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private IWXAPI wxAPI;
private TextView tvNickname,tvAge;
public static final int IMAGE_SIZE=32768;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
wxAPI = WXAPIFactory.createWXAPI(this,Constant.WECHAT_APPID,true);
wxAPI.registerApp(Constant.WECHAT_APPID);
findViewById(R.id.btn_login).setOnClickListener(this);
findViewById(R.id.btn_share_friend_circle).setOnClickListener(this);
findViewById(R.id.btn_share_friend).setOnClickListener(this);
findViewById(R.id.btn_pay).setOnClickListener(this);
tvNickname= (TextView) findViewById(R.id.tv_nickname);
tvAge=(TextView) findViewById(R.id.tv_age);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_login:
login();
break;
case R.id.btn_share_friend_circle:
share(true);
break;
case R.id.btn_share_friend:
share(false);
break;
case R.id.btn_pay:
showToast("微信支付需要服务器支持");
break;
}
}
/**
* 这里用到的了EventBus框架
* @param weiXin
*/
@Subscribe
public void onEventMainThread(WeiXin weiXin){
Log.i("ansen","收到eventbus请求 type:"+weiXin.getType());
if(weiXin.getType()==1){
getAccessToken(weiXin.getCode());
}else if(weiXin.getType()==2){
switch (weiXin.getErrCode()){
case BaseResp.ErrCode.ERR_OK:
Log.i("ansen", "微信分享成功.....");
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
Log.i("ansen", "微信分享取消.....");
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
Log.i("ansen", "微信分享被拒绝.....");
break;
}
}else if(weiXin.getType()==3){
if(weiXin.getErrCode()==BaseResp.ErrCode.ERR_OK){
Log.i("ansen", "微信支付成功.....");
}
}
}
..........
public void showToast(String message){
Toast.makeText(this,message,Toast.LENGTH_LONG).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- onCreate 注册EventBus,通过WXAPIFactory创建IWXAPI类,并且注册appid,给四个按钮按钮设置点击事件。查找显示名字跟年龄的两个TextView。
- onClick 点击事件监听,根据id来判断点击不同的按钮,跳转到相应的方法,这些方法没贴出来来,等会单独讲。
- onEventMainThread(WeiXin weiXin) 用来接收消息,这个方法有个参数,用来判断类型,就是我们用EventBus发送时参数必须是WeiXin类型。首先判断type,是登录还是分享还是支付。登录成功情况下会获取到code,根据code然后我们就能获取到微信用户信息。
- showToast Toast提示
- onDestroy 取消EventBus注册
微信登录
微信登录流程有以下三个步骤:
- 微信授权登陆
- 根据授权登陆code 获取该用户token
- 根据token获取用户资料
当我们点击登录按钮的时候,调用的是login方法。这个方法就在MainActivity里面。就是给微信发起一个登录请求,弹出一个授权界面。
public void login(){
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = String.valueOf(System.currentTimeMillis());
wxAPI.sendReq(req);
}
在你的包名相应目录下新建一个wxapi目录,然后在wxapi目录下新增一个WXEntryActivity类,用来接收登录授权以及分享时微信的回调信息。这个类继承自Activity,需要实现IWXAPIEventHandler接口。
package com.ansen.shoenet.wxapi;
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
private IWXAPI wxAPI;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
wxAPI = WXAPIFactory.createWXAPI(this,Constant.WECHAT_APPID,true);
wxAPI.registerApp(Constant.WECHAT_APPID);
wxAPI.handleIntent(getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent){
super.onNewIntent(intent);
wxAPI.handleIntent(getIntent(),this);
Log.i("ansen","WXEntryActivity onNewIntent");
}
@Override
public void onReq(BaseReq arg0) {
Log.i("ansen","WXEntryActivity onReq:"+arg0);
}
@Override
public void onResp(BaseResp resp){
if(resp.getType()== ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX){
Log.i("ansen","微信分享操作.....");
WeiXin weiXin=new WeiXin(2,resp.errCode,"");
EventBus.getDefault().post(weiXin);
}else if(resp.getType()==ConstantsAPI.COMMAND_SENDAUTH){
Log.i("ansen", "微信登录操作.....");
SendAuth.Resp authResp = (SendAuth.Resp) resp;
WeiXin weiXin=new WeiXin(1,resp.errCode,authResp.code);
EventBus.getDefault().post(weiXin);
}
finish();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
onCreate、onNewIntent、onReq这三个方法是固定写法。onResp方法接收微信结果信息,首先判断类型,根据不同的类型去封装WeiXin对象,如果是登录操作,把code传入进去,然后把封装好的WeiXin对象通过EventBus发送出去。MainActivity的onEventMainThread方法就会接收到这个消息。最后调用finish关闭当前的activity。
WXEntryActivity记得在AndroidManifest.xml中注册
<activity
android:exported="true"
android:name=".wxapi.WXEntryActivity"/>
继续回到首页的onEventMainThread,如果登录类型调用getAccessToken(),并且传入code。根据code获取access_token,这个url是微信公开的,需要传入三个参数,appid、secret、code。请求成功之后会返回access_token跟openid等信息。
public void getAccessToken(String code){
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
"appid="+Constant.WECHAT_APPID+"&secret="+Constant.WECHAT_SECRET+
"&code="+code+"&grant_type=authorization_code";
HTTPCaller.getInstance().get(WeiXinToken.class, url, null, new RequestDataCallback<WeiXinToken>() {
@Override
public void dataCallback(WeiXinToken obj) {
if(obj.getErrcode()==0){
getWeiXinUserInfo(obj);
}else{
showToast(obj.getErrmsg());
}
}
});
}
获取到access_token跟openid之后继续调用getWeiXinUserInfo方法获取用户信息。这样就能取到当前微信app登录的用户一些信息。有昵称、年龄、头像地址、语言等基本信息。在企业开发中,到了这一步就可以拿着这些信息调用自己服务器的登录接口。当然我们这边就把昵称跟年龄给TextView显示下。
public void getWeiXinUserInfo(WeiXinToken weiXinToken){
String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+
weiXinToken.getAccess_token()+"&openid="+weiXinToken.getOpenid();
HTTPCaller.getInstance().get(WeiXinInfo.class, url, null, new RequestDataCallback<WeiXinInfo>() {
@Override
public void dataCallback(WeiXinInfo obj) {
tvNickname.setText("昵称:"+obj.getNickname());
tvAge.setText("年龄:"+obj.getAge());
Log.i("ansen","头像地址:"+obj.getHeadimgurl());
}
});
}
WeiXinToken跟WeiXinInfo这两个实体类就不贴代码了,WeiXinToken用来映射获取访问token接口返回的json。WeiXinInfo用来映射获取用户接口返回的json。
微信分享
分享有两种分享到朋友圈跟分享给好友,统一调用share方法。传入一个boolean类型来判断是否分享到朋友圈。