微信第三方授权登录之Android app应用

微信OAuth2.0授权登录让微信用户使用微信身份安全登录第三方应用或网站,在微信用户授权登录已接入微信OAuth2.0的第三方应用后,第三方可以获取到用户的接口调用凭证(access_token),通过access_token可以进行微信开放平台授权关系接口调用,从而可实现获取微信用户基本开放信息和帮助用户实现基础开放功能等。
前提准备:

  1. 申请你的AppID
  2. 下载微信终端开发工具包以及签名apk
  3. 把对应的工具包放到项目内
  4. AndroidManifest.xml 设置一些权限




    步骤可以分为三步;一步是在客户端发起处理,剩下的两步是在服务器端进行的;

  5. 第一步: 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;

package com.wx.app;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tencent.mm.sdk.modelmsg.SendAuth;
import com.tencent.mm.sdk.modelmsg.SendMessageToWX;
import com.tencent.mm.sdk.modelmsg.WXMediaMessage;
import com.tencent.mm.sdk.modelmsg.WXWebpageObject;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.wx.app.util.DownLoadImage;
import com.wx.app.util.DownLoadImage.BitmapCallBack;
import com.wx.app.util.HttpUtil;
import com.wx.app.util.WXUtil;

@SuppressLint("ShowToast")
public class AppsActivity extends Activity {

    // 自己微信应用的 appId
    public static String WX_APP_ID = "";


    public static String WX_CODE = "";

    public static IWXAPI wxApi;
    public static boolean isWXLogin = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_apps);
        wxApi = WXAPIFactory.createWXAPI(this, WX_APP_ID, true);
        wxApi.registerApp(WX_APP_ID);

        findViewById(R.id.wx_login).setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                isWXLogin = true;
                SendAuth.Req req = new SendAuth.Req();
                req.scope = "snsapi_userinfo";
                req.state = "wechat_sdk_demo";
                wxApi.sendReq(req);
            }
        });

        findViewById(R.id.wx_share).setOnClickListener(new OnClickListener() {
            public void onClick(View v) {

                final SendMessageToWX.Req req = new SendMessageToWX.Req();
                WXWebpageObject webpage = new WXWebpageObject();
                // 要跳转的地址
                webpage.webpageUrl = "http://www.baidu.com";
                final WXMediaMessage msg = new WXMediaMessage(webpage);
                msg.title = "标题";
                msg.description = "要分享到微信的内容,要换行使用 \n 已经换行";
                // 网络图片地址 png 格式
                // eg: http://h.hiphotos.baidu.com/image/w%3D310/sign=58272176271f95caa6f594b7f9177fc5/aa18972bd40735fa29e06ab19c510fb30f2408a1.png
                String imageUrl = "";
                // 0:发送到朋友 1:发送到朋友圈 2:收藏
                final int shareWhat = 0;
                if (imageUrl.length() == 0) {
                    // 分享的图片不能超过32k 否则弹不出微信分享框
                    Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
                    msg.thumbData = WXUtil.bmpToByteArray(bmp, true);
                    req.transaction = buildTransaction("webpage");
                    req.message = msg;
                    req.scene = shareWhat;
                    wxApi.sendReq(req);
                } else {
                    // 主线程不能访问网络,开启线程下载图片
                    new DownLoadImage(imageUrl).loadBitmap(new BitmapCallBack() {
                        public void getBitmap(Bitmap bitmap) {
                            // 分享的图片不能超过32k 压缩图片
                            Bitmap thumbBmp = Bitmap.createScaledBitmap(bitmap, 100, 100, true);
                            bitmap.recycle();
                            msg.thumbData = WXUtil.bmpToByteArray(thumbBmp, true);
                            req.transaction = buildTransaction("webpage");
                            req.message = msg;
                            req.scene = shareWhat;
                            wxApi.sendReq(req);
                        }
                    });
                }
            }
        });
    }

    private String buildTransaction(final String type) {
        return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
    }

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

    /**
     * @methods: 获得微信用户信息
     * @author: lianzhi
     * @Date: 2015-3-5
     */
    private void loadWXUserInfo() {
        //进行传递WX_CODE与服务器端进行交互
    }

}

微信回调的类注意类名以及所在文件的位置

package com.wx.app.wxapi;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

import com.tencent.mm.sdk.modelbase.BaseReq;
import com.tencent.mm.sdk.modelbase.BaseResp;
import com.tencent.mm.sdk.modelmsg.SendAuth;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.wx.app.AppsActivity;

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AppsActivity.wxApi.handleIntent(getIntent(), this);
    }

    public void onReq(BaseReq req) {
        finish();
    }

    public void onResp(BaseResp resp) {
        switch(resp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                if(AppsActivity.isWXLogin){
                    SendAuth.Resp sendResp = (SendAuth.Resp) resp;
                    AppsActivity.WX_CODE = sendResp.code;
                    finish();
                }else{
                    Toast.makeText(this, "成功!", Toast.LENGTH_LONG).show();
                }
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                Toast.makeText(this, "取消!", Toast.LENGTH_LONG).show();
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                Toast.makeText(this, "被拒绝", Toast.LENGTH_LONG).show();
                break;
            default:
                Toast.makeText(this, "失败!", Toast.LENGTH_LONG).show();
                break;
        }
        AppsActivity.isWXLogin=false;
        finish();
    }

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

manifest的配置文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.wx.app"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
        <activity
            android:name="com.wx.app.AppsActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.wx.app.wxapi.WXEntryActivity"
            android:configChanges="orientation|keyboardHidden"
            android:exported="true"
            android:launchMode="singleTop"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.Translucent" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

最后把apk打包到手机,用微信官方生成签名的apk进行生成签名,把签名填写到微信的开放平台上。
服务前端的处理:
2. 通过code参数加上AppID和AppSecret等,通过API换取access_token:
StringBuffer buffer = new StringBuffer();buffer.append(“https://api.weixin.qq.com/sns/oauth2/access_token?appid=“+ APPID);
buffer.append(“&secret=” + SECRET);
buffer.append(“&code=” + code);
buffer.append(“&grant_type=authorization_code”);
String uri = buffer.toString();
logger.info(“uri:” + uri);
return httpGet(uri);
3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

JSONObject jobj = JSONObject.parseObject(accessText);
   if (jobj.containsKey("access_token")) {
    String accessToken = jobj.getString("access_token");
    String wxOpenId = jobj.getString("openid");
    StringBuffer buffer = new StringBuffer();
    buffer.append("https://api.weixin.qq.com/sns/userinfo?access_token="+ accessToken);
    buffer.append("&openid=" + wxOpenId);
    String uri = buffer.toString();
    String resText = httpGet(uri);
    JSONObject obj = JSONObject.parseObject(resText);
    if (obj.containsKey("openid")) {
    WxMpUser user = new WxMpUser();
    user.setOpenId(obj.getString("openid"));
    user.setNickname(obj.getString("nickname"));
    user.setSex(obj.getString("sex"));
    user.setProvince(obj.getString("province"));
    user.setCity(obj.getString("city"));
    user.setCountry(obj.getString("country"));
    user.setHeadImgUrl(obj.getString("headimgurl"));
    user.setUnionId(obj.getString("unionid"));
    return user;
    } else {
    return null;
   }
  } else {
    return null;
 }

在这里有个demo可以贡献大家,服务器端没有提供demo地址:http://download.csdn.net/detail/lamboo_cn/9471091

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值