Android微信授权app登陆

简介:

App应用集成第三方登陆,已经是目前常用的功能,虽然现在有服务商集成了第三方登陆,但是平时所用的也就微信和QQ,就自己看文档写了,其中也遇到了一些问题,顾写简单的记录一下。
1、申请开发者权限:
使用微信的第三方登陆功能,必须有微信开放平台开发者账号。并对要接入的第三方登陆应用进行申请,申请通过后,可以获取到应用的AppID和AppSecret,申请的时候有两个地方要注意。**一个是应用的包名,一个是应用的签名**

申请截图

2、引用资源包:
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
  或者
直接加载 lib(需要从官网下载)包
3、manifest加载权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
4、需要在Application中注册应用到微信平台:
public class ZHApplication extends Application {
    public static final String WX_APPID = "wx4683d194d3db0bba";
    public static final String WX_APPSecret = "2a2a6debce6680c9102b8d432f07a618";

    private IWXAPI _api;
    @Override
    public void onCreate() {
        super.onCreate();
        _api = WXAPIFactory.createWXAPI(this, new String(WX_APPID), true);
        _api.registerApp(new String(WX_APPID));
    }
}
5、创建WXEntryActivity:
在程序包下新建一个名为wxapi的包,并在下面新建一个名为WXEntryActivity的类,并实现IWXAPIEventHandler接口。其中微信发送给第三方应用的请求将会回调onReq方法,第三方应用发送到微信的请求的响应结果将回调nResp方法。在成功响应微信登陆请求后我会发送一个广播,并存储获得的code。code是获取access_token所必需的,具体可以参考微信的文档。

代码如下:(**注意:需要在AndroidManifest中队新添加的类进行注册,并将exported属性设置为true(表示该Activity可以被其它程序调用)**。)

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.Toast;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.ttook.wcmj.ZHConstants;
import com.ttook.wcmj.util.LogUtil;

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
    private IWXAPI api;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        api = WXAPIFactory.createWXAPI(this, new String(ZHConstants.WX_APPID_B), false);
        //将你收到的intent和实现IWXAPIEventHandler接口的对象传递给handleIntent方法
        api.handleIntent(getIntent(), this);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
        finish();
    }

    @Override
    public void onReq(BaseReq baseReq) {

    }

    @Override
    public void onResp(BaseResp baseResp) {
        String result = "";
        LogUtil.i("==WXEntryActivity==onResp==" + baseResp.errCode);
        switch (baseResp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                String code = ((SendAuth.Resp) baseResp).code;
                SharedPreferences WxSp = getApplicationContext().getSharedPreferences(ZHConstants.SpName, Context.MODE_PRIVATE);
                SharedPreferences.Editor WxSpEditor = WxSp.edit();                WxSpEditor.putString(ZHConstants.CODE,code);
                WxSpEditor.apply();
                Intent intent = new Intent();
                intent.setAction(ZHConstants.AUTH_LOGIN_ACTION);    WXEntryActivity.this.sendBroadcast(intent);
                finish();
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                result = "发送取消";
                Toast.makeText(this, result, Toast.LENGTH_LONG).show();
                finish();
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                result = "发送被拒绝";
                Toast.makeText(this, result, Toast.LENGTH_LONG).show();
                finish();
                break;
            default:
                result = "发送返回";
                Toast.makeText(this, result, Toast.LENGTH_LONG).show();
                finish();
                break;
        }
    }
}
6、微信授权:
授权流程图,官网上有,我截取了一部分,如下
![授权流程图](https://img-blog.csdn.net/20170525104121977?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHhmMDUxNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
  • 按照流程来,请求code,代码如下
     /** 开始授权*/
    private void weChatAuth() {
        if (_api == null) {
            _api = WXAPIFactory.createWXAPI(this, new String(ZHApplication.WX_APPID), true);
        }
        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "wx_login_wcmj";
        _api.sendReq(req);
    }
    
    **执行该操作之后会拉起微信打开授权登陆页面,然后你操作的结果会返回到我们第六步建立的WXEntryActivity类中,若同意请求则可以获取到code执行接下来的操作**
    
  • 通过code获取access_token,代码如下
    微信获取access_token的接口
    https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
    这里的APPID和SECRET就是我们申请应用时获得的。 
    正确返回如下:
    ![这里写图片描述](https://img-blog.csdn.net/20170525105057122?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHhmMDUxNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
    
  • 最后一步获取第三方登陆的用户个人信息
    http请求方式: GET 
    https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID 
    
    可以获取到用户的昵称,性别,城市,头像等你需要的信息
    
    protected void requestInfoMsg(final String access_token,final  String openid ){
        LoadDialog.show(_context);
        if(!NetworkUtil.isConnected(this)){
            ZHApplication.getApplication(this).showToast("网络连接有误");
            LoadDialog.dismiss(_context);
        }else{
            StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, "https://api.weixin.qq.com/sns/userinfo" ,
                    new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response) {
                            LogUtil.d("=获取个人信息=" + response);
                           try {
                JSONObject jsonObject = new JSONObject(response);
    
            String nickName = jsonObject.getString("nickname");
            String sex = jsonObject.getString("sex");
            String province = jsonObject.getString("province");
            String city = jsonObject.getString("city");
            String country = jsonObject.getString("country");
            String headimgurl = jsonObject.getString("headimgurl");
            String privilege = jsonObject.getString("privilege");
            String unionid = jsonObject.getString("unionid");
        } catch (JSONException e) {
            e.printStackTrace();
        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {
                        Message message = mHandler.obtainMessage();
                        message.what = ZHConstants.FAILUER;
                        mHandler.sendMessage(message);
                    }
                }){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
              HashMap<String, String> map = new HashMap<>();
                map.put("access_token", access_token);
                map.put("openid", openid);
                return map;
            }
        };
        getRequestQueue(_context).add(jsonObjectRequest);
    }
    }
    
7、授权过程的详细代码:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.ttook.wcmj.R;
import com.ttook.wcmj.ZHApplication;
import com.ttook.wcmj.ZHConstants;
import com.ttook.wcmj.model.WXModel;
import com.ttook.wcmj.ui.base.BaseActivity;
import com.ttook.wcmj.util.LogUtil;
import com.ttook.wcmj.util.NetworkUtil;
import com.ttook.wcmj.util.SPUtils;
import com.ttook.wcmj.widget.LoadDialog;
import com.ttook.wcmj.wxapi.WXEntryActivity;
import java.util.HashMap;
import java.util.Map;
public class ZHLoginActivity extends BaseActivity {
    private Button           _thirdLoginBut;
    private IWXAPI           _api;
    private ReceiveBroadCast _receiveBroadCast;
    private RequestQueue     _requestQueue = null;
    private Context          _context;

@Override
protected void onCreate() {
    setContentView(R.layout.activity_login);
    _context = this;
    initState();
    initReceiveBroadCast();
}

@Override
protected void initView() {
    _thirdLoginBut = getViewById(R.id.login_third_button);
}

@Override
protected void setListener() {
    _thirdLoginBut.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            weChatAuth();
        }
    });
}

@Override
protected void processLogic(Bundle savedInstanceState) {
}

public void initReceiveBroadCast(){
    _receiveBroadCast = new ReceiveBroadCast();
    IntentFilter filter = new IntentFilter();
    filter.addAction(ZHConstants.AUTH_LOGIN_ACTION);
    registerReceiver(_receiveBroadCast, filter);
}

/** 开始授权*/
private void weChatAuth() {
    if (_api == null) {
        _api = WXAPIFactory.createWXAPI(this, new String(ZHConstants.WX_APPID_B), true);
    }
    SendAuth.Req req = new SendAuth.Req();
    req.scope = "snsapi_userinfo";
    req.state = "wx_login_wcmj";
    _api.sendReq(req);
}

/**授权返回广播*/
public class ReceiveBroadCast extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        LogUtil.i("==onReceive()===action==" + intent.getAction());
        if (intent.getAction() != null && intent.getAction().equals(ZHConstants.AUTH_LOGIN_ACTION)) {
            getAccessToken();
        }
    }
}

/**
 * 单建类,全局只初始化一个对象
 * @param context
 * @return
 */
private RequestQueue getRequestQueue(Context context) {
    if (_requestQueue == null) {
        synchronized (WXEntryActivity.class) {
            if (_requestQueue == null) {
                _requestQueue = Volley.newRequestQueue(context);
            }
        }
    }
    return _requestQueue;
}

/** 获取Token等数据*/
protected void getAccessToken(){
    SharedPreferences WX_Sp = getApplicationContext().getSharedPreferences(ZHConstants.SpName, Context.MODE_PRIVATE);
    final String code = WX_Sp.getString(ZHConstants.CODE, "");
    if(!NetworkUtil.isConnected(this)){
        ZHApplication.getApplication(this).showToast("网络连接有误");
    }else{
        StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, ZHConstants.WX_ACCESS_TOKEN_URL ,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {

                        WXModel info = WXModel.parseJson(response);
                        if(info != null && TextUtils.isEmpty(info.getUnionid()) != true) {
                            Message message = mHandler.obtainMessage();
                            message.what = ZHConstants.SUCCESS_WX;
                            message.obj = info;
                            mHandler.sendMessage(message);
                        }else{
                            Message message = mHandler.obtainMessage();
                            message.what = ZHConstants.FAILUER_WX;
                            mHandler.sendMessage(message);
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {
                        Message message = mHandler.obtainMessage();
                        message.what = ZHConstants.FAILUER_WX;
                        mHandler.sendMessage(message);
                    }
                }){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                HashMap<String, String> map = new HashMap<>();
                map.put("appid", ZHApplication.WX_APPID);
                map.put("secret", ZHApplication.WX_APPSecret);
                map.put("code", code);
                map.put("grant_type", "authorization_code");
                return map;
            }
        };
        getRequestQueue(_context).add(jsonObjectRequest);
    }
}

private Handler mHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what){
            case ZHConstants.FAILUER_WX:
                showToast("微信授权登陆失败");
                break;
            case ZHConstants.SUCCESS_WX:
                WXModel info = (WXModel) msg.obj;
                String _unionID = info.getUnionid();

                wxGrantSuccessDealWith(_unionID);
                break;
            case ZHConstants.SUCCESS:

                break;
            case ZHConstants.FAILUER:
                showToast("旺财麻将管理平台登陆授权失败");
                finish();
                break;
            default:
                break;
        }
        LoadDialog.dismiss(_context);
    }
};

/**
 * 授权后的处理操作
 * @param unionId
 */
public void wxGrantSuccessDealWith(String unionId){
    if(unionId == null) unionId = "";
    LogUtil.i("put SPUtils unionid is " + unionId);
    SPUtils.put(_context,ZHConstants.LOGIN_KEY,unionId);

    Bundle bundle = new Bundle();
    bundle.putString("unionid",unionId);
    openActivity(ZHMainActivity.class,bundle);
    finish();
}

/** 获取个人信息*/
protected void requestInfoMsg(final String access_token,final  String openid ){
    LoadDialog.show(_context);
    if(!NetworkUtil.isConnected(this)){
        ZHApplication.getApplication(this).showToast("网络连接有误");
        LoadDialog.dismiss(_context);
    }else{
        StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, "https://api.weixin.qq.com/sns/userinfo" ,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        LogUtil.d("=获取个人信息=" + response);

                       try {
            JSONObject jsonObject = new JSONObject(response);

            String nickName = jsonObject.getString("nickname");
            String sex = jsonObject.getString("sex");
            String province = jsonObject.getString("province");
            String city = jsonObject.getString("city");
            String country = jsonObject.getString("country");
            String headimgurl = jsonObject.getString("headimgurl");
            String privilege = jsonObject.getString("privilege");
            String unionid = jsonObject.getString("unionid");


        } catch (JSONException e) {
            e.printStackTrace();
        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {
                        Message message = mHandler.obtainMessage();
                        message.what = ZHConstants.FAILUER;
                        mHandler.sendMessage(message);
                    }
                }){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
              HashMap<String, String> map = new HashMap<>();
                map.put("access_token", access_token);
                map.put("openid", openid);
                return map;
            }
        };
        getRequestQueue(_context).add(jsonObjectRequest);
    }
}

@Override
public void onDestroy() {
    super.onDestroy();
    if(_receiveBroadCast != null)
        unregisterReceiver(_receiveBroadCast);
}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值