android實現(xiàn)微信聯(lián)合登錄開發(fā)

隨著現(xiàn)在社交app的越來越普及捞挥,微信球化,QQ,微博幾乎成了我們每個人的手機必備牵囤,而且第三方應用也越來越多厕倍,不是每個用戶都想為你的應用注冊一個獨立帳號的歌逢,所以聯(lián)合登錄也就顯得尤為重要旅择,成了我們不得不掌握的開發(fā)要點成艘,但你要用微信等帳號實現(xiàn)聯(lián)合登錄,人家也有要求哆档,就是你必須遵守OAuth2.0協(xié)議標準(https://oauth.net/2/)就行。

接下來我們就以android studio為平臺住闯,介紹下接入微信的整個流程:

這里有一個官方參考資料:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=6bfe3acd2969037c7217667f24f8eeaf714e5113&lang

那么在接入之前瓜浸,我們還有一些準備工作要做:

1):登錄微信開放平臺澳淑,完成賬號申請:https://open.weixin.qq.com

2):提交app完成審核,并開通相應權(quán)限:

image.png

在提交app完成審核的過程中插佛,我們需要提供app的包名與簽名:

包名就是我們創(chuàng)建app時候的名稱杠巡,可以通過manifest.xml和build.gradle中查看,如在manifest.xml中:

<?xml version="1.0" encoding="utf-8"?>
<manifest 
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yeejay.reader"
>

...

在build.gradle中:

defaultConfig {
    applicationId "com.yeejay.reader"
    ...
}

如果manifest.xml與build.gradle中不一致雇寇,將以build.gradle中的聲明為準:

應用簽名的獲取會有一些麻煩氢拥,因為我們需要通過簽名工具對我們的應用進行簽名,如果不進行簽名锨侯,每次安裝apk時android平臺會為我們生成默認簽名嫩海,由于平臺的不一致性,導致我們的apk裝到不同的手機上簽名不一致囚痴,最后導致無法正常使用微信登錄與分享功能叁怪,所以我們要提前做好統(tǒng)一簽名,整個簽名流程如下:

(1)點擊 build ---> Generate Signed Apk... ---> 選擇app module ---> 填寫生成keystore.jks的目錄深滚,密鑰奕谭,有效期等信息;

(2)將生成的keystore.jks文件拷貝到project目錄下的app目錄下痴荐;

(3)在build.gradle文件中進行配置血柳,代碼如下:

signingConfigs {

    release {
        storeFile file('keystore.jks')
        storePassword 'xxx'
        keyAlias 'xxx'
        keyPassword 'xxx'
    }
}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
    }

    debug {
        signingConfig signingConfigs.release
    }
}

將配置中的xxx改為生成keystore.jks時的密碼信息;

(4)Sync同步下項目代碼生兆,完成后在右邊的Gradle projects/app/build目錄下雙擊assembleDebug或assembleRelease即可生成對應版本帶有簽名的apk难捌。

(5)下載apk簽名檢測工具:
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319167&token=&lang=zh_CN
在最下面有一個簽名生成工具,單擊下載進行下載皂贩;

(6)將下載的apk簽名工具安裝到手機上栖榨,將之前生成的帶有簽名認證的apk也裝到手機上,打開簽名工具apk,如下圖:

image.png

輸入包名明刷,點擊按鈕生成對應的數(shù)字簽名;

(7) 將包名與數(shù)字簽名注冊到我們的app審核過程中婴栽;

(8)漫長的等待...,也許是兩三天辈末,也許一兩個禮拜愚争。當我們的應用申請通過時,微信開放平臺會返回給我們APP_ID與APP_SECRET信息挤聘。

當應用審核通過后轰枝,就到我們的代碼實施階段了,不過在寫代碼之前组去,我們先來了解一下OAuth2.0它的一個認證流程:

image.png

整個過程的交互一共七個流程鞍陨,當用戶使用第三方應用請求微信登錄時,此時會調(diào)起微信登錄確認頁面,并請求微信OAuth2.0進行授權(quán)诚撵,當用戶確認登錄時缭裆,這時微信平臺會拉起我們的第三方應用,并將帶有臨時票據(jù)的信息返回給我們的第三方應用寿烟,當我們的應用拿到微信的臨時票據(jù)時澈驼,我們就可以根據(jù)它的票據(jù)的code信息,再加上我們應用的appId與appSecret信息換取access_token筛武。當然缝其,為了用戶帳號信息的保存,這個過程一般都是由我們的第三方應用的服務(wù)器完成的徘六,我們只需要將我們的code傳給我們的服務(wù)器内边,由服務(wù)器最終完成與微信平臺的token換取。

接下來就是開始寫代碼了硕噩,首先我們需要下載微信的sdk包假残,在build.gradle中,添加下面一行代碼:

dependencies {

...

compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'

...

}

sync炉擅,將會下載我們最新的sdk版本辉懒。如果下載失敗我們也可以使用離線包,添加到app/lib目錄中谍失,并添加引用即可(由于前段時間jCenter下架了微信的sdk眶俩,導致開發(fā)的過程中發(fā)現(xiàn)不能直接使用,這時候可以考慮在lib中添加即可)快鱼;

根據(jù)微信開發(fā)平臺的官方要求颠印,調(diào)起微信登錄的處理邏輯必須放在我們應用的包名.wxapi目錄下,否則會報錯抹竹。這點可以參考微信提供的官方sdkDemo线罕,https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319167&token=&lang=zh_CN 在范例代碼進行下載。不過這里下載的代碼可能會因為編碼的原因窃判,導致漢語注釋變成了混亂字符钞楼,后來將UTF-8編碼改為GBK就OK了。

我們看一下代碼的實現(xiàn)邏輯:

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

public static final String APP_ID = "xxxxxxxxxx";
public static final String APP_SECRET = "xxxxxxxxxx";
private static final String WEIXIN_SCOPE = "snsapi_userinfo";
private static final String WEIXIN_STATE = "login_wx";

private IWXAPI api;
private SendAuth.Req req;

private TextView loginWx;
private User user;
private String wxCode;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.login_wx);
    loginWx = (TextView) findViewById(R.id.login_wx);
    api = WXAPIFactory.createWXAPI(this, APP_ID, false);
    api.registerApp(APP_ID);

    try {
        api.handleIntent(getIntent(), this);
    } catch (NullPointerException e) {
        e.printStackTrace();
    }

    initListener();
}

private void initListener() {
    loginWx.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            sendAuth();
        }
    });
}

private void sendAuth() {
    req = new SendAuth.Req();
    req.scope = WEIXIN_SCOPE;
    req.state = WEIXIN_STATE;
    api.sendReq(req);
}

@Override
public void onReq(BaseReq baseReq) {
}

@Override
public void onResp(BaseResp baseResp) {
    int type = baseResp.getType();
    if (type == 1) {
        // 登錄
    SendAuth.Resp sendAuthResp = (SendAuth.Resp) baseResp;
    wxCode = sendAuthResp.code;
    String state = ((SendAuth.Resp) baseResp).state;
    int errCode = baseResp.errCode;
    Intent intent = new Intent(WXEntryActivity.this, HomeActivity.class);
    intent.putExtra("login", "login");
    intent.putExtra("wxCode", wxCode);
    startActivity(intent);
    YeeUtils.animOpenActivity(this);
    finish();
    } 
}
    
@Override
public void finish() {
    super.finish();
    YeeUtils.animCloseActivity(this);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    api.unregisterApp();
}
}

要實現(xiàn)微信登錄的功能袄琳,我們的代碼就必須實現(xiàn)IWXAPIEventHandler接口询件,實現(xiàn)onReq()與onResp()接口,首先我們要在activity創(chuàng)建的時候需要進行一些初始化的操作唆樊,這個照寫就是:

api = WXAPIFactory.createWXAPI(this, APP_ID, false);
api.registerApp(APP_ID);

try {
    api.handleIntent(getIntent(), this);
} catch (NullPointerException e) {
    e.printStackTrace();
}

當我們進行微信登錄時宛琅,整個認證流程也就從sendAuth()開始了,當調(diào)起微信登錄并確認后逗旁,這個時候微信sdk會調(diào)起我們的當前activity并觸發(fā)onResp()回調(diào)嘿辟,并傳回code信息,這時候我們就可以將接下來的處理交給我們的服務(wù)器,由它完成對微信token的換取红伦。

當然如果你想自己實現(xiàn)對微信token的獲取以及接下來的操作介陶,也是可以的,不過不建議這樣使用色建,下面就是獲取token的代碼:

private void getResult(String code) {
    String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
            + APP_ID
            + "&secret="
            + APP_SECRET
            + "&code="
            + code
            + "&grant_type=authorization_code";
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, null, new SuccessResponse(), new ErrorListener());
    StudyApplication.getInstance().newRequestQueue(this).add(request);
}

class SuccessResponse implements Response.Listener<JSONObject> {

    @Override
    public void onResponse(JSONObject response) {
 
        if (null != response) {
            String openid = null;
            try {
                openid = response.getString("openid")
                        .toString().trim();
            String access_token = response
                    .getString("access_token").toString().trim();          
               SharePreferenceHelper.putValue(getApplicationContext(), "access_token", access_token);
                getUID(openid, access_token);
            }
            catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
}

通過這一步那么我們就拿到了用戶的token信息,使用token我們就可以獲取到用戶信息舌缤,包括昵稱箕戳,性別,頭像国撵,地址等信息陵吸,我們接下來看getUid()中的實現(xiàn):

private void getUID(final String openId, final String accessToken) {
    String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openId;
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, null, new UIDSuccessResponse(), new ErrorListener());
    StudyApplication.getInstance().newRequestQueue(this).add(request);
    }

class UIDSuccessResponse implements Response.Listener<JSONObject> {

        @Override
        public void onResponse(JSONObject response) {
            if (response == null) {
                return;
            }
            String nickname = null;
            nickname = response.optString("nickname");
            String unionid = response.optString("unionid");
            String headUrl = response.optString("headimgurl");
            SharePreferenceHelper.putValue(getApplicationContext(), "nickname", nickname);
            SharePreferenceHelper.putValue(getApplicationContext(), "photourl", headUrl);
            SharePreferenceHelper.putValue(getApplicationContext(), "uin", unionid);
            if (user == null) {
                user = new User();
            }
            user.setUin(unionid);
            user.setNickName(nickname);
            user.setHeadImgUrl(headUrl);

            ...
        }
    };

當拿到用戶的私人信息后,我們就完成了整個流程介牙,但這些信息不應該由我們自己處理壮虫,所以當需要獲取用戶信息時,我們應該請求我們自己的服務(wù)器环础,然后由服務(wù)器再去請求微信服務(wù)器囚似,這樣的流程才是安全可靠的。

除了微信登錄线得,微信sdk還集成了微信好友分享饶唤,朋友圈分享,小程序分享(比較早的版本是沒有的...)等功能贯钩,分享內(nèi)容包括圖片募狂,文本,網(wǎng)頁等角雷,這就看我們的需求了祸穷,分享這塊我就不寫了,大家可以參考下官方的sdkDemo關(guān)于分享的代碼勺三。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末雷滚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子檩咱,更是在濱河造成了極大的恐慌揭措,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刻蚯,死亡現(xiàn)場離奇詭異绊含,居然都是意外死亡,警方通過查閱死者的電腦和手機炊汹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門躬充,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事充甚∫哉” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵伴找,是天一觀的道長盈蛮。 經(jīng)常有香客問我,道長技矮,這世上最難降的妖魔是什么抖誉? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮衰倦,結(jié)果婚禮上袒炉,老公的妹妹穿的比我還像新娘。我一直安慰自己樊零,他們只是感情好我磁,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著驻襟,像睡著了一般夺艰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上沉衣,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天劲适,我揣著相機與錄音,去河邊找鬼厢蒜。 笑死霞势,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的斑鸦。 我是一名探鬼主播愕贡,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼巷屿!你這毒婦竟也來了固以?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嘱巾,失蹤者是張志新(化名)和其女友劉穎憨琳,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旬昭,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡篙螟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了问拘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片遍略。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖绪杏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蕾久,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布僧著,位于F島的核電站,受9級特大地震影響霹抛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜杯拐,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望端逼。 院中可真熱鬧,春花似錦污淋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赁豆。三九已至仅醇,卻和暖如春魔种,著一層夾襖步出監(jiān)牢的瞬間析二,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工节预, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留叶摄,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓安拟,卻偏偏與公主長得像蛤吓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子糠赦,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,163評論 25 707
  • 轉(zhuǎn)載需要著名出處: 之前寫過微信登錄分享支付第一版: 前言 大部分的app都有接入第三方sdk的需求哲戚。例如第三方登...
    Android開發(fā)666閱讀 6,456評論 3 38
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)艾岂,斷路器顺少,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 第2天·21天OH卡魔法美顏瘦身課#玩卡不卡·每日一抽# 每一位都可以通過這張卡片覺察自己: 1、直覺他叫什么名字...
    聽味十足的故事閱讀 201評論 0 0
  • 如果陽光不那么高遠我愿意摘取一籃每天把它種在地里施肥王浴、除草脆炎、澆水直到收獲 如果大地不這么廣袤我愿擇取一隅種些糧食和...
    郭安安閱讀 323評論 11 15