Android微信登錄迷殿、分享、支付

轉(zhuǎn)載需要著名出處:

http://blog.csdn.net/lowprofile_coding/article/details/78004224

之前寫過(guò)微信登錄分享支付第一版:

http://blog.csdn.net/lowprofile_coding/article/details/48086381

前言

大部分的app都有接入第三方sdk的需求咖杂。例如第三方登錄需要接入微信庆寺、QQ、微博诉字。第三方支付需要接入微信懦尝、支付寶、銀聯(lián)壤圃。

這些我都有使用過(guò)陵霉,都有使用過(guò)他們的sdk,感覺(jué)最麻煩的就是微信伍绳,不能直接調(diào)試踊挠,得用正式的簽名進(jìn)行簽名才能調(diào)試。還有他們官方的demo也是跑不起來(lái)的冲杀,因?yàn)闆](méi)有簽名文件效床。需要注意的地方也很多。

代碼實(shí)現(xiàn)

微信sdk現(xiàn)在支持Android Studio在線引用了漠趁,之前都是添加jar的方法扁凛。需要訪問(wèn)微信的接口獲取用戶信息忍疾,所以把我們之前封裝的okhttp也一起在線引用闯传。okhttp需要在自定義的Application中初始化這個(gè)我就不貼代碼了。之前已經(jīng)講過(guò)很多次卤妒。在app/build.gradle文件dependencies標(biāo)簽中加入以下兩行代碼:

compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
compile 'com.ansen.http:okhttpencapsulation:1.0.1'

需要用到網(wǎng)絡(luò)甥绿,所以在AndroidManifest.xml文件中加入網(wǎng)絡(luò)權(quán)限:

<uses-permission android:name="android.permission.INTERNET" />

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登錄之后信息在這里顯示"/>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/tv_nickname"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="昵稱:"/>

        <TextView
            android:id="@+id/tv_age"
            android:layout_below="@+id/tv_nickname"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="年齡:"/>
    </RelativeLayout>

    <Button
        android:id="@+id/btn_login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="微信登錄"/>

    <Button
        android:id="@+id/btn_share_friend_circle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="分享到朋友圈"/>

    <Button
        android:id="@+id/btn_share_friend"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="分享給好友"/>

    <Button
        android:id="@+id/btn_pay"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="微信支付"/>
</LinearLayout>

布局文件很簡(jiǎn)單字币,就LinearLayout里面放了幾個(gè)TextView,跟幾個(gè)按鈕共缕。

WeiXin.java 用于EventBus來(lái)傳送消息洗出,微信sdk有個(gè)很奇怪的地方,就是不管登錄图谷、分享翩活、支付之后都得用一個(gè)Activity來(lái)接收,所以我們還得從接收的那個(gè)activity把結(jié)果信息通過(guò)EventBus傳遞給MainActivity便贵。雖然用廣播也能實(shí)現(xiàn)菠镇,但是個(gè)人喜歡用EventBus,使用靈活承璃。簡(jiǎn)單輕量利耍。

public class WeiXin {
    private int type;//1:登錄 2.分享 3:微信支付
    private int errCode;//微信返回的錯(cuò)誤碼
    private String code;//登錄成功才會(huì)有的code

    public WeiXin() {
    }

    public WeiXin(int type,int errCode, String code) {
        this.type = type;
        this.errCode=errCode;
        this.code = code;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public int getErrCode() {
        return errCode;
    }

    public void setErrCode(int errCode) {
        this.errCode = errCode;
    }
}

Constant.java 常量類,微信appid跟secret的值用兩個(gè)常量保存盔粹。為了保護(hù)隱私這兩個(gè)值我已經(jīng)修改過(guò)隘梨。

public class Constant {
    public static String WECHAT_APPID="wxda6db2aec81389af";
    public static String WECHAT_SECRET="8fed5a2d510022587ef8a6194c965be3";
}

MainActivity.java 全部代碼貼出來(lái)比較亂,暫時(shí)貼出MainActivity部分代碼舷嗡。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private IWXAPI wxAPI;
    private TextView tvNickname,tvAge;
    public static final int IMAGE_SIZE=32768;//微信分享圖片大小限制

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EventBus.getDefault().register(this);//注冊(cè)
        wxAPI = WXAPIFactory.createWXAPI(this,Constant.WECHAT_APPID,true);
        wxAPI.registerApp(Constant.WECHAT_APPID);

        findViewById(R.id.btn_login).setOnClickListener(this);
        findViewById(R.id.btn_share_friend_circle).setOnClickListener(this);
        findViewById(R.id.btn_share_friend).setOnClickListener(this);
        findViewById(R.id.btn_pay).setOnClickListener(this);

        tvNickname= (TextView) findViewById(R.id.tv_nickname);
        tvAge=(TextView) findViewById(R.id.tv_age);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_login://微信登錄
                login();
                break;
            case R.id.btn_share_friend_circle://微信分享到朋友圈
                share(true);
                break;
            case R.id.btn_share_friend://微信分享給朋友
                share(false);
                break;
            case R.id.btn_pay://微信支付
//              先去服務(wù)器獲取支付信息轴猎,返回一個(gè)WeiXinPay對(duì)象,然后調(diào)用pay方法
                showToast("微信支付需要服務(wù)器支持");
                break;
        }
    }

    /**
     * 這里用到的了EventBus框架
     * @param weiXin
     */
    @Subscribe
    public void onEventMainThread(WeiXin weiXin){
        Log.i("ansen","收到eventbus請(qǐng)求 type:"+weiXin.getType());
        if(weiXin.getType()==1){//登錄
            getAccessToken(weiXin.getCode());
        }else if(weiXin.getType()==2){//分享
            switch (weiXin.getErrCode()){
                case BaseResp.ErrCode.ERR_OK:
                    Log.i("ansen", "微信分享成功.....");
                    break;
                case BaseResp.ErrCode.ERR_USER_CANCEL://分享取消
                    Log.i("ansen", "微信分享取消.....");
                    break;
                case BaseResp.ErrCode.ERR_AUTH_DENIED://分享被拒絕
                    Log.i("ansen", "微信分享被拒絕.....");
                    break;
            }
        }else if(weiXin.getType()==3){//微信支付
            if(weiXin.getErrCode()==BaseResp.ErrCode.ERR_OK){//成功
                Log.i("ansen", "微信支付成功.....");
            }
        }
    }
    
    ..........

    public void showToast(String message){
        Toast.makeText(this,message,Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);//取消注冊(cè)
    }
}
  • onCreate 注冊(cè)EventBus咬崔,通過(guò)WXAPIFactory創(chuàng)建IWXAPI類税稼,并且注冊(cè)appid,給四個(gè)按鈕按鈕設(shè)置點(diǎn)擊事件垮斯。查找顯示名字跟年齡的兩個(gè)TextView郎仆。
  • onClick 點(diǎn)擊事件監(jiān)聽(tīng),根據(jù)id來(lái)判斷點(diǎn)擊不同的按鈕兜蠕,跳轉(zhuǎn)到相應(yīng)的方法扰肌,這些方法沒(méi)貼出來(lái)來(lái),等會(huì)單獨(dú)講熊杨。
  • onEventMainThread(WeiXin weiXin) 用來(lái)接收消息曙旭,這個(gè)方法有個(gè)參數(shù),用來(lái)判斷類型晶府,就是我們用EventBus發(fā)送時(shí)參數(shù)必須是WeiXin類型桂躏。首先判斷type,是登錄還是分享還是支付川陆。登錄成功情況下會(huì)獲取到code剂习,根據(jù)code然后我們就能獲取到微信用戶信息。
  • showToast Toast提示
  • onDestroy 取消EventBus注冊(cè)

微信登錄

微信登錄流程有以下三個(gè)步驟:

  • 微信授權(quán)登陸
  • 根據(jù)授權(quán)登陸code 獲取該用戶token
  • 根據(jù)token獲取用戶資料

當(dāng)我們點(diǎn)擊登錄按鈕的時(shí)候,調(diào)用的是login方法鳞绕。這個(gè)方法就在MainActivity里面失仁。就是給微信發(fā)起一個(gè)登錄請(qǐng)求,彈出一個(gè)授權(quán)界面们何。

public void login(){
    SendAuth.Req req = new SendAuth.Req();
    req.scope = "snsapi_userinfo";
    req.state = String.valueOf(System.currentTimeMillis());
    wxAPI.sendReq(req);
}

在你的包名相應(yīng)目錄下新建一個(gè)wxapi目錄萄焦,然后在wxapi目錄下新增一個(gè)WXEntryActivity類,用來(lái)接收登錄授權(quán)以及分享時(shí)微信的回調(diào)信息冤竹。這個(gè)類繼承自Activity拂封,需要實(shí)現(xiàn)IWXAPIEventHandler接口。

package com.ansen.shoenet.wxapi;
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
    private IWXAPI wxAPI;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        wxAPI = WXAPIFactory.createWXAPI(this,Constant.WECHAT_APPID,true);
        wxAPI.registerApp(Constant.WECHAT_APPID);
        wxAPI.handleIntent(getIntent(), this);
    }

    @Override
    protected void onNewIntent(Intent intent){
        super.onNewIntent(intent);
        wxAPI.handleIntent(getIntent(),this);
        Log.i("ansen","WXEntryActivity onNewIntent");
    }

    @Override
    public void onReq(BaseReq arg0) {
        Log.i("ansen","WXEntryActivity onReq:"+arg0);
    }

    @Override
    public void onResp(BaseResp resp){
        if(resp.getType()== ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX){//分享
            Log.i("ansen","微信分享操作.....");
            WeiXin weiXin=new WeiXin(2,resp.errCode,"");
            EventBus.getDefault().post(weiXin);
        }else if(resp.getType()==ConstantsAPI.COMMAND_SENDAUTH){//登陸
            Log.i("ansen", "微信登錄操作.....");
            SendAuth.Resp authResp = (SendAuth.Resp) resp;
            WeiXin weiXin=new WeiXin(1,resp.errCode,authResp.code);
            EventBus.getDefault().post(weiXin);
        }
        finish();
    }
}

onCreate鹦蠕、onNewIntent烘苹、onReq這三個(gè)方法是固定寫法。onResp方法接收微信結(jié)果信息片部,首先判斷類型镣衡,根據(jù)不同的類型去封裝WeiXin對(duì)象,如果是登錄操作档悠,把code傳入進(jìn)去廊鸥,然后把封裝好的WeiXin對(duì)象通過(guò)EventBus發(fā)送出去。MainActivity的onEventMainThread方法就會(huì)接收到這個(gè)消息辖所。最后調(diào)用finish關(guān)閉當(dāng)前的activity惰说。

WXEntryActivity記得在AndroidManifest.xml中注冊(cè)

<activity
    android:exported="true"
    android:name=".wxapi.WXEntryActivity"/>

繼續(xù)回到首頁(yè)的onEventMainThread,如果登錄類型調(diào)用getAccessToken()缘回,并且傳入code吆视。根據(jù)code獲取access_token,這個(gè)url是微信公開的酥宴,需要傳入三個(gè)參數(shù)啦吧,appid、secret拙寡、code授滓。請(qǐng)求成功之后會(huì)返回access_token跟openid等信息。

public void getAccessToken(String code){
    String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
            "appid="+Constant.WECHAT_APPID+"&secret="+Constant.WECHAT_SECRET+
            "&code="+code+"&grant_type=authorization_code";
    HTTPCaller.getInstance().get(WeiXinToken.class, url, null, new RequestDataCallback<WeiXinToken>() {
        @Override
        public void dataCallback(WeiXinToken obj) {
            if(obj.getErrcode()==0){//請(qǐng)求成功
                getWeiXinUserInfo(obj);
            }else{//請(qǐng)求失敗
                showToast(obj.getErrmsg());
            }
        }
    });
}

獲取到access_token跟openid之后繼續(xù)調(diào)用getWeiXinUserInfo方法獲取用戶信息肆糕。這樣就能取到當(dāng)前微信app登錄的用戶一些信息般堆。有昵稱、年齡诚啃、頭像地址淮摔、語(yǔ)言等基本信息。在企業(yè)開發(fā)中始赎,到了這一步就可以拿著這些信息調(diào)用自己服務(wù)器的登錄接口和橙。當(dāng)然我們這邊就把昵稱跟年齡給TextView顯示下顾彰。

public void getWeiXinUserInfo(WeiXinToken weiXinToken){
    String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+
            weiXinToken.getAccess_token()+"&openid="+weiXinToken.getOpenid();
    HTTPCaller.getInstance().get(WeiXinInfo.class, url, null, new RequestDataCallback<WeiXinInfo>() {
        @Override
        public void dataCallback(WeiXinInfo obj) {
            tvNickname.setText("昵稱:"+obj.getNickname());
            tvAge.setText("年齡:"+obj.getAge());
            Log.i("ansen","頭像地址:"+obj.getHeadimgurl());
        }
    });
}

WeiXinToken跟WeiXinInfo這兩個(gè)實(shí)體類就不貼代碼了,WeiXinToken用來(lái)映射獲取訪問(wèn)token接口返回的json胃碾。WeiXinInfo用來(lái)映射獲取用戶接口返回的json。

微信分享

分享有兩種分享到朋友圈跟分享給好友筋搏,統(tǒng)一調(diào)用share方法仆百。傳入一個(gè)boolean類型來(lái)判斷是否分享到朋友圈。

public void share(boolean friendsCircle){
    WXWebpageObject webpage = new WXWebpageObject();
    webpage.webpageUrl = "www.baidu.com";//分享url
    WXMediaMessage msg = new WXMediaMessage(webpage);
    msg.title = "分享標(biāo)題";
    msg.description = "分享描述";
    msg.thumbData =getThumbData();//封面圖片byte數(shù)組

    SendMessageToWX.Req req = new SendMessageToWX.Req();
    req.transaction = String.valueOf(System.currentTimeMillis());
    req.message = msg;
    req.scene = friendsCircle ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
    wxAPI.sendReq(req);
}

分享內(nèi)容有很多格式奔脐,分享圖片俄周、分享視頻、分享消息髓迎。我們這邊就分享消息為例峦朗,也是分享比較常見(jiàn)的格式。首先new一個(gè)WXWebpageObject對(duì)象排龄,設(shè)置標(biāo)題波势、內(nèi)容、打開鏈接橄维、封面等尺铣。最后調(diào)用wxAPI的sendReq放松一個(gè)請(qǐng)求。

分享跟登錄一樣争舞,都會(huì)回調(diào)WXEntryActivity凛忿,然后又把分享結(jié)果發(fā)送給MainActivity.onEventMainThread方法。

支付
支付首先需要請(qǐng)求我們自己的服務(wù)器竞川,獲取支付信息店溢。獲取成功之后調(diào)用pay方法。

public void pay(WeiXinPay weiXinPay){
    PayReq req = new PayReq();
    req.appId = Constant.WECHAT_APPID;//appid
    req.nonceStr=weiXinPay.getNoncestr();//隨機(jī)字符串委乌,不長(zhǎng)于32位床牧。推薦隨機(jī)數(shù)生成算法
    req.packageValue=weiXinPay.getPackage_value();//暫填寫固定值Sign=WXPay
    req.sign=weiXinPay.getSign();//簽名
    req.partnerId=weiXinPay.getPartnerid();//微信支付分配的商戶號(hào)
    req.prepayId=weiXinPay.getPrepayid();//微信返回的支付交易會(huì)話ID
    req.timeStamp=weiXinPay.getTimestamp();//時(shí)間戳

    wxAPI.registerApp(Constant.WECHAT_APPID);
    wxAPI.sendReq(req);
}

weiXinPay的值應(yīng)該是我們從自己服務(wù)器獲取的,然后把返回信息封裝到PayReq對(duì)象中遭贸,最后調(diào)用wxAPI的sendReq方法發(fā)起請(qǐng)求叠赦。

在wxapi目錄下新增一個(gè)WXPayEntryActivity類,這個(gè)類跟WXEntryActivity同級(jí)革砸,用來(lái)接收微信支付的回調(diào)信息除秀。這個(gè)類繼承自Activity,需要實(shí)現(xiàn)IWXAPIEventHandler接口算利。

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
    private IWXAPI wxAPI;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        wxAPI = WXAPIFactory.createWXAPI(this, Constant.WECHAT_APPID);
        wxAPI.handleIntent(getIntent(), this);
    }
    
    @Override
    protected void onNewIntent(Intent intent){
        super.onNewIntent(intent);
        setIntent(intent);
        wxAPI.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq baseReq) {}

    @Override
    public void onResp(BaseResp resp) {
        Log.i("ansen", "微信支付回調(diào) 返回錯(cuò)誤碼:"+resp.errCode+" 錯(cuò)誤名稱:"+resp.errStr);
        if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX){//微信支付
            WeiXin weiXin=new WeiXin(3,resp.errCode,"");
            EventBus.getDefault().post(weiXin);
        }
        finish();
    }
}

其他方法都是固定寫法册踩,在onResp中判斷如果是微信登錄,就封裝一個(gè)WeiXin對(duì)象效拭,然后發(fā)送EventBus請(qǐng)求暂吉。這樣MainActivity的onEventMainThread就會(huì)接收到這個(gè)WeiXin對(duì)象胖秒。

WXPayEntryActivity記得在AndroidManifest.xml中注冊(cè)。

<activity
    android:exported="true"
    android:name=".wxapi.WXPayEntryActivity"/>

項(xiàng)目結(jié)構(gòu)圖如下所示慕的,從圖中我們看到軟件包名是com.ansen.shoenet阎肝。接收微信登錄支付返回的Activity的包名必須是com.ansen.shoenet.wxapi。兩個(gè)activity的名字也是固定寫法肮街。

project_structure

簽名

微信登錄分享支付都有一個(gè)簽名驗(yàn)證风题,這個(gè)很麻煩,導(dǎo)致每次調(diào)試都需要重新簽名嫉父。

首先用android studio生成一個(gè)正式的簽名文件沛硅,簽名文件是.jks結(jié)尾的,這個(gè)簽名文件是你以后打線上包一直要用到的绕辖。然后用這個(gè)簽名文件生成apk摇肌。這個(gè)時(shí)候我們的app就有了正式簽名。把正式簽名的apk發(fā)送到手機(jī)上進(jìn)行安裝仪际。

并且下載一個(gè)簽名生成工具安裝围小,這個(gè)工具用于獲取安裝到手機(jī)的第三方應(yīng)用簽名的apk包。微信官方下載地址:

https://res.wx.qq.com/open/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android2.apk

以上兩個(gè)app都安裝好了之后打開從微信下載的那個(gè)app,軟件名字叫「GenSignature」,有一個(gè)輸入框树碱,輸入我們軟件的包名吩抓,點(diǎn)擊Get Signature按鈕.效果圖如下:


get_signature

把那行綠色的16進(jìn)制數(shù)炒下來(lái)保存到txt文本中。

微信sdk官網(wǎng)后臺(tái)配置

官網(wǎng)地址:

https://open.weixin.qq.com/

在微信sdk首頁(yè)赴恨,有個(gè)管理中心點(diǎn)擊之后默認(rèn)就是移動(dòng)應(yīng)用疹娶,如果還沒(méi)有創(chuàng)建移動(dòng)應(yīng)用就先創(chuàng)建一個(gè),如果有了就點(diǎn)擊當(dāng)前的應(yīng)用后面的查看按鈕伦连,就會(huì)進(jìn)入應(yīng)用詳細(xì)界面雨饺。

在應(yīng)用詳細(xì)界面一直往下滾動(dòng),滾到最底部有個(gè)開發(fā)信息惑淳。點(diǎn)擊修改额港,進(jìn)入修改界面,在修改界面滾動(dòng)到最下面,效果圖如下所示:


app_info

首先我們?cè)贏ndroid應(yīng)用這里打上勾歧焦,然后填寫應(yīng)用簽名移斩,這個(gè)簽名都是我之前要你們保存到記事本上的那個(gè)值,包名就是app包名绢馍。點(diǎn)擊保存向瓷。

運(yùn)行軟件

登錄之后效果圖如下:

login_success

分享到朋友圈如下:

share_friend_circle

分享給朋友:

share_friend

微信支付沒(méi)法測(cè)試,因?yàn)樾枰?wù)器支持舰涌。

微信官方開發(fā)文檔

我這偏文章只是針對(duì)現(xiàn)在微信的sdk版本接入猖任,但是sdk是有可能變化的,版本變化瓷耙、接口變化等朱躺。所以建議大家還是以官方文檔為主刁赖。我的文章提供參考。

移動(dòng)應(yīng)用微信登錄開發(fā)指南

https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=219192a54f13e8e7011ced8e4ce5b36b699629c4&lang=zh_CN

Android微信支付開發(fā)手冊(cè)

https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317784&token=219192a54f13e8e7011ced8e4ce5b36b699629c4&lang=zh_CN

注意事項(xiàng)

接入微信sdk有很多需要注意的地方长搀,這里我們最后再來(lái)做一個(gè)總結(jié)宇弛。

  • 微信登陸,分享源请,支付回調(diào)的Activity包名跟類名一定要嚴(yán)格按照要求去寫
  • 接收回調(diào)的是Activity一定要在AndroidManifest.xml中中注冊(cè)
  • Constant里面兩個(gè)常量的值要去微信申請(qǐng)并且創(chuàng)建應(yīng)用才有的枪芒,這里需要改成你們申請(qǐng)的值。
  • 需要訪問(wèn)網(wǎng)絡(luò)所以記得在AndroidManifest.xml中添加權(quán)限
  • 調(diào)用微信的登陸巢钓,分享,支付你的安裝包一定要有簽名,簽名信息一定要跟你在微信官網(wǎng)上配置的簽名信息一致
  • 微信沒(méi)有客服支持.....如果出了問(wèn)題看官方的Demo或者官方API
  • 微信SDK經(jīng)常升級(jí)疗垛,如果你開發(fā)的時(shí)候有最新的就用最新的吧.....

最后的最后

你們直接運(yùn)行我的demo是不行的症汹,因?yàn)槟銈儧](méi)有的jks文件,沒(méi)法簽名贷腕,并且源碼中的appid跟secret被我修改過(guò)了背镇,是不能使用的,但是你們可能又想看運(yùn)行效果泽裳,所以我在項(xiàng)目下建了個(gè)apk文件夾瞒斩,里面放了一個(gè)可以測(cè)試微信登錄分享的apk安裝包。

源碼下載

如果你想第一時(shí)間看我的后期文章涮总,掃碼關(guān)注公眾號(hào)胸囱,每周不定期推送Android開發(fā)實(shí)戰(zhàn)教程文章...

      Android開發(fā)666 - 安卓開發(fā)技術(shù)分享
             掃描二維碼加關(guān)注
Android開發(fā)666
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瀑梗,隨后出現(xiàn)的幾起案子烹笔,更是在濱河造成了極大的恐慌,老刑警劉巖抛丽,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谤职,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡亿鲜,警方通過(guò)查閱死者的電腦和手機(jī)允蜈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蒿柳,“玉大人饶套,你說(shuō)我怎么就攤上這事±萏剑” “怎么了凤跑?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)叛复。 經(jīng)常有香客問(wèn)我仔引,道長(zhǎng)扔仓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任咖耘,我火速辦了婚禮翘簇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘儿倒。我一直安慰自己版保,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布夫否。 她就那樣靜靜地躺著彻犁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凰慈。 梳的紋絲不亂的頭發(fā)上汞幢,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音微谓,去河邊找鬼森篷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛豺型,可吹牛的內(nèi)容都是我干的仲智。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼姻氨,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼钓辆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起肴焊,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤岩馍,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后抖韩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛀恩,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年茂浮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了双谆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡席揽,死狀恐怖顽馋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情幌羞,我是刑警寧澤寸谜,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站属桦,受9級(jí)特大地震影響熊痴,放射性物質(zhì)發(fā)生泄漏他爸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一果善、第九天 我趴在偏房一處隱蔽的房頂上張望诊笤。 院中可真熱鬧,春花似錦巾陕、人聲如沸讨跟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)晾匠。三九已至,卻和暖如春梯刚,著一層夾襖步出監(jiān)牢的瞬間凉馆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工乾巧, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留句喜,地道東北人预愤。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓沟于,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親植康。 傳聞我的和親對(duì)象是個(gè)殘疾皇子旷太,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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