1. 程式人生 > >Android 微信登入授權、微信分享

Android 微信登入授權、微信分享

1.先去微信開放平臺註冊賬號,然後建立應用,簽名工具下載(在頁面最下面),不細說。

建立成功得到appid和secret(註冊到微信、獲取引數什麼的都會用到)

有個注意點,就是新增應用的時候會要簽名,你測試的簽名跟線上的簽名不一樣,會出現測試環境下可以調起微信,但是線上釋出的不行,原因就是簽名的問題,注意及時更換。

2.配置環境,新增依賴

dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
}
或
dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}
(其中,前者包含統計功能)
3.新增許可權
<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.註冊到微信(在需要的地方呼叫,比如onCreate)
private static final String APP_ID = "wx......";
    private IWXAPI api;

    private void regToWx() {
        api = WXAPIFactory.createWXAPI(this, APP_ID, true);
        api.registerApp(APP_ID);
    }

5.呼叫微信登入授權
private void wxLogin() {
        // send oauth request
        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "wechat_sdk_demo_test";
        api.sendReq(req);
    }
6.在包名下建立wxapi包和WXEntryActivity類(繼承Activity並實現IWXAPIEventHandler介面)


public class WXEntryActivity extends Activity implements IWXAPIEventHandler

WXEntryActivity是微信回撥的一個類,通常給個透明的主題或者處理完業務邏輯就直接finish。

這個回撥是有點繞的(用第三方整合的話就沒有這麼麻煩...),需要在回撥中拿到code,然後再根據code去獲取AccessToken,然後再根據AccessToken和OpenId去獲取UserInfo。(根據固定的url和引數去請求就能拿到,下面的程式碼也可以直接用,改改引數就行,請求方式也沒有特別要求,官網要求get,反手一個post也拿到了...)

在onCreate中

// 通過WXAPIFactory工廠,獲取IWXAPI的例項
        api = WXAPIFactory.createWXAPI(this, GlobalConstant.APP_ID, false);
        api.handleIntent(getIntent(), this);

// 微信傳送請求到第三方應用時,會回撥到該方法
    @Override
    public void onReq(BaseReq baseReq) {
        LogUtil.i("onReq" + baseReq.getType());
    }
// 第三方應用傳送到微信的請求處理後的響應結果,會回撥到該方法
    @Override
    public void onResp(BaseResp baseResp) {

        // baseresp.getType 1:第三方授權, 2:分享
//        Toast.makeText(this, "baseresp.getType = " + baseResp.getType(), Toast.LENGTH_SHORT).show();

        int result = 0;
        switch (baseResp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                result = R.string.errcode_success;//傳送成功
                String code = ((SendAuth.Resp) baseResp).code;
                LogUtil.i(code);
                getAccessToken(code);
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL://傳送取消
                result = R.string.errcode_cancel;
                finish();
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED://傳送被拒絕
                result = R.string.errcode_deny;
                break;
            case BaseResp.ErrCode.ERR_UNSUPPORT:
                result = R.string.errcode_unsupported;//不支援錯誤
                break;
            default:
                result = R.string.errcode_unknown;//傳送返回
                break;
        }
        Toast.makeText(this, result, Toast.LENGTH_LONG).show();
    }
/**
     * @param code 根據code再去獲取AccessToken
     */
    private void getAccessToken(String code) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
        HttpUtil httpUtil = new HttpUtil();
        Map<String, String> params = new HashMap<>();
        params.put("appid", GlobalConstant.APP_ID);
        params.put("secret", GlobalConstant.SECRET);
        params.put("code", code);
        params.put("grant_type", "authorization_code");
        httpUtil.postRequest(url, params, new MyStringCallBack() {

            @Override
            public void onError(Call call, Exception e, int id) {
                super.onError(call, e, id);
            }

            @Override
            public void onResponse(String response, int id) {
                LogUtil.i(response);
                AccessToken mAccessToken = GsonUtil.GsonToBean(response, AccessToken.class);
                getUserInfo(mAccessToken.access_token, mAccessToken.openid);
            }
        });

    }
/**
     * @param access_token 根據access_token再去獲取UserInfo
     */
    private void getUserInfo(String access_token, String openid) {
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
        HttpUtil httpUtil = new HttpUtil();
        Map<String, String> params = new HashMap<>();
        params.put("access_token", access_token);
        params.put("openid", openid);
        httpUtil.postRequest(url, params, new MyStringCallBack() {

            @Override
            public void onError(Call call, Exception e, int id) {
                super.onError(call, e, id);
            }

            @Override
            public void onResponse(String response, int id) {
                LogUtil.i(response);
                WXUserInfo mWXUserInfo = GsonUtil.GsonToBean(response, WXUserInfo.class);
                ......
                finish();
            }
        });
    }

到此登入授權就結束了

7.微信分享

關於分享的介紹:官方文件,以分享網頁為例

private void shareWebPage() {
        //初始化一個WXWebpageObject物件,填寫url
        WXWebpageObject wxWebpageObject = new WXWebpageObject();
        wxWebpageObject.webpageUrl = "www.baidu.com";

        //用WXWebpageObject物件初始化一個WXMediaMessage物件,填寫標題和描述
        WXMediaMessage wxMediaMessage = new WXMediaMessage(wxWebpageObject);
        wxMediaMessage.title = "網頁標題";
        wxMediaMessage.description = "網頁描述";
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.icon);//圖示
        wxMediaMessage.thumbData = bmpToByteArray(bitmap, true);

        //構造一個Req
        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = buildTransaction("webpage");//transaction欄位用於唯一標示的一個請求
        req.message = wxMediaMessage;
        req.scene = SendMessageToWX.Req.WXSceneSession;//傳送到聊天介面——WXSceneSession

        //呼叫api介面傳送資料到微信
        api.sendReq(req);

    }

附上兩個上面用到的方法:

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

    public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
        if (needRecycle) {
            bmp.recycle();
        }
        byte[] result = output.toByteArray();
        try {
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
關於分享型別:
傳送到聊天介面——WXSceneSession
傳送到朋友圈——WXSceneTimeline
新增到微信收藏——WXSceneFavorite

需要就都寫上

流程稍微繁瑣,但是沒有難度,很多人都說官方文件寫的不清不楚,畢竟寫文件的人跟沒用過的人視角不一樣,所以還是多看看文件吧。