- 小程序回调APP的extMsg值一直为{} ——微信6.6.6版本的Bug,在6.6.7版本已修复,具体可以看下这个帖子:https://developers.weixin.qq.com/blogdetail?action=get_post_info&docid=000a2818d14998a043d6bf3ac52000&highline=Android
需求来源
最近微信的小程序支持从App唤起,操作后支持跳回App的功能。我司产品就来提需求了,希望当前客户端的活动运营位支持跳转小程序的页面,并点击小程序的按钮跳回App指定页面。产品说这个功能可以避免一个活动开发多个页面的问题,并且微信小程序的活动也可以在客户端内展示了。
调研
- 唤起功能
String appId = "wxd930ea5d5xxxx8f4f"; // 填应用AppId
IWXAPI api = WXAPIFactory.createWXAPI(context, appId);
WXLaunchMiniProgram.Req req = new WXLaunchMiniProgram.Req();
req.userName = "gh_d43xxxxca31f"; // 填小程序原始id
req.path = path; //拉起小程序页面的可带参路径,不填默认拉起小程序首页
req.miniprogramType = WXLaunchMiniProgram.Req.MINIPTOGRAM_TYPE_RELEASE;// 可选打开 开发版,体验版和正式版
api.sendReq(req);
- 回调
public void onResp(BaseResp resp) {
if (resp.getType() == ConstantsAPI.COMMAND_LAUNCH_WX_MINIPROGRAM) {
WXLaunchMiniProgram.Resp launchMiniProResp = (WXLaunchMiniProgram.Resp) resp;
String extraData =launchMiniProResp.extMsg; // 对应JsApi navigateBackApplication中的extraData字段数据
}
}
看微信文档使用很简单,唤起时绑定小程序和App,指定打开的路径,指定小程序版本即可。 回调时可以拿到小程序下发的“app-parameter“字段中内容,关于app-parameter可以看下 https://developers.weixin.qq.com/miniprogram/dev/api/launchApp.html,需要小程序的同学写的。
开发
1、唤起
为了无侵入式支持客户端原有运营位(比如常见的轮播广告位)点击跳转到小程序的页面,我们打算采用schema方式进行跳转,采用一个透明的Activity作为接收者,拿到参数后,去调用微信的接口。(内容都作为schema的参数去传递,注意对path做encode)
<activity
android:name=".MiniprogramActivity"
android:theme="@android:style/Theme.Translucent" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:scheme="schema"
android:host="launchMiniProgram"
</intent-filter>
</activity>
内部调用微信接口
public class MiniprogramActivity extends BaseActivity{
public static final int LAUNCH_MINIPROGRAM_SUPPORTED_SDK_667 = 0x25010500;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent != null && dispatchUri(intent)) {
this.finish();
}
}
public boolean dispatchUri(Intent intent) {
String path, miniProgramId, miniprogramType;
path = intent.getData().getQueryParameter("path");
miniProgramId = intent.getData().getQueryParameter("userName");
miniprogramType = intent.getData().getQueryParameter("miniprogramType");
//path decode
if (!TextUtils.isEmpty(path)) {
try {
path = URLDecoder.decode(path, "utf-8");
} catch (UnsupportedEncodingException e) {
}
}
launchMiniProgram(this, miniProgramId, path, miniprogramType);
return true;
}
public void launchMiniProgram(Context context, String miniProgramId, String path,String miniprogramType){
IWXAPI api = WXAPIFactory.createWXAPI(context, appId);
if (!api.isWXAppInstalled()) {
Toast.makeText(context, context.getString("您还没有安装微信"), Toast.LENGTH_SHORT).show();
return;
}
//Android微信6.6.7版本以下有bug,唤起后无法拿到回调参数。此处限制最低唤起版本为6.6.7
if (!(api.getWXAppSupportAPI() >= LAUNCH_MINIPROGRAM_SUPPORTED_SDK_667)) {
Toast.makeText(context, context.getString("请您升级到最新的微信版本,当前版本不支持打开小程序"), Toast.LENGTH_SHORT).show();
return;
}
int miniprogramTypeInt = WXMiniProgramObject.MINIPTOGRAM_TYPE_RELEASE;
if (!TextUtils.isEmpty(miniProgramType)) {
if ("1".equals(miniProgramType)) {
miniprogramTypeInt = WXMiniProgramObject.MINIPROGRAM_TYPE_TEST;
} else if ("2".equals(miniProgramType)) {
miniprogramTypeInt = WXMiniProgramObject.MINIPROGRAM_TYPE_PREVIEW;
}
}
WXLaunchMiniProgram.Req miniProgramReq = new WXLaunchMiniProgram.Req();
miniProgramReq.miniprogramType = miniprogramTypeInt;
miniProgramReq.userName = miniProgramId;
miniProgramReq.path = path;
api.sendReq(miniProgramReq);
}
最终schema结构:
schema://launchMiniProgram?userName=gh_d43f693ca31f&path=common%2fpages&miniprogramType=1
其中参数
- userName 小程序的原始ID。 如果确定只有一个可以写死
- path 要打开小程序内的页面。 可以后端加上自定义的参数,注意这个需要path需要encode下
- miniprogramType 小程序版本。作为参数的目的是方便调试
2、回调
按微信文档中描述,从小程序中跳回App只能通过点击小程序中的按钮方可跳回,如何实现点击按钮跳回App,并携带参数呢,需如下两步
- App端
需要创建WXEntryActivty,实现IWXAPIEventHandler接口,重写onResp方法。注意Acitvity需要在Manifest文件中声明 android:exported="true",这样才可以被外部唤起
public void onResp(BaseResp resp) {
if (resp.getType() == ConstantsAPI.COMMAND_LAUNCH_WX_MINIPROGRAM) {
WXLaunchMiniProgram.Resp launchMiniProResp = (WXLaunchMiniProgram.Resp) resp;
String extraData =launchMiniProResp.extMsg; // 对应下面小程序中的app-parameter字段的value
}
}
- 小程序端
需要将 <button> 组件 open-type 的值设置为 launchApp。如果需要在打开 APP 时向 APP 传递参数,可以设置 app-parameter 为要传递的参数。通过 binderror 可以监听打开 APP 的错误事件。
举例 :<button open-type="launchApp" app-parameter="wechat" binderror="launchAppError">打开APP</button>
这样App拿到的内容就是wechat
总结
主要说下开发中遇到的坑
- 小程序回调APP的extMsg值一直为{} ——微信6.6.6版本的Bug,在6.6.7版本已修复,具体可以看下这个帖子:https://developers.weixin.qq.com/blogdetail?action=get_post_info&docid=000a2818d14998a043d6bf3ac52000&highline=Android
- 最低唤起小程序的微信版本。这个问题源自上个问题,微信API中提供的最低版本为Build.LAUNCH_MINIPROGRAM_SUPPORTED_SDK_INT=620757000。但这个值肯定比6.6.7低。为了稳妥,我们自己限制了唤起小程序用户的最低版本为6.6.7,对应微信openSDK版本为 0x25010500(这个值是费劲吧力找微信人要的。。)