Android探索與鞏固(微信QQ第三方登錄填坑)

@TOCjava

前言

​ 上個周到如今一直在忙年前的優化任務,領導都是越到年末越想激發你的潛力,任務一個一個地來,幹完了就能回家。做爲一個剛剛進入這家公司的Android獨苗,接觸陌生的代碼而且周圍人沒辦法提供幫助的狀況下在這麼短期開發幾個功能,仍是挺費神的。等到如今才徹底收工,有時間閒下來去總結一下上個周把我折磨得死去活來的小妖精們。(示例大部分依舊是kotlin)android

微信三方登陸

​ 集成微信的三方登錄過程不難,可是中間有好多大坑官方沒有說明白。咱們先從頭看開始講,遇到的坑就放在後面詳細探討一下。ios

  1. 註冊微信開放平臺用戶,申請應用。後端

    這一步應該不用說太多,就是簡單的註冊流程。不過在Android應用這,app的簽名是經過微信提供的簽名工具獲取的:GenSignature,在這裏面輸入本機已經安裝的應用包名,就能獲取到這個應用的簽名。填上就好了。審覈上面說是七個工做日,其實幾個小時就好了。api

  2. 引入第三方包,初始化緩存

引入三方包,老規矩微信

com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+
複製代碼

在項目的gradle文件中引用這個地址,更新一下就可使用了。app

而後進行初始化,通常要放在Application裏面進行:ide

val appID = "wxecb9abc374b780c2"
val api: IWXAPI = WXAPIFactory.createWXAPI(this, appID, true)
private fun initWx() {
   api.registerApp(appID)
}
複製代碼

固然這一步不少人直接放在須要調用登錄的Activity或者Fragment裏面進行,不過我們這裏防止之後還須要加微信其餘功能,就放在這裏了。工具

  1. 接下來就是在Activity或者Fragment裏面的操做。

    private fun startWxLogin() {
        val appID = "wxecb9abc374b780c2"
        val api: IWXAPI = WXAPIFactory.createWXAPI(this, appID, true)
        if (!api.isWXAppInstalled) {
            showShort("您還未安裝微信")
        } else {
            val req = SendAuth.Req()
            req.scope = "snsapi_userinfo"
            req.state = "zhys_wxlogin"
            api.sendReq(req)
        }
    }
    複製代碼

    這個方法就是調起微信的操做,將這個方法放進相應的點擊事件裏面就行了。req.scope固定爲這個,req.state自定。

  2. 接下來須要新建一個類用於接收微信傳回來的信息。由於在微信官網註冊了包名和簽名,因此微信是經過用絕對路徑的方式將信息傳到這個類裏面,這個類有嚴格的命名規則。必須是包名的一級子目錄下新建一個文件夾:wxapi,在這個文件夾下新建名爲WXEntryActivity的類,官網給出的規則必須是:包名.wxapi.WXEntryActivity,好比說官網註冊爲com.androidproject.test,那麼這個類的包名就應該是com.androidproject.test.wxapi.WXEntryActivity。下面是這個類的基本寫法

class WXEntryActivity : Activity(), IWXAPIEventHandler {
    private var mWeixinAPI: IWXAPI? = null
    private val RETURN_MSG_TYPE_LOGIN = 1
    private val RETURN_MSG_TYPE_SHARE = 2

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mWeixinAPI = WXAPIFactory.createWXAPI(this, WEIXIN_APP_ID, true)
        mWeixinAPI!!.handleIntent(this.intent, this)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        mWeixinAPI!!.handleIntent(intent, this)//必須調用此句話
    }

    //微信發送的請求將回調到onReq方法
    override fun onReq(req: BaseReq) { LogUtils.d("onReq")
    }

    //發送到微信請求的響應結果
    override fun onResp(resp: BaseResp) {
        LogUtils.d("onResp")
        when (resp.errCode) {
            BaseResp.ErrCode.ERR_OK -> {
                LogUtils.d("ERR_OK")
                //發送成功
                val sendResp = resp as SendAuth.Resp
                val code = sendResp.code
                EventBus.getDefault().post(code,"wxCode")
                finish()
            }
            BaseResp.ErrCode.ERR_USER_CANCEL -> {
                if (resp.type == RETURN_MSG_TYPE_SHARE){
                    showShort("分享失敗")
                }else{
                    showShort("登錄失敗")
                }
                LogUtils.e("ERR_USER_CANCEL")
            }
            BaseResp.ErrCode.ERR_AUTH_DENIED -> LogUtils.e("ERR_AUTH_DENIED")
            else -> {
                showShort("微信登錄錯誤")
                LogUtils.d("微信登錄錯誤"+" "+resp.errCode+resp.errStr)
                finish()
            }
        }//發送取消
        //發送被拒絕
        //發送返回

    }
    companion object {
        private val APP_SECRET = "305c1e604e79f7e9b4c9a617c67c345c"
        val WEIXIN_APP_ID = "wxecb9abc374b780c2"
        private val uuid: String? = null
    }

}
複製代碼
  1. 這裏咱們只用到了微信返回的code,而後發送給後端,後端再集成微信三方登陸的功能獲取咱們的用戶信息,若是是想取到相關用戶信息也是能夠取到的。

好了,到如今爲止,微信的基本用法就這麼多,下面來說一下我在微信集成的時候遇到的

一開始,我按照官網一步步寫完運行以後發現微信調起界面只是一閃而過,調起瞬間又關閉,而後在WXEntryActivity這個類中debug也沒有觸發。顯然,微信沒有找到這個類。因而我檢查了包名,和官網如出一轍,而後我又檢查簽名,發現debug模式安裝和打包安裝的簽名是不同的。這就很坑,因而我得出結論,以後打包以後再測試吧。可是!!!!改了簽名以後仍是不行,網上查找解決辦法都說包名不對。但是我左看右看包名徹底一致啊,而後這個問題困擾了我一天。到了晚上回到家精疲力盡的時候,想要作最後一博,就去試驗各類方法。而後我發現了這個代碼以前設計的是在不一樣環境下打包添加不一樣的後綴,

applicationIdSuffix ".develop"
複製代碼

這個時候大家確定覺得我在這個地方犯了低級錯誤,去找和官網註冊的相同後綴的包名問題就解決了(我卻是但願如此),事實證實問題並非那麼簡單。

在這裏插入圖片描述

找到相同包名覺得能夠鬆一口氣的時候,絕望地發現仍是不行。我這個時候就感受確定和這行代碼有關係,網上成功的案例都是絕對固定的包名。因而我註釋掉這行代碼,將微信註冊的包名換成沒有後綴的形式,果真成功了。(心裏一萬個草泥馬奔騰而過)。雖然成功了,可是這個項目不能這麼繼續作下去,由於以後還要作QQ登錄,騰訊開放平臺的包名是不能修改的,並且還用了其餘的第三方SDK,會影響其餘功能。我就只能更改目錄結構,硬生生把那個後綴寫死在裏面。而後切出另一個分支,維持原有的目錄結構,保證其餘功能能夠在測試環境測試。

微信登錄的坑

  1. 注意包名是否一致

  2. debug運行的簽名和打包簽名不一致(集成以後若是出現微信返回ERR=-6的錯誤,多半是簽名不一致,就是這個緣由。也有多是以前微信運行過錯誤的簽名,就會記錄到微信緩存中,須要清除緩存或者直接卸載重裝)

  3. //applicationIdSuffix ".develop"
    //signingConfig signingConfigs.release
    複製代碼

不能使用這兩行代碼(後面這個是我實驗出來的),比較懊惱的是至今不知道其緣由,但願有緣人看到這篇文章能夠解答一下。

QQ三方登陸

接下來咱們講一下QQ三方登陸,QQ三方登陸其實很簡單,我在這個地方絆倒純粹是經驗不足。

QQ三方登錄的SDK仍是用的依賴lib包的形式實現。在官網下載它的lib包,引入後就可使用了。

  1. 首先在你須要調用的地方進行實例化:

    val mTencent: Tencent = Tencent.createInstance("你的appid", applicationContext)
    複製代碼

    而後進行拉起QQ登錄:

    mTencent.login(this, "all", BaseUiListener())
    複製代碼

    這裏的BaseUiListener是本身去寫的接收qq的回調。須要本身去寫一下.

  2. 編寫QQ回調

    public class BaseUiListener implements IUiListener {
        //注意測試須要在騰訊開放平臺註冊調試者QQ號
        @Override
        public void onComplete(Object response) {
            try {
    // String openId = ((JSONObject) response).getString("openid");
    // String expires = ((JSONObject) response).getString("expires_in");
                String token = ((JSONObject) response).getString("access_token");
                LogUtils.d(((JSONObject) response).getString("access_token"));
                EventBus.getDefault().post(token,"qqToken");
            } catch (JSONException e) {
                e.printStackTrace();
            }
    
        }
    
        @Override
        public void onError(UiError e) {
            LogUtils.d("code:" + e.errorCode + ", msg:"
                    + e.errorMessage + ", detail:" + e.errorDetail);
        }
    
        @Override
        public void onCancel() {
            LogUtils.d("onCancel");
        }
    
    }
    複製代碼

這裏我只須要qq的accessToken,全部就取了這個值,其餘的我的信息也能夠取到。

QQ須要注意的點就是在測試環境下須要去騰訊開放平臺註冊調試者QQ號,否則的話只會不斷地從新拉起沒有反應。(奇怪的是,ios不用註冊也能夠收到,由於這個我一直沒注意這個問題)。

至此,微信QQ三方登錄的坑就算填完了,這些坑耽誤了我太長時間,不過也值得。下面再講一個和主題無關的小坑:

我中間還用了百度的離線語音合成,可是出現一個問題,打正式的包的時候語音就沒法讀出。我就去鎖定了打包的那幾行代碼得出如下結論:

// minifyEnabled false
// shrinkResources false
複製代碼

這兩行不能隨便加上,收縮資源和縮小文件會去刪掉它認爲沒用的資源文件。極大可能會誤刪,因此致使了離線語音不可用。

最後總結

​ 前段時間時間太緊張了,博客也沒更,本身維護的項目也沒作,後面再慢慢跟上吧。踩過的這些坑雖然耗時長,可是漲了很多經驗,之後就不會犯錯了。

相關文章
相關標籤/搜索