Apply for account

Go to theWechat open platformApply for account

After adding the app, fill in Android at the bottomThe package nameandApplication of signature, fill in Android, iOS, I don’t care

Signature using theGensignatureTo obtainTo use it, install the APP on the phone, and then install the APP to obtain the signature on the same phone with the release signature. Then enter the package name and click “Get” in the picture below.Enter the signature and package name in this ↓ at the bottom of the page

Then duplicate this at the top of the pageAppIDThis thing doesn’t change, just copy it once, down hereAppSecretYes or no.

Because wechat login callback is written very retarded, users nickname avatar and other things, you and the background, who to manage wechat to, who will use the AppSecret

Automatically sign the debug package

If you don’t want to sign manually every time, you can use gradle scripts to sign automatically. Add it in android under build.gradle of your APP

signingConfigs {
        debug {
            keyAlias 'aaa'// The signature file in the library
            keyPassword '123456'// Signature password
            storeFile file('D:/AndroidProjects/xxx.jks')// The path and name of the signature database file, which is strongly recommended to be saved in the project directory
            storePassword '123456'// Signature database password}}Copy the code

Import the lib

Repeat after me: Gradle method good! Wechat payment and wechat login are in this package, import is done

/ / WeChat SDK
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
Copy the code

Login code (written to your login screen)

First instantiate a wechat API object Java

private IWXAPI api;

// Instantiate the global wechat API object. You can write it to the Activity's onCreate or put the whole object into the Application for global use
        api = WXAPIFactory.createWXAPI(this."Your AppID".false);
        api.registerApp("Your AppID");
Copy the code

Kotlin

lateinit var api: IWXAPI

// Instantiate the global wechat API object. You can write it to the Activity's onCreate or put the whole object into the Application for global use
        api = WXAPIFactory.createWXAPI(this."Your AppID".false)
        api.registerApp("Your AppID")
Copy the code

Then there is the login method Java

private void login(IWXAPI api) {
        if(! api.isWXAppInstalled()) { ToastUtils.showShort("You haven't installed the wechat client yet!");// Here is a Toast sentence, which can be replaced with your own Toast utility class
            return;
        }
        SendAuth.Req req =new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "wechat_sdk_demo_test";
        api.sendReq(req);
        finish();
    }
Copy the code

Kotlin

private fun login(api: IWXAPI) {
        if(! api.isWXAppInstalled) { ToastUtils.showShort("You haven't installed the wechat client yet!")// Here is a Toast sentence, which can be replaced with your own Toast utility class
            return
        }
        val req = SendAuth.Req()
        req.scope = "snsapi_userinfo"
        req.state = "wechat_sdk_demo_test"
        api.sendReq(req)
        finish()
    }
Copy the code

Call this method directly to request wechat login, the callback written in Activtiy mentioned below. Yeah, that’s right. Callbacks to other activities, right? Added: ak47 schematic item and loot added: DO not know his wechat SDK developer mind is not into sulfuric acid (╯ next □ ‘) ak47 schematic item and loot write this fairy operation logic.

Create the WXAPI Activity

Create a subpackage called wxAPI under your package name, this name cannot be changed, Then create a WXEntryActivity -> wechat Login/wechat share callback WXPayEntryActivity -> wechat pay callback they both inherit the Activity implementation IWXAPIEventHandler interface

Register the callback Activity

<! STRART -->
        <activity
            android:name=".wxapi.WXEntryActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:exported="true"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />

        <! --/* wechat pay */-->
        <activity
            android:name=".wxapi.WXPayEntryActivity"
            android:exported="true"
            android:launchMode="singleInstance"
            android:theme="@style/AppSplash">
            <! -- wechat Pay -->
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="Fill in the AppID here." />
            </intent-filter>
        </activity>
        
Copy the code

Content of the style

  <style name="AppSplash" parent="Theme.AppCompat.Light.NoActionBar">
        <! -- Set boot background transparency -->
        <item name="android:windowIsTranslucent">true</item>
        <! -- Set startup without Title -->
        <item name="android:windowNoTitle">true</item>
    </style>
Copy the code

WXPayEntryActivity if your project is useless, don’t write it. In WXEntryActivity, you take a WXAPI object as you did before, and the creation process is essentially the same and I’m not going to write it down here, but if you started writing it in your Application you can just use it now. The difference is this time it’s going to be in onCreate and onNewIntent

setIntent(intent);// create onNewIntent
api.handleIntent(intent, this);
Copy the code

Then override onReq (request issued) and onResp (request returned) and log where onReq (request returned) is issued

Toast.makeText(this."openid = " + req.openId, Toast.LENGTH_SHORT).show();
Copy the code

Where the receiver returns (onResp) Let’s get things done

Java

@Override
private void onResp(BaseResp resp) {
    String result = "";
    switch (resp.errCode) {
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                result = "Operation cancelled";
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                result = "Request denied";
                break;
            default:
                result = "Unknown error";
                break; }}switch (resp.type) {
            case 1: {if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
                    SendAuth.Resp resp2 = (SendAuth.Resp) resp;
                    val code = resp2.code;
                    result = "Login successful";
                    getAccessToken(code);// If you want the user information of your background, you need to use this code to request the interface of wechat. Otherwise, you can directly return the code to the background here
                }
                break;
            }
            case 2: {
                if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
                    result = "Share the success";
                }
            }
        }
        ToastUtil.showShort(result);
        Logger.d(result);
}

Copy the code

Kotlin

override fun onResp(resp: BaseResp) {
        when (resp.errCode) {
            BaseResp.ErrCode.ERR_USER_CANCEL -> result = "Operation cancelled"
            BaseResp.ErrCode.ERR_AUTH_DENIED -> result = "Request denied"
            else -> {
                result = "Unknown error"}}when (resp.type) {
            1- > {if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
                    val code = (resp as SendAuth.Resp).code
                    result = "Login successful"
                    getAccessToken(code)// If you want the user information of your background, you need to use this code to request the interface of wechat. Otherwise, you can directly return the code to the background here}}2- > {if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
                    result = "Share the success"
                }
            }
        }
        ToastUtil.showShort(result)
        Logger.d(result)
    }
Copy the code

If your background only wanted code, that would be it, just replace the getAccessToken method with an HTTP request and send it to your background. If you still want to pick up wechat nicknames and profile pictures, keep reading.

Use code to adjust wechat interface to get token

Java+OkHttp3

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";
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token";
        OkHttpClient mOkHttpClient = new OkHttpClient();
        ///< Post mode can also be...
        // RequestBody body = new FormBody.Builder()
        //.add("appid", "replace with your appID ")
        //.add("secret", "replace your app key ")
        // .add("code", code)
        // .add("grant_type", "authorization_code")
        // .build();
        url += "? appid=" + "Replace with your appID" + "&secret=xxxxxxxx"
                + "&code=" + code + "&grant_type=authorization_code";
        final Request request = new Request.Builder()
                .url(url)
                //.post(body)
                .build();
        Call call = mOkHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                finish();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String json = response.body().string();
                WXTokenModel accessToken = JSONObject.parseObject(json, newTypeReference<WXTokenModel>() { }); getUserInfo(accessToken.getAccess_token(), accessToken.getOpenid()); }}); }Copy the code

Kotlin+Kolley

/ * * *@paramAccessToken */ according to code
    private fun getAccessToken(code: String) {
        // String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
        ///< Post mode can also be...
        // RequestBody body = new FormBody.Builder()
        //.add("appid", "replace with your appID ")
        //.add("secret", "replace your app key ")
        // .add("code", code)
        // .add("grant_type", "authorization_code")
        // .build();
        Http.post {
            // url += ("? Appid =" + "replace with your appID" + "&secret= XXXXXXXX"
// + "&code=" + code + "&grant_type=authorization_code")
            url = "https://api.weixin.qq.com/sns/oauth2/access_token"
            params {
                "appid" - "Your AppID"
                "secret" - "Your Secret"
                "code" - code// The code you got
                "grant_type" - "authorization_code"
            }
            onSuccess { byts ->
                var result = byts.toString(Charset.defaultCharset())
                if (TextUtils.isNotEmpty(result)) {
                    val model: WXTokenModel = StringNullAdapter.gson.fromJson(result)
                    getUserInfo(model.access_token, model.openid)
                }
            }
            onFail { error ->
                var message = error.message
                ToastUtil.showShort(message)
            }
        }
    }
Copy the code

StringNullAdapter is a third-party library that does not crash when parsing JSON even if it is empty

implementation 'com. Ohmerhe. Kolley: kolley: 0.3.1'
implementation 'com. Making. Mfangtao: FTLibary: 2.0.2'
Copy the code

WXTokenModel

JavaBean

public class WXTokenModel{
    private String access_token = "";
    private int expires_in = 0;
    private openid: String = "";
    private String refresh_token  = "";
    private String scope: = "";
    
    / / getter/setter slightly
}
Copy the code

Kotlin data class

data class WXTokenModel(
    var access_token: String = "".var expires_in: Int = 0.var openid: String = "".var refresh_token: String = "".var scope: String = ""
)
Copy the code

Use token to adjust wechat interface to get user information

Java+OkHttp3

private void getUserInfo(String access_token, String openid) {
        // String url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
        String url = "https://api.weixin.qq.com/sns/userinfo";
        OkHttpClient mOkHttpClient = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
                .add("access_token", access_token)
                .add("openid", openid)
                .build();
        final Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        Call call = mOkHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                finish();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String json = response.body().string();
                WXUserInfo wxUserInfo = JSONObject.parseObject(json, new TypeReference<WXUserInfo>() {
                });// So far all the nickname avatar, pass it to your backgroundfinish(); }}); }Copy the code

Kotlin+kolley

private fun getUserInfo(access_token: String, openid: String) {
        // String url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
        Http.post {
            url = "https://api.weixin.qq.com/sns/userinfo"
            params {
                "access_token" - access_token
                "openid" - openid
            }
            onSuccess { byts ->
                var result = byts.toString(Charset.defaultCharset())
                if (TextUtils.isNotEmpty(result)) {
                    val model: WXUserInfo = StringNullAdapter.gson.fromJson(result)
                    sendThird(openid, model.headimgurl, model.nickname)// So far all the nickname avatar, pass it to your background
                }
            }
            onFail { error ->
                var message = error.message
                ToastUtil.showShort(message)
            }
        }
    }
Copy the code

WXUserInfo

JavaBean

public class WXUserInfo(
    private String city = "";
    private String country = "";
    private String headimgurl = "";
    private String nickname = "";
    private String openid= "";
    private List<String> privilege = ArrayList();
    private String province "";
    private int sex 0;
    private String unionid "";
    
    / / getter/setter slightly
)
Copy the code

Kotlin data class

data class WXUserInfo(
    var city: String = "",
    var country: String = "",
    var headimgurl: String = "",
    var nickname: String = "",
    var openid: String = "",
    var privilege:  MutableList<String> = ArrayList(),
    var province: String = "",
    var sex: Int = 0,
    var unionid: String = ""
)
Copy the code

Wechat login strange call chain caused problems

The call chain here is your login interface → wechat login interface → wechat callback interface. You will find that in this jump, because wechat login interface does not return to you, your login interface cannot get the login result through methods like onActivtiyResult, and the login result is transmitted to wechat callback interface. Your login screen is nothing more than a request sender. Once you send the request, it’s useless. WXEntryActivity, on the other hand, is usually an empty interface with no layout. Because most apps directly enter the home page after logging in to wechat instead of having a special login successful interface, WXEntryActivity is transparent in many apps. The line api.sendreq (req) is usually followed by finish() to make the login screen go off the stack, preventing the user from going back to the login screen at the bottom of the stack after trying to exit the APP. Of course, this will cause a problem, that is, the user in wechat authorization interface click exit, there is no stack element directly back to the desktop (in fact, WXEntryActivity, but because it is transparent, so it looks like the APP exit), So the solution is to create a WXEntryActivity when resp.errCode! = baserESP.errcode. ERR_OK to manually launch our own login interface.

About the integration of umu login scheme

If your project uses Umeng share, instead of importing the original library, import the following library

implementation 'com. Umeng. Umsdk: share - wx: 6.9.4'
Copy the code

And then add it to Application onCreate

UMConfigure.init(this."AppKey friends union"."Umeng", UMConfigure.DEVICE_TYPE_PHONE, "Their Allies MessageSecret");
PlatformConfig.setWeixin("WeChat AppID"."WeChat AppSecret");
Copy the code

Call to Java

private UMShareAPI umShareAPI;
private UMAuthListener umAuthListener;// The method of this thing can be directly empty implementation, because its callback wechat will not go. The method is empty, not the object


/ / onCreate
umShareAPI = UMShareAPI.get(this);

// Invoke login
umShareAPI.getPlatformInfo(this, SHARE_MEDIA.WEIXIN, umAuthListener);// Wechat login
Copy the code

Kotlin

lateinit var umShareAPI: UMShareAPI
lateinit var umAuthListener: UMAuthListener// The method of this thing can be directly empty implementation, because its callback wechat will not go. The method is empty, not the object


/ / onCreate
umShareAPI = UMShareAPI.get(this)

// Invoke login
umShareAPI.getPlatformInfo(this, SHARE_MEDIA.WEIXIN, umAuthListener)// Wechat login
Copy the code

Other parts are the same as the official SDK

reference

Part of the code from Android- wechat login pit (+ umeng wechat login)