这篇内容去年的时候就想写了,但是一直没交作业,蹭着还有一些空闲时间,抓紧总结一下,希望能帮到你一丢丢
关于三方登录和三方分享的功能很常见,之前也用过一些三方平台,如下
近一年左右,我分别在普通项目和模块化项目中实现了 微信登录、绑定、解绑功能,所以我将分类说明
基础集成
集成之初首先要 将我们的应用注册到微信平台,以此获得
AppID
和AppSecret
,这俩个key都很重要,在注册、鉴权等请求中都有用到
一切以 官方文档 为准 ,仅说明部分关键文档
OAuth2.0 协议
在微信SDK中主要用到了 OAuth2.0,务必了解这个协议的整个流程
我记得有一次面试,被问到了微信登录 → OAuth2.0流程 ,我是这么回答的
- 在微信平台注册App,获取 AppID 和 AppSecret
- 在应用内调用三方登录,将 AppID 等信息传给微信
- 微信获取到AppID 后,从微信端数据库获取应用信息
- 在鉴权页显示用户信息与是否授权的操作
- 当用户授权后,返回临时code,然后加上AppID和AppSecret获取token(也可由后端执行)
- 将临时code传给我方后端,我方后端调用微信后端获取token(可返回到客户端,也可自我消费)
- 后端(客户端)通过token获取用户信息
在5-7步骤中客户端也可以直接发请求给微信,以此获取用户信息;但如果是涉及到绑定、解绑微信那么就需要临时code
关联场景:点击三方登录时,发起请求
关联场景:鉴权,确认授权后获取临时票据(code)
关联场景:通过code 获取 access_token、用户信息
可以直接请求 https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
,替换code字段即可
关联场景:access_token 有效期
关于access_token有效期的问题,有的人直接设置最长有效期(30天),有的又要去通过刷新
refresh_token
动态去给access_token
续期,反正考虑的越多,问题就越多,我此处仅做记录
注册到微信
自述总结:相当于SDK的注册方式,只不过一般SDK注册在Application,而微信SDK在Activity组件
要使你的程序启动后微信终端能响应你的程序,必须在代码中向微信终端注册你的 id(一般在 Activity 的 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));
}
发送请求、响应到微信
自述总结:
sendReq(BaseReq req) 一般用于业务相关功能调用处
,而关于sendResp(BaseResp resp)并未用到!
发送请求或发送响应到微信终端,可以通过 IWXAPI
的 sendReq
和 sendResp
两个方法来实现
boolean sendReq(BaseReq req);
:sendReq
是第三方 app 主动发送消息给微信,发送完成之后会切回到第三方 app 界面。boolean sendResp(BaseResp resp);
:sendResp
是微信向第三方 app 请求数据,第三方 app 回应数据之后会切回到微信界面。
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) ;
接收微信的请求及返回值
自述如下
- 在相应目录下
新建一个 wxapi目录,并在该 wxapi 目录下新增一个 WXEntryActivity 类
,该类继承自 Activity 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>
WXEntryActivity
实现IWXAPIEventHandler
接口,重写onReq
(一般用于请求微信方面的接口)、onResp
(一般用于接收微信方面返回的数据)
注意事项:如果需要混淆代码,为了保证 sdk 的正常使用,需要在 proguard.cfg
加上下面两行配置
-keep class com.tencent.mm.opensdk.** {
*;
}
-keep class com.tencent.wxop.** {
*;
}
-keep class com.tencent.mm.sdk.** {
*;
}
普通项目
我并不确定每个人遇到的业务需求是否相同,不过我习惯性记录一下我遇到的问题
- 常规的微信登录中,在用户鉴权后可以直接请求微信后端获取到用户信息,但是当初在这个项目中是先获取到
临时票据(code)
,然后请求自己公司的后端接口,由双方后端交互获取数据后再将用户信息返回给客户端 - 在
WXEntryActivity
的onResp
监听微信返回后通过SendAuth.Resp
的state
校验,执行对应逻辑 - 因为微信的返回数据都在
WXEntryActivity
中,而最终数据的调用方都在其他组件,为了方便我在这里使用的是EventBus
组件
绑定、解绑微信
在此项目中不论是登录、绑定、解绑都是依赖于code和后端,所以俩者区别除了发送请求时的state不同之外,只有对应的业务操作不同而已
自述总结:其实绑定、解绑微信,并不是微信直接提供的功能!
而是很多公司衍生出来的附属功能
绑定微信时需要前往微信鉴权,解绑时因为是已方操作所以并不需要调用微信!
(仅需在对应需求功能点加入以下微信请求即可)
//微信登陆,获取授权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
的监听处理并不是很关键,更多的可以看看这种架构de封装方式,因为并不是由我完全封装,一起来学习一下吧
封装架构
可以通过这种方式学习一下设计思想
调用方法
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()
}
}