微信登陆第三方应用

 

相信很多第三方应用都使用到微信登陆,今天来详细讲解微信登陆的流程及实现。

1:微信登陆都有一个点击事件:

  

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.get_verification:
            sendVerificationCode();
            break;
        case R.id.phone_register:
            Intent phoneRegisterIntent = new Intent(this, RegisterActivity.class);
            startActivity(phoneRegisterIntent);
            finish();
            break;
        case R.id.wechat_login:
            WeiXinUtil.wxLogin();
            break;
        case R.id.login_layout:
            checkThenLogin();
            break;
        default:
            break;
    }
}

2:按照1的步骤我们新建WeiXinUtil,并在其中实现wxLogin()方法

/**
 * 微信登陆
 * Created by acer-pc on 2018/8/20.
 */

public class WeiXinUtil {


    public static void wxLogin() {

        if (!WinnerApplication.mWxApi.isWXAppInstalled()) {
            ToastUtil.toast("您还未安装微信客户端");
            return;
        }
        final SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = BuildConfig.Weixin.state;
        WinnerApplication.mWxApi.sendReq(req);
    }

    /**
     * 绑定微信
     */
    public static void wxBind() {

        if (!WinnerApplication.mWxApi.isWXAppInstalled()) {
            ToastUtil.toast("您还未安装微信客户端");
            return;
        }
        final SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = BuildConfig.Weixin.state_bind;
        WinnerApplication.mWxApi.sendReq(req);
    }

    public static void wxShareImg(Bitmap bitmap, int type) {
        shareBitmapToWx(bitmap, type);
    }


    /**
     * 分享图片到微信
     * @param bmp
     * @param type
     */
    private static void shareBitmapToWx(Bitmap bmp, int type) {
        try {
            if (bmp == null) {
                ToastUtil.toast("分享图片失败");
                return;
            }
            WXImageObject imageObject = new WXImageObject(bmp);
            WXMediaMessage msg = new WXMediaMessage();
            msg.mediaObject = imageObject;

            Bitmap thumb = Bitmap.createScaledBitmap(bmp, 300, 300, true);
            bmp.recycle();
            msg.setThumbImage(thumb);

            SendMessageToWX.Req req = new SendMessageToWX.Req();
            req.transaction = "img";
            req.message = msg;
            req.scene = type;

            WinnerApplication.mWxApi.sendReq(req);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}

 

3:定义全局变量和微信申请的应用开发账号和密码

/**
 * 关于微信和APP之间的对接
 * Created by acer-pc on 2018/8/16.
 */

public class BuildConfig {

    public static class Weixin{

        //自定义两个字段,用于微信登陆和绑定的时候调用微信接口的数据
        public static final String state = "superwinner_wx_login_123";
        public static final String state_bind = "superwinner_wx_bind_123";

        //APP注册微信接口时申请的
        public static final String APP_ID = "wx04583164f67d466d";
        private static final String APP_SECRET = "6a6b5ed812b7c0b62f44e096f25a60fe";

        public static final String ACCESS_TOKEN_URL_GET = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" +
                APP_ID +
                "&secret=" +
                APP_SECRET +
                "&code=" +
                "CODE" +
                "&grant_type=authorization_code";

        public static final String ACCESS_TOKEN_VALID_URL_GET = "https://api.weixin.qq.com/sns/auth?access_token=" +
                "ACCESS_TOKEN" +
                "&openid=" +
                "OPENID";


        public static final String REFRESH_ACCESS_TOKEN_URL_GET = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" +
                APP_ID +
                "&grant_type=refresh_token&" +
                "refresh_token=" +
                "REFRESH_TOKEN";

        public static final String USER_INFO_URL_GET = "https://api.weixin.qq.com/sns/userinfo?access_token=" +
                "ACCESS_TOKEN" +
                "&openid=" +
                "OPENID";

        public static String getAccessTokenUrl(String APP_ID, String APP_SECRET, String CODE){
            return ACCESS_TOKEN_URL_GET.replace("APPID", APP_ID)
                    .replace("APPSECRET", APP_SECRET)
                    .replace("CODE", CODE);
        }
    }
}

4:微信登陆都会有一个返回的结果,需要我们自己定义

/**
 * 定义一个接受微信返回的数据的Activity
 * * Created by acer-pc on 2018/8/16.
 */

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //
        try {
            WinnerApplication.mWxApi.handleIntent(getIntent(), this);
            finish();
        } catch (Exception ex) {
            ex.printStackTrace();
            finish();
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        Log.i("微信启动", "onNewIntent");
        WinnerApplication.mWxApi.handleIntent(intent, this);
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    public void onReq(BaseReq baseReq) {
        Log.i("微信请求发起","微信请求");
    }

    @Override
    public void onResp(final BaseResp baseResp) {
        Log.i("微信返回码", ((SendAuth.Resp) baseResp).errCode + "");
        final boolean isLogin = BuildConfig.Weixin.state.equals(((SendAuth.Resp) baseResp).state);
        final boolean isBind = BuildConfig.Weixin.state_bind.equals(((SendAuth.Resp) baseResp).state);
        switch (((SendAuth.Resp) baseResp).errCode) {
            case ERR_OK:
                if (!(isLogin || isBind)) {
                    ToastUtil.toast("微信授权失败");
                    return;
                } else {
                    break;
                }
            case ERR_USER_CANCEL:
                ToastUtil.toast("用户取消");
                finish();
                return;
            case ERR_AUTH_DENIED:
                ToastUtil.toast("拒绝登陆");
                break;
            default:
                finish();
                return;
        }


        final String code = ((SendAuth.Resp) baseResp).code;

        APIConfig.getDataIntoView(new Runnable() {
            @Override
            public void run() {
                String rs = HttpUtil.GetDateFromNetByGet(BuildConfig.Weixin.ACCESS_TOKEN_URL_GET.replace("CODE", code), null);
                final AccessToken accessToken = GsonUtil.parseJson(rs, AccessToken.class);
               Log.d("AccessToken",accessToken.getAccess_token());
                if (accessToken != null && accessToken.getErrcode() == null) {
                    RuntimeConfig.accessToken = accessToken;
                    final String userRs = HttpUtil.GetDateFromNetByGet(BuildConfig.Weixin.USER_INFO_URL_GET
                                    .replace("ACCESS_TOKEN", RuntimeConfig.accessToken.getAccess_token())
                                    .replace("OPENID", RuntimeConfig.accessToken.getOpenid())
                            , null);
                    WeixinUser weixinUser = GsonUtil.parseJson(userRs, WeixinUser.class);
                    if (weixinUser != null && weixinUser.getErrcode() == null) {
                        LogUtil.i("WXEntryActivity", "微信授权成功");
                        RuntimeConfig.weixinUser = weixinUser;
                        if (isBind) {
                            APIUtil.bindWeixin(WXEntryActivity.this);
                        } else if (isLogin) {
                            APIUtil.socialLogin(WXEntryActivity.this);
                        }
                    } else {
                        ToastUtil.toast("微信授权失败");
                    }

                } else {
                    ToastUtil.toast("微信授权失败");
                }
            }
        });

        finish();
    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {

    }
}

5:定义全局的类用来保存获取到的用户信息等

**
 * 保存一些全局变量,在整个应用中使用,避免过多的网络请求加载
 * Created by acer-pc on 2018/7/26.
 */

public class APIUtil {

    private final static String APPLICATION_CACHE_PATH = WinnerApplication.getContext().getCacheDir().getAbsolutePath();

    public interface CallBack<T extends BaseResult> {
        void handleResult(T result);
    }

    /**
     * 保存用户打开APP的时候的token信息
     * @param token 用户
     */
    public static void saveToken(String token) {
        RuntimeConfig.token = token;
        String absolutePath = WinnerApplication.getContext().getCacheDir().getAbsolutePath();
        AndroidFileUtil.writeStringToFile("true", absolutePath, DataConfig.PUSH_FILE_NAME);
        AndroidFileUtil.writeStringToFile(token, absolutePath, DataConfig.TOKEN_FILE_NAME);
        RuntimeConfig.FIRST_STARTUP = true;
    }

    /**
     * 全局获取Token
     * @return token
     */
    public static String getToken() {
        if (RuntimeConfig.token != null && !"".equals(RuntimeConfig.token)) {
            return RuntimeConfig.token;
        }

        String token = AndroidFileUtil.readFileByLines(APPLICATION_CACHE_PATH + "/" + DataConfig.TOKEN_FILE_NAME);
        RuntimeConfig.token = token;

        return token;
    }

    /**
     * 清空Token
     */
    public static void clearToken() {
        RuntimeConfig.token = "";
        File file = new File(APPLICATION_CACHE_PATH + "/" + DataConfig.TOKEN_FILE_NAME);
        AndroidFileUtil.deleteFile(file);
    }

    /**
     * @return 判断是否拥有Token
     */
    public static boolean hasToken() {
        String token = getToken();
        return token != null && !"".equals(token);
    }

    /**
     * @return 当前用户是否登录
     */
    public static boolean isLogin() {
        User user = getUser();

        return user != null && user.getId() != 0;
    }


    /**
     * 设置用户信息
     */
    public static void setUser(User user) {
        RuntimeConfig.user = user;

        String userJson = GsonUtil.toJson(user);

        File diskCache = new File(APPLICATION_CACHE_PATH + "/" + DataConfig.USER_FILE_NAME);
        AndroidFileUtil.deleteFile(diskCache);

        AndroidFileUtil.writeStringToFile(userJson, APPLICATION_CACHE_PATH, DataConfig.USER_FILE_NAME);
    }

    /**
     * @return 当前登录用户的信息
     */
    public static User getUser() {
        if (RuntimeConfig.user != null) {
            return RuntimeConfig.user;
        }

        String userJson = AndroidFileUtil.readFileByLines(APPLICATION_CACHE_PATH + "/" + DataConfig.USER_FILE_NAME);
        if (!"".equals(userJson)) {
            RuntimeConfig.user = GsonUtil.parseJson(userJson, User.class);
        }

        return RuntimeConfig.user;
    }

    /**
     * 清除用户缓存
     */
    public static void clearUser() {
        File diskCache = new File(APPLICATION_CACHE_PATH + "/" + DataConfig.USER_FILE_NAME);
        AndroidFileUtil.deleteFile(diskCache);

        RuntimeConfig.user = null;
    }


    /**
     * 绑定微信
     * @param activity
     */
    public static void bindWeixin(final Activity activity) {
        final String weixinId = RuntimeConfig.weixinUser.getOpenid();

        APIConfig.getDataIntoView(new Runnable() {
            @Override
            public void run() {
                String rs = HttpUtil.GetDataFromNetByPost(APIConfig.getORIGINALAPIUrl(APIConfig.API_USER_BIND_WEIXIN),
                        new ParamsBuilder()
                                .addParam("token", APIUtil.getToken())
                                .addParam("weixinId", weixinId)
                                .getParams());
                RuntimeConfig.weixinUser = null;
                LoginResult loginResult = GsonUtil.fromJson(rs, LoginResult.class);
                if (loginResult != null && loginResult.getResult() == APIConfig.CODE_SUCCESS) {
                    RuntimeConfig.user = loginResult.getData();
                }
                activity.finish();
                ToastUtil.toastByCode(loginResult);
            }
        });
    }


    /**
     * 社交账号微信登录
     */
    public static void socialLogin(final Activity activity) {
        final String weixinId = RuntimeConfig.weixinUser.getOpenid();
        final String userName = RuntimeConfig.weixinUser.getNickname();
        final String sex = String.valueOf(RuntimeConfig.weixinUser.getSex());
        final String headImgUrl = RuntimeConfig.weixinUser.getHeadimgurl();

        APIConfig.getDataIntoView(new Runnable() {
            @Override
            public void run() {
                Map<String,String> map=new HashMap<>();
                map.put("weixinId", weixinId);
                map.put("nickName", userName);
                map.put("sex", sex);
                map.put("headImgUrl", headImgUrl);
                map.put("token",APIUtil.getToken());
                //把分页信息传过去
                String paramJson = EncryptUtil.encrypt(map);
                String url = APIConfig.getORIGINALAPIUrl(APIConfig.API_USER_SSOBYWEIXIN);
                String rs = HttpUtil.GetDataFromNetByPost(url, new ParamsBuilder().addParam("paramJson", paramJson).getParams());
                RuntimeConfig.weixinUser = null;
                LoginResult loginResult =  EncryptUtil.decrypt(rs, LoginResult.class);
                if (loginResult != null && loginResult.getResult() == APIConfig.CODE_SUCCESS) {
                    saveUserToken(loginResult.getData());
                    activity.finish();
                } else {
                    ToastUtil.toastByCode(loginResult);
                }
            }
        });

    }

    /**
     * 保存用户登录信息
     *
     * @param user 用户
     */
    public static void saveUserToken(User user) {
        RuntimeConfig.user = user;
        String absolutePath = WinnerApplication.getContext().getCacheDir().getAbsolutePath();
        AndroidFileUtil.writeStringToFile("true", absolutePath, DataConfig.PUSH_FILE_NAME);
        AndroidFileUtil.writeStringToFile(user.getToken(), absolutePath, DataConfig.TOKEN_FILE_NAME);
        RuntimeConfig.FIRST_STARTUP = true;
    }
}

6:微信登陆基本完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值