App唤起微信小程序&回调,extMsg值一直为{}问题

需求来源


最近微信的小程序支持从App唤起,操作后支持跳回App的功能。我司产品就来提需求了,希望当前客户端的活动运营位支持跳转小程序的页面,并点击小程序的按钮跳回App指定页面。产品说这个功能可以避免一个活动开发多个页面的问题,并且微信小程序的活动也可以在客户端内展示了。

调研


微信文档:http://https//open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=21526646437Y6nEC&token=&lang=zh_CN

  • 唤起功能
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(这个值是费劲吧力找微信人要的。。)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容

  • 转载链接 注:本文转载知乎上的回答 作者:初雪 链接:https://www.zhihu.com/question...
    pengshuangta阅读 28,540评论 9 295
  • 遇见荷花文/赵春苗图片发自简书App 我是怎样被劫持过来的在夏天这条路上没办法逃脱,如此无助阳光的语言,不再像从前...
    鸟人的羽毛阅读 479评论 0 1
  • 小确幸 昨天听到一个词非常的喜欢“小确幸“育。每天给我的生命加分。育心是一种生活方式,育心已是很多人随时的理想。育...
    悦2017137阅读 328评论 2 1
  • 黑夜之中,童年,满天星斗。父亲在给我讲牛郎织女的故事。那闪烁的星斗为我描绘了男耕女织的美丽画卷。 时至今日您...
    小霞姐阅读 155评论 0 0
  • 有些人喜欢着喜欢着就讨厌了 有些人讨厌着讨厌着就更讨厌了
    二三在左阅读 74评论 0 0