安卓微信登录第三方详解

前言:接着上一篇QQ登录~

1、效果图
登录前:
在这里插入图片描述

登录后:
在这里插入图片描述

2、微信开放平台注册应用:链接:https://open.weixin.qq.com/
创建应用并获得需要的参数
在这里插入图片描述

填入应用包名与签名如下图,下载地址非必填
在这里插入图片描述

关于签名在build.gradle配置如下,这样运行出来的则是正式版本签名

signingConfigs {
        debug {
            storeFile file('D:/workspace/helloword.jks')
            storePassword '123456'
            keyAlias '123'
            keyPassword '123456'
        }
        release {
            storeFile file('D:/workspace/helloword.jks')
            storePassword '123456'
            keyAlias '123'
            keyPassword '123456'
        }
    }

3、登录类

public class TestActivity extends AppCompatActivity {

    private static final String TAG = "TestActivity";
    //微信AppID
    public static final String APP_ID = "wx08c24bb11123e4f5";
    //微信AppSecret
    public static final String WEIXIN_ID = "66fzzds17e660f5f5zq4f9d5e283aweba3";

    //展示个人信息
    private TextView infoText, infoName;
    private ImageView infoIcon;

    //初始化微信服务
    private IWXAPI api;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        //注册EventBus
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
        //通过WXAPIFactory工厂,获取IWXAPI实例,是否检查signature
        api = WXAPIFactory.createWXAPI(this, APP_ID, true);
        //将应用的appId注册到微信
        api.registerApp(APP_ID);

        infoText = this.findViewById(R.id.text_info);
        infoIcon = this.findViewById(R.id.info_icon);
        infoName = this.findViewById(R.id.info_name);
        //登录点击事件
        findViewById(R.id.button_login).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loginWeiXin();
            }
        });
    }

    /**
     * 微信登录
     */
    private void loginWeiXin() {
        SendAuth.Req auth = new SendAuth.Req();
        //snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。
        //使用snsapi_base可以让移动端网页授权绕过跳转授权登录页请求用户授权的动作,
        //直接跳转第三方网页带上授权临时票据(code),但会使得用户已授权作用域(scope)仅为snsapi_base,
        //从而导致无法获取到需要用户授权才允许获得的数据和基础功能。
        auth.scope = "snsapi_userinfo";
        auth.state = "wechat_sdk_微信登录";
        api.sendReq(auth);//向微信发送请求
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void OnLoginWeiXinEvent(LoginWeiXinEvent event) {
        //获取Token信息
        getWeiXinAccessToken(event.getCode());
    }

    /**
     * 根据code获取微信token
     */
    private void getWeiXinAccessToken(String code) {

        String url = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=" + APP_ID
                + "&secret=" + WEIXIN_ID
                + "&code=" + code
                + "&grant_type=authorization_code&connect_redirect=1";

        Log.e(TAG, "请求url:" + url);
        Log.e(TAG, "请求code:" + code);

        //1.okhttpClient对象
        //   OkHttpClient okHttpClient = new OkHttpClient();
        //2、构造Request,
        //builder.get()代表的是get请求,url方法里面放的参数是一个网络地址
        //  Request.Builder builder = new Request.Builder();
        //okHttpClient.sslSocketFactory();
        //okHttpClient.

        Request request = new Request.Builder().url(url).build();
        OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
        //  Request request = builder.get().url(url).build();
        //3将Request封装成call
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //失败回调
                Log.e(TAG, "请求失败:" + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                //成功回调
                String result = response.body().string();
                Log.e(TAG, "请求成功:" + result);

                try {
                    JSONObject jsonObject = new JSONObject(result);
                    String token = jsonObject.getString("access_token");
                    String openId = jsonObject.getString("openid");

                    Log.e(TAG, "登录token:" + token);
                    Log.e(TAG, "登录openId:" + openId);
                    //获取用户信息
                    getUserInfo(token, openId);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        });
    }

    /**
     * 获取个人信息
     * 根据openId和token获取个人信息
     */
    private void getUserInfo(final String token, final String openId) {

        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + openId;

        Log.e(TAG, "请求token:" + token);
        Log.e(TAG, "请求openId:" + openId);

        Request request = new Request.Builder().url(url).build();
        OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "请求失败:" + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //成功回调
                final String result = response.body().string();
                Log.e(TAG, "请求成功:" + result);

                try {
                    JSONObject jsonObject = new JSONObject(result);
                    final String nickname = jsonObject.getString("nickname");
                    final String headimgurl = jsonObject.getString("headimgurl");

                    //切换至主线程上
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //头像
                            GlideUtils.showGlide(TestActivity.this, headimgurl, infoIcon);
                            //昵称
                            infoName.setText(nickname);
                            infoText.setText(result);
                        }
                    });
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //销毁EventBus
        if (EventBus.getDefault().isRegistered(this))//加上判断
            EventBus.getDefault().unregister(this);
    }

}

对应布局:

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

    <ImageView
        android:id="@+id/info_icon"
        android:src="@mipmap/ic_launcher"
        android:layout_width="150dp"
        android:layout_height="150dp" />

    <TextView
        android:gravity="center"
        android:id="@+id/info_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp" />

    <TextView
        android:layout_marginBottom="10dp"
        android:layout_marginTop="10dp"
        android:id="@+id/text_info"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="14sp" />

    <Button
        android:id="@+id/button_login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="微信登录" />
</LinearLayout>

4、微信回调类
在最外层新建wxapi包,并新建类名WXEntryActivity(注意不要更改名字)

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

    /**
     * 微信登录相关
     */
    private IWXAPI api;
    private static final String TAG = "WXPayEntryActivity";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_bg);
        api = WXAPIFactory.createWXAPI(this, APP_ID, true);
        //将应用的appid注册到微信
        api.registerApp(APP_ID);
        //注意:
        //第三方开发者如果使用透明界面来实现WXEntryActivity,需要判断handleIntent的返回值,
        // 如果返回值为false,则说明入参不合法未被SDK处理,应finish当前透明界面,
        // 避免外部通过传递非法参数的Intent导致停留在透明界面,引起用户的疑惑
        try {
            boolean result = api.handleIntent(getIntent(), this);
            if (!result) {
                finish();
            }
            LogUtil.e("result:", result + "");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onReq(BaseReq baseReq) {

    }

    // 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
    //app发送消息给微信,处理返回消息的回调
    @Override
    public void onResp(BaseResp baseResp) {
        /**
         * 0 成功 展示成功页面
         * -1 错误 可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等
         * -2 用户取消 无需处理。发生场景:用户不支付了,点击取消,返回APP
         */
        Log.e(TAG, "请求成功:" + "错误码:"+ baseResp.errStr);
        Log.e(TAG, "errCode:""errCode:"+baseResp.errCode);

        switch (baseResp.errCode) {
            case 0:
                //拿到了微信返回的code,立马再去请求access_token
                String loginCode = ((SendAuth.Resp) baseResp).code;
                LoginWeiXinEvent event = new LoginWeiXinEvent();
                event.setCode(loginCode);
                EventBus.getDefault().post(event);
                finish();
                break;
            case -1:
                finish();
                break;
            case -2:
                finish();
                break;
        }
    }

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


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        api.handleIntent(data, this);
    }
}

其中layout_bg为自动生成布局,无UI界面

LoginWeiXinEvent通知类

public class LoginWeiXinEvent {

    private String code;

    public String getCode() {
        return code;
    }

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

5、AndroidManifest.xml清单文件中配置

 <!-- 微信登录 -->
        <activity
            android:name=".wxapi.WXEntryActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />

theme设置为透明防止登录后出现白色一闪而过的界面,引起用户疑惑。

6、依赖的资源:

    implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'//微信登录与支付
    implementation 'org.greenrobot:eventbus:3.1.1'//通知
    implementation 'com.squareup.okhttp3:okhttp:3.4.1'//网络请求
    implementation 'com.github.bumptech.glide:glide:4.7.1'//图片加载

猜你喜欢

转载自blog.csdn.net/qq_34536167/article/details/83215962