WeChat (Android) – привязать, отвязать, войти, поделиться, перейти в апплет

Я хотел написать эту статью еще в прошлом году, но не сдал домашнее задание, и у меня еще есть немного свободного времени, так что поторопитесь подвести итоги, надеюсь, это вам немного поможет.

Функции трехстороннего входа в систему и трехстороннего совместного использования очень распространены, и некоторые трехсторонние платформы использовались раньше, а именно:

近一年左右,我分别在普通项目和模块化项目中实现了 微信登录、绑定、解绑功能,所以我将分类说明

Базовая интеграция

В начале интеграции мы должны зарегистрировать наше приложение на платформе WeChat, чтобы получить AppIDи AppSecretэти два ключа очень важны и используются при регистрации, аутентификации и других запросах.

Все соответствует официальным документам , поясняются только некоторые ключевые документы.

Протокол OAuth2.0

OAuth2.0 в основном используется в WeChat SDK , поэтому обязательно изучите весь процесс работы этого протокола.

Я помню интервью, где меня спросили о процессе входа в WeChat → OAuth2.0, и я ответил так.

  1. Зарегистрируйте приложение на платформе WeChat, получите AppID и AppSecret
  2. Вызовите трехсторонний вход в приложение и передайте AppID и другую информацию в WeChat.
  3. После того как WeChat получит AppID, получите информацию о приложении из базы данных WeChat.
  4. Операция отображения информации о пользователе и авторизации на странице аутентификации
  5. После авторизации пользователя верните временный код, а затем добавьте AppID и AppSecret, чтобы получить токен (также может быть выполнен серверной частью).
  6. Передайте временный код нашему бэкэнду, и наш бэкэнд вызывает бэкэнд WeChat, чтобы получить токен (он может быть возвращен клиенту или использован сам по себе).
  7. Бэкэнд (клиент) получает информацию о пользователе через токен.

На шагах 5–7 клиент также может напрямую отправить запрос в WeChat для получения информации о пользователе; но если это предполагает привязку и отмену привязки WeChat, требуется временный код.

вставьте сюда описание изображения

Связанный сценарий: при нажатии на трехсторонний вход инициируется запрос.

вставьте сюда описание изображения
вставьте сюда описание изображения

Связанный сценарий: аутентификация, получение временного билета (кода) после подтверждения авторизации.

вставьте сюда описание изображения

Связанный сценарий: получение access_token и информации о пользователе с помощью кода

Вы можете запросить напрямую https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code, просто замените поле кода

вставьте сюда описание изображения
вставьте сюда описание изображения

Связанный сценарий: период действия access_token

Что касается срока действия access_token, то некоторые люди прямо устанавливают максимальный срок действия (30 дней), а некоторым приходится продлевать его, обновляя refresh_tokenдинамику access_token. В любом случае, чем больше вы об этом думаете, тем больше у вас будет проблем. Я просто сделать запись здесь

вставьте сюда описание изображения
вставьте сюда описание изображения

Зарегистрируйтесь в WeChat

Краткое описание файла ознакомительных сведений: он эквивалентен методу регистрации SDK, за исключением того, что общий SDK регистрируется в приложении, а WeChat SDK регистрируется в компоненте Activity.

Чтобы терминал WeChat реагировал на вашу программу после ее запуска, вы должны зарегистрировать свой идентификатор в терминале WeChat в коде (обычно регистрируется в onCreate действия).

// APP_ID 替换为你的应用从官方网站申请到的合法appID
private static final String APP_ID = "wx88888888";
// IWXAPI 是第三方app和微信通信的openApi接口
private IWXAPI api;

private regToWx() {
    
    
    // 通过WXAPIFactory工厂,获取IWXAPI的实例
    api = WXAPIFactory.createWXAPI(this, APP_ID, true);
    // 将应用的appId注册到微信
    api.registerApp(APP_ID);
    //建议动态监听微信启动广播进行注册到微信
    registerReceiver(new BroadcastReceiver () {
    
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
    
            // 将该app注册到微信
            api.registerApp(Constants.APP_ID);
        }
    }, new IntentFilter (ConstantsAPI.ACTION_REFRESH_WXAPP));
}

Отправить запрос, ответить на WeChat

Краткое описание файла readme: sendReq(BaseReq req) 一般用于业务相关功能调用处и sendResp (соответственно BaseResp) не используется!

Отправьте запрос или отправьте ответ на терминал WeChat, чего можно добиться с помощью IWXAPIметодов sendReqиsendResp

  • boolean sendReq(BaseReq req);: sendReqэто стороннее приложение, которое активно отправляет сообщения в WeChat и после отправки переключается обратно на интерфейс стороннего приложения.
  • boolean sendResp(BaseResp resp);: sendRespWeChat запрашивает данные у стороннего приложения, и стороннее приложение снова переключится на интерфейс WeChat после ответа на данные.

Пример реализации sendReq

//初始化一个 WXTextObject 对象,填写分享的文本内容
WXTextObject textObj = new WXTextObject();
textObj.text = text;

//用 WXTextObject 对象初始化一个 WXMediaMessage 对象
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = textObj;
msg.description = text;

SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = String.valueOf(System.currentTimeMillis());  //transaction字段用与唯一标示一个请求
req.message = msg;
req.scene = mTargetScene;

//调用api接口,发送数据到微信
api.sendReq(req);

Реализация sendResp аналогична SendReq, как показано ниже.

// 初始化一个 WXTextObject 对象
WXTextObject textObj = new WXTextObject();
textObj.text = text;

// 用 WXTextObject 对象初始化一个 WXMediaMessage 对象
WXMediaMessage msg = new WXMediaMessage(textObj);
msg.description = text;

// 构造一个Resp
GetMessageFromWX.Resp resp = new GetMessageFromWX.Resp();
// 将req的transaction设置到resp对象中,其中bundle为微信传递过来的Intent所带的内容,通过getExtras()方法获取
resp.transaction = new GetMessageFromWX.Req(bundle).transaction;
resp.message = msg;

//调用api接口,发送数据到微信
api.sendResp (resp) ;

Получите запрос WeChat и возвращаемое значение

вставьте сюда описание изображения
Readme следующим образом

  1. В соответствующем каталоге 新建一个 wxapi目录,并在该 wxapi 目录下新增一个 WXEntryActivity 类этот класс наследуется от Activity
  2. AndroidManifestзарегистрироваться
<activity
    android:name=".wxapi.WXEntryActivity"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Translucent.NoTitleBar"
    android:exported="true"
    android:taskAffinity="填写你的包名"
    android:launchMode="singleTask">
</activity>
  1. WXEntryActivityРеализовать IWXAPIEventHandlerинтерфейс, переписать onReq(обычно используется для запроса интерфейса WeChat) onResp(обычно используется для получения данных, возвращаемых WeChat)

Примечание. Если вам нужно запутать код, чтобы обеспечить нормальное использование SDK, вам необходимо proguard.cfgдобавить следующие две строки конфигурации.

-keep class com.tencent.mm.opensdk.** {
    
    
    *;
}
-keep class com.tencent.wxop.** {
    
    
    *;
}
-keep class com.tencent.mm.sdk.** {
    
    
    *;
}

общие предметы

Я не уверен, что у всех одинаковые бизнес-потребности, но я обычно записываю проблемы, с которыми сталкиваюсь.

  • При обычном входе в WeChat после аутентификации пользователя вы можете напрямую запросить серверную часть WeChat для получения информации о пользователе, но в этом проекте вы сначала получили ее, а затем запросили 临时票据(code)внутренний интерфейс своей компании, и серверные части обеих сторон взаимодействовали для получения данные. Затем верните информацию о пользователе клиенту.
  • Пройдите проверку после возврата WXEntryActivityмониторинга onRespWeChat и выполните соответствующую логику.SendAuth.Respstate
  • Поскольку возвращаемые данные WeChat находятся в формате , а вызывающая сторона конечных данных находится в других компонентах, для удобства я использую WXEntryActivityздесь EventBusкомпонент

Привязка и отвязка WeChat

В этом проекте, будь то вход в систему, привязка или отвязка, это зависит от кода и бэкенда, поэтому разница между ними заключается в разнице в состоянии при отправке запроса, различаются только соответствующие бизнес-операции.

Краткое описание Readme: 其实绑定、解绑微信,并不是微信直接提供的功能!это вспомогательная функция, разработанная многими компаниями.

绑定微信时需要前往微信鉴权,解绑时因为是已方操作所以并不需要调用微信!(Просто добавьте следующий запрос WeChat в соответствующую точку функции спроса)

    //微信登陆,获取授权code(临时票据),每次都变更
    var req = SendAuth.Req()
    req.scope = "snsapi_userinfo";
    req.state = "bindWx";
    WxUtil.getApi(this.sendReq(req)

WxUtil

import static com.alipay.tianyan.mobilesdk.TianyanMonitorAbility.registerReceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.xiaomi.mipush.sdk.Constants;

//这个工具当时写的很鸡肋...
public class WxUtil {
    
    

    // APP_ID 替换为你的应用从官方网站申请到的合法appID
    public static final String APP_ID = "appID";

    // IWXAPI 是第三方 app 和微信通信的 openApi 接口
    public static IWXAPI api;

    public static IWXAPI getApi(Context context){
    
    
        if (api!=null){
    
    
            return api;
        }
        return WXAPIFactory.createWXAPI(context, APP_ID, true);
    }

    // 当前未用到
    public static void regToWx(Context context) {
    
    
        // 通过 WXAPIFactory 工厂,获取 IWXAPI 的实例
        api = WXAPIFactory.createWXAPI(context, APP_ID, true);
        // 将应用的 appId 注册到微信
        api.registerApp(APP_ID);

        //建议动态监听微信启动广播进行注册到微信
        registerReceiver(new BroadcastReceiver() {
    
    
            @Override
            public void onReceive(Context context, Intent intent) {
    
    
                // 将该 app 注册到微信
                api.registerApp(Constants.APP_ID);
                Log.e("wx", "微信已注册");
            }
        }, new IntentFilter(ConstantsAPI.ACTION_REFRESH_WXAPP));

    }
}

WXEntryActivity

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.util.Log
import android.widget.Toast
import com.tencent.mm.opensdk.constants.ConstantsAPI
import com.tencent.mm.opensdk.modelbase.BaseReq
import com.tencent.mm.opensdk.modelbase.BaseResp
import com.tencent.mm.opensdk.modelbiz.SubscribeMessage
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessView
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessWebview
import com.tencent.mm.opensdk.modelmsg.SendAuth
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import org.greenrobot.eventbus.EventBus
import java.lang.ref.WeakReference

class WXEntryActivity : Activity(), IWXAPIEventHandler {
    
    
    private var api: IWXAPI? = null
    private val TAG = "WXEntryActivity"

    private var handler: MyHandler? = null

    private class MyHandler(wxEntryActivity: WXEntryActivity) : Handler() {
    
    
        private val wxEntryActivityWeakReference: WeakReference<WXEntryActivity> = WeakReference(wxEntryActivity)

        override fun handleMessage(msg: Message) {
    
    
            when (msg.what) {
    
    
                6, 7 -> {
    
    
                    val loginData = msg.data
                    val loginCode: String? = loginData.getString("code")
                    EventBus.getDefault().post(loginCode?.let {
    
     AuthorCodeEvent(it) })
                }
                8 -> {
    
    
                    val loginData = msg.data
                    val loginCode: String? = loginData.getString("code")
                    EventBus.getDefault().post(loginCode?.let {
    
     BindAuthorCodeEvent(it) })
                }
            }
        }
    }

    public override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        api = WXAPIFactory.createWXAPI(this, "wxappid", false)
        handler = MyHandler(this)
        try {
    
    
            val intent = intent
            api!!.handleIntent(intent, this)
        } catch (e: Exception) {
    
    
            e.printStackTrace()
        }
    }

    override fun onNewIntent(intent: Intent) {
    
    
        super.onNewIntent(intent)
        setIntent(intent)
        api!!.handleIntent(intent, this)
    }

    override fun onReq(baseReq: BaseReq) {
    
    
        when (baseReq.type) {
    
    
            ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX -> {
    
    
            }
            ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX -> {
    
    
            }
            BaseResp.ErrCode.ERR_OK ->
                Toast.makeText(this@WXEntryActivity, "分享成功", Toast.LENGTH_LONG).show()
            BaseResp.ErrCode.ERR_USER_CANCEL ->                //分享取消
                Toast.makeText(this@WXEntryActivity, "分享取消", Toast.LENGTH_LONG).show()
            BaseResp.ErrCode.ERR_AUTH_DENIED ->                //分享拒绝
                Toast.makeText(this@WXEntryActivity, "分享拒绝", Toast.LENGTH_LONG).show()
            else -> {
    
    
            }
        }
        finish()
    }

    override fun onResp(resp: BaseResp) {
    
    
        var result = 0
        result = when (resp.errCode) {
    
    
            BaseResp.ErrCode.ERR_OK -> R.string.errcode_success
            BaseResp.ErrCode.ERR_USER_CANCEL -> R.string.errcode_cancel
            BaseResp.ErrCode.ERR_AUTH_DENIED -> R.string.errcode_deny
            BaseResp.ErrCode.ERR_UNSUPPORT -> R.string.errcode_unsupported
            else -> R.string.errcode_unknown
        }
        Log.e(TAG, getString(result) + ", type=" + resp.type)
    
        if (resp.type == ConstantsAPI.COMMAND_SENDAUTH) {
    
    
            val authResp = resp as SendAuth.Resp
            Log.d(TAG, "onResp: " + authResp.state)
            if (authResp.state != null) {
    
     //默认返回是空
                if (authResp.state == "sharesdk_wechat_auth") {
    
     //微信分享
                    val code = authResp.code
                    val msg = Message.obtain()
                    msg.what = 6
                    val data = Bundle()
                    data.putString("code", code)
                    msg.data = data
                    handler?.sendMessage(msg)
                } else if (authResp.state == "none") {
    
    
                    val code = authResp.code
                    val msg = Message.obtain()
                    msg.what = 0
                    val data = Bundle()
                    data.putString("code", code)
                    msg.data = data
                    handler?.sendMessage(msg)
                } else if (authResp.state == "login2") {
    
     //微信登录
                    val code = authResp.code
                    val msg = Message.obtain()
                    msg.what = 7
                    val data = Bundle()
                    data.putString("code", code)
                    msg.data = data
                    handler?.sendMessage(msg)
                } else if (authResp.state == "bindWx") {
    
     //绑定微信
                    val code = authResp.code
                    val msg = Message.obtain()
                    msg.what = 8
                    val data = Bundle()
                    data.putString("code", code)
                    msg.data = data
                    handler?.sendMessage(msg)
                }
            }
        }
        finish()
    }
}

有部分代码非我所写,留个备份,各位可忽略

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.util.Log
import android.widget.Toast
import com.tencent.mm.opensdk.constants.ConstantsAPI
import com.tencent.mm.opensdk.modelbase.BaseReq
import com.tencent.mm.opensdk.modelbase.BaseResp
import com.tencent.mm.opensdk.modelbiz.SubscribeMessage
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessView
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessWebview
import com.tencent.mm.opensdk.modelmsg.SendAuth
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import org.greenrobot.eventbus.EventBus
import java.lang.ref.WeakReference

class WXEntryActivity : Activity(), IWXAPIEventHandler {
    
    
    private var api: IWXAPI? = null
    private val TAG = "WXEntryActivity"

    private var handler: MyHandler? = null

    private class MyHandler(wxEntryActivity: WXEntryActivity) : Handler() {
    
    
        private val wxEntryActivityWeakReference: WeakReference<WXEntryActivity> =
            WeakReference(wxEntryActivity)

        override fun handleMessage(msg: Message) {
    
    
            when (msg.what) {
    
    
                /*  NetworkUtil.GET_TOKEN -> {
                      val data = msg.data
                      var json: JSONObject? = null
                      try {
                          json = JSONObject(data.getString("result"))
                          val openId: String
                          val accessToken: String
                          val refreshToken: String
                          val scope: String
                          openId = json.getString("openid")
                          accessToken = json.getString("access_token")
                          refreshToken = json.getString("refresh_token")
                          scope = json.getString("scope")
                          val intent = Intent(
                              wxEntryActivityWeakReference.get(),
                              AboutActivity::class.java
                          )
                          intent.putExtra("openId", openId)
                          intent.putExtra("accessToken", accessToken)
                          intent.putExtra("refreshToken", refreshToken)
                          intent.putExtra("scope", scope)
                          wxEntryActivityWeakReference.get()!!.startActivity(intent)
                      } catch (e: JSONException) {
                          Log.e(WXEntryActivity.TAG, e.message)
                      }
                  }
                  0 -> {
                      val data = msg.data
                      val code: String?
                      code = data.getString("code")
                      val intent = Intent(
                          wxEntryActivityWeakReference.get(),
                          WithdrawActivity::class.java
                      )
                      intent.putExtra("code", code)
                      wxEntryActivityWeakReference.get()!!.startActivity(intent)
                  }*/
                6, 7 -> {
    
    
                    val loginData = msg.data
                    val loginCode: String? = loginData.getString("code")
                    /* val loginIntent = Intent(
                         wxEntryActivityWeakReference.get(),
                         PhoneLoginActivity::class.java
                     )
                     loginIntent.putExtra("code", loginCode)
                     wxEntryActivityWeakReference.get()!!.startActivity(loginIntent)*/
                    EventBus.getDefault().post(loginCode?.let {
    
     AuthorCodeEvent(it) })
                }
                8 -> {
    
    
                    val loginData = msg.data
                    val loginCode: String? = loginData.getString("code")
                    /* val loginIntent = Intent(
                         wxEntryActivityWeakReference.get(),
                         PhoneLoginActivity::class.java
                     )
                     loginIntent.putExtra("code", loginCode)
                     wxEntryActivityWeakReference.get()!!.startActivity(loginIntent)*/
                    EventBus.getDefault().post(loginCode?.let {
    
     BindAuthorCodeEvent(it) })
                }
                /*  7 -> {
                      val login2data = msg.data
                      val login2code: String?
                      login2code = login2data.getString("code")
                      val login2intent = Intent(
                          wxEntryActivityWeakReference.get(),
                          NLoginActivity::class.java
                      )
                      login2intent.putExtra("code", login2code)
                      wxEntryActivityWeakReference.get()!!.startActivity(login2intent)
                  }
                  8 -> {
                      val binddata = msg.data
                      val bindcode: String?
                      bindcode = binddata.getString("code")
                      val bindintent = Intent(
                          wxEntryActivityWeakReference.get(),
                          ProfileDetailActivity::class.java
                      )
                      bindintent.putExtra("code", bindcode)
                      wxEntryActivityWeakReference.get()!!.startActivity(bindintent)
                  }*/
            }
        }

    }

    public override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        api = WXAPIFactory.createWXAPI(this, "wxappid", false)
        handler = MyHandler(this)
        try {
    
    
            val intent = intent
            api!!.handleIntent(intent, this)
        } catch (e: Exception) {
    
    
            e.printStackTrace()
        }
    }

    override fun onNewIntent(intent: Intent) {
    
    
        super.onNewIntent(intent)
        setIntent(intent)
        api!!.handleIntent(intent, this)
    }

    override fun onReq(baseReq: BaseReq) {
    
    
        when (baseReq.type) {
    
    
            ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX -> {
    
    
            }
            ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX -> {
    
    
            }
            BaseResp.ErrCode.ERR_OK ->
                Toast.makeText(this@WXEntryActivity, "分享成功", Toast.LENGTH_LONG).show()
            BaseResp.ErrCode.ERR_USER_CANCEL ->                //分享取消
                Toast.makeText(this@WXEntryActivity, "分享取消", Toast.LENGTH_LONG).show()
            BaseResp.ErrCode.ERR_AUTH_DENIED ->                //分享拒绝
                Toast.makeText(this@WXEntryActivity, "分享拒绝", Toast.LENGTH_LONG).show()
            else -> {
    
    
            }
        }
        finish()
    }

    override fun onResp(resp: BaseResp) {
    
    
        var result = 0
        result = when (resp.errCode) {
    
    
            BaseResp.ErrCode.ERR_OK -> R.string.errcode_success
            BaseResp.ErrCode.ERR_USER_CANCEL -> R.string.errcode_cancel
            BaseResp.ErrCode.ERR_AUTH_DENIED -> R.string.errcode_deny
            BaseResp.ErrCode.ERR_UNSUPPORT -> R.string.errcode_unsupported
            else -> R.string.errcode_unknown
        }
        Log.e(TAG, getString(result) + ", type=" + resp.type)
        if (resp.type == ConstantsAPI.COMMAND_SUBSCRIBE_MESSAGE) {
    
    
            val subscribeMsgResp = resp as SubscribeMessage.Resp
            val text = String.format(
                "openid=%s\ntemplate_id=%s\nscene=%d\naction=%s\nreserved=%s",
                subscribeMsgResp.openId,
                subscribeMsgResp.templateID,
                subscribeMsgResp.scene,
                subscribeMsgResp.action,
                subscribeMsgResp.reserved
            )
            Log.e(TAG, text)
        }
        if (resp.type == ConstantsAPI.COMMAND_LAUNCH_WX_MINIPROGRAM) {
    
    
            val launchMiniProgramResp = resp as WXLaunchMiniProgram.Resp
            val text = String.format(
                "openid=%s\nextMsg=%s\nerrStr=%s",
                launchMiniProgramResp.openId,
                launchMiniProgramResp.extMsg,
                launchMiniProgramResp.errStr
            )
            Log.e(TAG, text)
        }
        if (resp.type == ConstantsAPI.COMMAND_OPEN_BUSINESS_VIEW) {
    
    
            val launchMiniProgramResp = resp as WXOpenBusinessView.Resp
            val text = String.format(
                "openid=%s\nextMsg=%s\nerrStr=%s\nbusinessType=%s",
                launchMiniProgramResp.openId,
                launchMiniProgramResp.extMsg,
                launchMiniProgramResp.errStr,
                launchMiniProgramResp.businessType
            )
            Log.e(TAG, text)
        }
        if (resp.type == ConstantsAPI.COMMAND_OPEN_BUSINESS_WEBVIEW) {
    
    
            val response = resp as WXOpenBusinessWebview.Resp
            val text = String.format(
                "businessType=%d\nresultInfo=%s\nret=%d",
                response.businessType,
                response.resultInfo,
                response.errCode
            )
            Log.e(TAG, text)
        }
        if (resp.type == ConstantsAPI.COMMAND_SENDAUTH) {
    
    
            val authResp = resp as SendAuth.Resp
            Log.d(TAG, "onResp: " + authResp.state)
            if (authResp.state != null) {
    
     //默认返回是空
                if (authResp.state == "sharesdk_wechat_auth") {
    
    
                    val code = authResp.code
                    val msg = Message.obtain()
                    msg.what = 6
                    val data = Bundle()
                    data.putString("code", code)
                    msg.data = data
                    handler?.sendMessage(msg)
                } else if (authResp.state == "none") {
    
    
                    val code = authResp.code
                    val msg = Message.obtain()
                    msg.what = 0
                    val data = Bundle()
                    data.putString("code", code)
                    msg.data = data
                    handler?.sendMessage(msg)
                } else if (authResp.state == "login2") {
    
    
                    val code = authResp.code
                    val msg = Message.obtain()
                    msg.what = 7
                    val data = Bundle()
                    data.putString("code", code)
                    msg.data = data
                    handler?.sendMessage(msg)
                } else if (authResp.state == "bindWx") {
    
    
                    val code = authResp.code
                    val msg = Message.obtain()
                    msg.what = 8
                    val data = Bundle()
                    data.putString("code", code)
                    msg.data = data
                    handler?.sendMessage(msg)
                }
            }
        }
        finish()
    }
}

модульный проект

Межкомпонентная связь задействована в проектах с компонентной и модульной архитектурой, и взаимодействовать через компоненты, как раньше , EventBusнецелесообразно , поэтому Hilt+接口метод, используемый в текущем проекте

Обработка мониторинга WXEntryActivityне очень критична.Вы можете посмотреть метод инкапсуляции этой архитектуры подробнее, потому что он не полностью инкапсулирован мной, давайте учиться вместе

Архитектура пакета

Вы можете научиться дизайн-мышлению таким образом

метод вызова

import android.content.Context

interface WeChatService {
    
    

    fun startAuth(context: Context, black: (String) -> Unit)

    fun authSuccess(code: String)

    fun authFail()

    fun startMiniProgram(context: Context, userName: String, path: String, miniprogramType: String, black: (String) -> Unit)

    fun miniSuccess(res: String)
}

реализация метода

import android.content.Context
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram
import com.tencent.mm.opensdk.modelmsg.SendAuth
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import timber.log.Timber
import javax.inject.Inject


class WeChatServiceImpl @Inject constructor() : WeChatService {
    
    

    companion object {
    
    
        const val WX_APP_ID = "appID" // 微信appID
    }

    init {
    
    
        WXAPIFactory.createWXAPI(AppContext, WX_APP_ID, true).registerApp(WX_APP_ID)
    }

    private var authBlackListener: ((String) -> Unit)? = null

    private var miniBlackListener: ((String) -> Unit)? = null

    override fun startAuth(context: Context, black: (String) -> Unit) {
    
    
        val iWXAPI = WXAPIFactory.createWXAPI(context, WX_APP_ID, true)
        if (!iWXAPI.isWXAppInstalled) {
    
    
            context.neutralDialog(message = "您还没有安装微信")
            return
        }
        authBlackListener = black
        //微信登陆,获取授权code(临时票据),每次都变更
        val req = SendAuth.Req()
        req.scope = "snsapi_userinfo"
        req.state = "bindWx"
        Timber.e("WxHaServiceImp 开始发起授权")
        iWXAPI.sendReq(req)
    }

    override fun authSuccess(code: String) {
    
    
        authBlackListener?.invoke(code)
        authBlackListener = null
    }

    override fun authFail() {
    
    
        authBlackListener = null
    }

    override fun miniSuccess(res: String) {
    
    
        miniBlackListener?.invoke(res)
        miniBlackListener = null
    }

    override fun startMiniProgram(context: Context, userName: String, path: String, miniprogramType: String, black: (String) -> Unit) {
    
    
        val iWXAPI = WXAPIFactory.createWXAPI(context, WX_APP_ID, true)
        if (!iWXAPI.isWXAppInstalled) {
    
    
            context.neutralDialog(message = "您还没有安装微信")
            return
        }
        miniBlackListener = black
        iWXAPI.sendReq(WXLaunchMiniProgram.Req().apply {
    
    
            // 填小程序原始id
            this.userName = userName
            //拉起小程序页面的可带参路径,不填默认拉起小程序首页,对于小游戏,可以只传入 query 部分,来实现传参效果,如:传入 "?foo=bar"。
            this.path = path
            // 可选打开 开发版,体验版和正式版
            this.miniprogramType = miniprogramType.toInt()
        })
    }

}

Использование сценария

Если в будущем вы столкнетесь с другими сценариями, вы продолжите интегрировать их здесь.

Аутентификация (вход, привязка)

      weChatService.startAuth(requireContext()) {
    
     code ->
           //通过临时票据(code)请求我方后端接口,执行对应业务逻辑
        }

Перейти к апплету

        javascriptMethod.openWXminiProgram.observe(this) {
    
     params -> //  调用小程序
            try {
    
    
                val userName = params["userName"].string()
                val path = params["path"].string()
                val miniProgramType = params["miniProgramType"].string()
                val callbackId = params["callbackId"].string()
             	//微信小程序所需参数
                ServiceManager.weChatService().startMiniProgram(this, userName, path, miniProgramType){
    
     res ->
                    Timber.e("observe - res监听:$res" )
                    javascriptMethod.evaluateJavascript(callbackId, res)
                }
            } catch (throwable: Throwable) {
    
    
                Timber.e(throwable)
            }
        }

WXEntryActivity

import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import androidx.appcompat.app.AppCompatActivity
import com.tencent.mm.opensdk.constants.ConstantsAPI
import com.tencent.mm.opensdk.modelbase.BaseReq
import com.tencent.mm.opensdk.modelbase.BaseResp
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram
import com.tencent.mm.opensdk.modelmsg.SendAuth
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import timber.log.Timber


internal class WXEntryActivity : AppCompatActivity(), IWXAPIEventHandler {
    
    

    private val wxapi: IWXAPI by lazy {
    
    
        WXAPIFactory.createWXAPI(this, "appID")// 微信appID
    }

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        wxapi.handleIntent(intent, this)
    }

    @SuppressLint("MissingSuperCall")
    override fun onNewIntent(intent: Intent?) {
    
    
        super.onNewIntent(intent)
        setIntent(intent)
        wxapi.handleIntent(intent, this)
    }

    override fun onReq(baseReq: BaseReq?) = finish()

    override fun onResp(baseResp: BaseResp?) {
    
    
        if (baseResp?.type == ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX) {
    
       // 微信分享
//            when (baseResp.errCode) {
    
    
//                BaseResp.ErrCode.ERR_OK -> "微信分享成功"
//                BaseResp.ErrCode.ERR_USER_CANCEL -> "微信分享被取消"
//                BaseResp.ErrCode.ERR_AUTH_DENIED -> "微信分享失败"
//                else -> "微信分享未知"
//            }.apply {
    
    
//                ToastUtils.showToast(this)
//            }
        } else if (baseResp?.type == ConstantsAPI.COMMAND_SENDAUTH) {
    
           // 微信授权
            val result = when (baseResp.errCode) {
    
    
                BaseResp.ErrCode.ERR_OK -> "发送成功"
                BaseResp.ErrCode.ERR_USER_CANCEL -> "发送取消"
                BaseResp.ErrCode.ERR_AUTH_DENIED -> "发送被拒绝"
                BaseResp.ErrCode.ERR_UNSUPPORT -> "不支持错误"
                else -> "发送返回"
            }
            Timber.e("baseRespErrCode =$result")
            if (baseResp.errCode == BaseResp.ErrCode.ERR_OK) {
    
      // 微信授权成功
                ServiceManager.weChatService().authSuccess((baseResp as SendAuth.Resp).code)
            } else {
    
        // 微信授权失败
                ServiceManager.weChatService().authFail()
            }
        } else if (baseResp?.type == ConstantsAPI.COMMAND_LAUNCH_WX_MINIPROGRAM) {
    
    
            val launchMiniProResp = baseResp as WXLaunchMiniProgram.Resp
            val extraData = launchMiniProResp.extMsg //对应小程序组件 <button open-type="launchApp"> 中的 app-parameter 属性
            Timber.e("小程序返回数据:" + extraData.string())
            if (!TextUtils.isEmpty(extraData)) {
    
    
                Timber.e("小程序返回数据不为空内部回调:" + extraData.string())
                ServiceManager.weChatService().miniSuccess(extraData.string())
            }
        }
        this.finish()
    }

}

Supongo que te gusta

Origin blog.csdn.net/qq_20451879/article/details/123858796
Recomendado
Clasificación