序:
微信公众号基本的菜单很难满足个性化及多功能的实现,那么微信能否实现自定菜单呢,具体的功能又如何去实现么?下面就来学习一下微信自定义公众号菜单吧!
自定义菜单接口可实现多种类型按钮,如下:
1、click:点击推事件用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;
2、view:跳转URL用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。
3、scancode_push:扫码推事件用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后显示扫描结果(如果是URL,将进入URL),且会将扫码的结果传给开发者,开发者可以下发消息。
4、scancode_waitmsg:扫码推事件且弹出“消息接收中”提示框用户点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具,然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息。
5、pic_sysphoto:弹出系统拍照发图用户点击按钮后,微信客户端将调起系统相机,完成拍照操作后,会将拍摄的相片发送给开发者,并推送事件给开发者,同时收起系统相机,随后可能会收到开发者下发的消息。
6、pic_photo_or_album:弹出拍照或者相册发图用户点击按钮后,微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程。
7、pic_weixin:弹出微信相册发图器用户点击按钮后,微信客户端将调起微信相册,完成选择操作后,将选择的相片发送给开发者的服务器,并推送事件给开发者,同时收起相册,随后可能会收到开发者下发的消息。
8、location_select:弹出地理位置选择器用户点击按钮后,微信客户端将调起地理位置选择工具,完成选择操作后,将选择的地理位置发送给开发者的服务器,同时收起位置选择工具,随后可能会收到开发者下发的消息。
9、media_id:下发消息(除文本消息)用户点击media_id类型按钮后,微信服务器会将开发者填写的永久素材id对应的素材下发给用户,永久素材类型可以是图片、音频、视频、图文消息。请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id。
10、view_limited:跳转图文消息URL用户点击view_limited类型按钮后,微信客户端将打开开发者在按钮中填写的永久素材id对应的图文消息URL,永久素材类型只支持图文消息。请注意:永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id。
请注意,3到8的所有事件,仅支持微信iPhone5.4.1以上版本,和Android5.4以上版本的微信用户,旧版本微信用户点击后将没有回应,开发者也不能正常接收到事件推送。9和10,是专门给第三方平台旗下未微信认证(具体而言,是资质认证未通过)的订阅号准备的事件类型,它们是没有事件推送的,能力相对受限,其他类型的公众号不必使用。
 
 
开始准备:
 
菜单创建接口调用请求说明
http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
参数说明
参数 是否必须 说明
button 一级菜单数组,个数应为1~3个
sub_button 二级菜单数组,个数应为1~5个
type 菜单的响应动作类型,view表示网页类型,click表示点击类型,miniprogram表示小程序类型
name 菜单标题,不超过16个字节,子菜单不超过60个字节
key click等点击类型必须 菜单KEY值,用于消息接口推送,不超过128字节
url view、miniprogram类型必须 网页链接,用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。
media_id media_id类型和view_limited类型必须 调用新增永久素材接口返回的合法media_id
appid miniprogram类型必须 小程序的appid(仅认证公众号可配置)
pagepath miniprogram类型必须 小程序的页面路径
返回结果
 正确时的返回JSON数据包如下:{"errcode":0,"errmsg":"ok"}
错误时的返回JSON数据包如下(示例为无效菜单名长度):{"errcode":40018,"errmsg":"invalid button name size"}
 
菜单查询接口:
开发者还可使用接口查询自定义菜单的结构。另外请注意,在设置了个性化菜单后,使用本自定义菜单查询接口可以获取默认菜单和全部个性化菜单信息。
请求说明
http请求方式:GET
https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN
 
菜单删除接口
使用接口创建自定义菜单后,开发者还可使用接口删除当前使用的自定义菜单。另请注意,在个性化菜单时,调用此接口会删除默认菜单及全部个性化菜单。
请求说明
http请求方式:GET
https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN
返回说明
对应创建接口,正确的Json返回结果:
{"errcode":0,"errmsg":"ok"}
 
动手实现:
对于菜单中按钮属性,可定义个菜单按钮基类

  1. /**
  2. * 微信菜单基类
  3. * @author Damon
  4. */
  5. public class MenuButton
  6. {
  7. /**
  8. * 菜单的响应动作类型,view表示网页类型,click表示点击类型,miniprogram表示小程序类型
  9. */
  10. private String type = "";
  11.  
  12. /**
  13. * 菜单标题,不超过16个字节,子菜单不超过60个字节
  14. */
  15. private String name = "";
  16.  
  17. public String getType()
  18. {
  19. return type;
  20. }
  21.  
  22. public void setType(String type)
  23. {
  24. this.type = type;
  25. }
  26.  
  27. public String getName()
  28. {
  29. return name;
  30. }
  31.  
  32. public void setName(String name)
  33. {
  34. this.name = name;
  35. }
  36.  
  37. }

对于子菜单,可以继承基类,同时对本身新增属性对定义:

  1. /**
  2. * 子菜单
  3. * @author Damon
  4. *
  5. */
  6. public class SubMenuButton extends MenuButton
  7. {
  8. /**
  9. * click等点击类型必须 菜单KEY值,用于消息接口推送,不超过128字节
  10. */
  11. private String key ="";
  12.  
  13. /**
  14. * view、miniprogram类型必须 网页链接,用户点击菜单可打开链接,不超过1024字节。
  15. * type为miniprogram时,不支持小程序的老版本客户端将打开本url。
  16. */
  17. private String url="";
  18.  
  19. /**
  20. * media_id类型和view_limited类型必须 调用新增永久素材接口返回的合法media_id
  21. */
  22. private String media_id = "";
  23.  
  24. /**
  25. * miniprogram类型必须 小程序的appid(仅认证公众号可配置)
  26. */
  27. private String appid = "";
  28.  
  29. /**
  30. * miniprogram类型必须 小程序的页面路径
  31. */
  32. private String pagepath = "";
  33.  
  34. public String getKey()
  35. {
  36. return key;
  37. }
  38.  
  39. public void setKey(String key)
  40. {
  41. this.key = key;
  42. }
  43.  
  44. public String getUrl()
  45. {
  46. return url;
  47. }
  48.  
  49. public void setUrl(String url)
  50. {
  51. this.url = url;
  52. }
  53.  
  54. public String getMedia_id()
  55. {
  56. return media_id;
  57. }
  58.  
  59. public void setMedia_id(String media_id)
  60. {
  61. this.media_id = media_id;
  62. }
  63.  
  64. public String getAppid()
  65. {
  66. return appid;
  67. }
  68.  
  69. public void setAppid(String appid)
  70. {
  71. this.appid = appid;
  72. }
  73.  
  74. public String getPagepath()
  75. {
  76. return pagepath;
  77. }
  78.  
  79. public void setPagepath(String pagepath)
  80. {
  81. this.pagepath = pagepath;
  82. }
  83.  
  84. }

对导航窗口进行定义,即包含多个子菜单:

  1. /**
  2. * 导航菜单
  3. * @author Damon
  4. */
  5. public class LevelMenu extends MenuButton
  6. {
  7.  
  8. /**
  9. * 包含多个子菜单 定义名称与json中一致,不然解析名称对不上
  10. */
  11. private SubMenuButton[] sub_button;
  12.  
  13. public SubMenuButton[] getSub_button()
  14. {
  15. return sub_button;
  16. }
  17.  
  18. public void setSub_button(SubMenuButton[] sub_button)
  19. {
  20. this.sub_button = sub_button;
  21. }
  22.  
  23. }

最终封装一个菜单类,方便数据封装和解析:

  1. /**
  2. * 微信菜单类
  3. * @author Damon
  4. */
  5. public class Menu
  6. {
  7.  
  8. /* 定义名称与json中一致,不然解析名称对不上 */
  9. private MenuButton[] button;
  10.  
  11. public MenuButton[] getButton()
  12. {
  13. return button;
  14. }
  15.  
  16. public void setButton(MenuButton[] button)
  17. {
  18. this.button = button;
  19. }
  20.  
  21. }

基本对象都定义好了,下一步就是进行接口调用,实现创建自定义菜单:

实现主要分3步:
1、获取有效的 access_token
2、组件菜单;
3、调用接口,实现创建
  1. /**
  2. * 创建菜单
  3. * @param menu
  4. * @return
  5. */
  6. public boolean createMenu()
  7. {
  8.  
  9. // 1、获取access_token
  10. WeChatTokenService tWeChatTokenService = new WeChatTokenService();
  11. String tAccess_Token = tWeChatTokenService.getToken("appid", "appsceret").getToken();
  12.  
  13. // 2、组建菜单
  14. String tMenuJSON = JSONObject.fromObject(getMenu()).toString();
  15.  
  16. // 3、请求调用
  17. String result = createMenubyHttps(tAccess_Token, tMenuJSON);
  18.  
  19. System.out.println(result);
  20.  
  21. return true;
  22. }

其中 access_token的获取可参考之前第三节的,这样每个token都有2个小时的有效时间,不用频繁获取。

组件菜单,详细如下:

  1. /**
  2. * 定义菜单属性
  3. * @return
  4. */
  5. private Menu getMenu()
  6. {
  7. Menu menu = new Menu();
  8.  
  9. // 建3个导航菜单
  10. LevelMenu tLevelMenuOne = new LevelMenu();
  11. tLevelMenuOne.setName("Damon");
  12. LevelMenu tLevelMenuTwo = new LevelMenu();
  13. tLevelMenuTwo.setName("Panou");
  14. LevelMenu tLevelMenuThree = new LevelMenu();
  15. tLevelMenuThree.setName("Papaw");
  16.  
  17. // 第一个导航菜单的子菜单
  18. SubMenuButton tSubMenuButton_oneone = new SubMenuButton();
  19. tSubMenuButton_oneone.setType(SysCon.WECHAT_MENU_TYPE_CLICK);
  20. tSubMenuButton_oneone.setName("play basketball");
  21. tSubMenuButton_oneone.setKey("11");
  22.  
  23. SubMenuButton tSubMenuButton_onetwo = new SubMenuButton();
  24. tSubMenuButton_onetwo.setType(SysCon.WECHAT_MENU_TYPE_CLICK);
  25. tSubMenuButton_onetwo.setName("swimming");
  26. tSubMenuButton_onetwo.setKey("12");
  27.  
  28. // 加入导航菜单
  29. tLevelMenuOne.setSub_button(new SubMenuButton[]
  30. { tSubMenuButton_oneone, tSubMenuButton_onetwo });
  31.  
  32. // 第二 个导航菜单的子菜单
  33. SubMenuButton tSubMenuButton_twoone = new SubMenuButton();
  34. tSubMenuButton_twoone.setType(SysCon.WECHAT_MENU_TYPE_CLICK);
  35. tSubMenuButton_twoone.setName("watching TV");
  36. tSubMenuButton_twoone.setKey("21");
  37.  
  38. SubMenuButton tSubMenuButton_twotwo = new SubMenuButton();
  39. tSubMenuButton_twotwo.setType(SysCon.WECHAT_MENU_TYPE_CLICK);
  40. tSubMenuButton_twotwo.setName("play games");
  41. tSubMenuButton_twotwo.setKey("22");
  42.  
  43. SubMenuButton tSubMenuButton_twothree = new SubMenuButton();
  44. tSubMenuButton_twothree.setType(SysCon.WECHAT_MENU_TYPE_CLICK);
  45. tSubMenuButton_twothree.setName("shopping");
  46. tSubMenuButton_twothree.setKey("23");
  47.  
  48. // 加入导航菜单
  49. tLevelMenuTwo.setSub_button(new SubMenuButton[]
  50. { tSubMenuButton_twoone, tSubMenuButton_twotwo, tSubMenuButton_twothree });
  51.  
  52. // 第三个导航菜单的子菜单
  53. SubMenuButton tSubMenuButton_threeone = new SubMenuButton();
  54. tSubMenuButton_threeone.setType(SysCon.WECHAT_MENU_TYPE_CLICK);
  55. tSubMenuButton_threeone.setName("cring");
  56. tSubMenuButton_threeone.setKey("31");
  57.  
  58. SubMenuButton tSubMenuButton_threetwo = new SubMenuButton();
  59. tSubMenuButton_threetwo.setType(SysCon.WECHAT_MENU_TYPE_CLICK);
  60. tSubMenuButton_threetwo.setName("laughing");
  61. tSubMenuButton_threetwo.setKey("32");
  62.  
  63. // 加入导航菜单
  64. tLevelMenuThree.setSub_button(new SubMenuButton[]
  65. { tSubMenuButton_threeone, tSubMenuButton_threetwo });
  66.  
  67. menu.setButton(new MenuButton[]
  68. { tLevelMenuOne, tLevelMenuTwo, tLevelMenuThree });
  69.  
  70. return menu;
  71.  
  72. }

通过对象的封装进行获取,然后转成JSON格式。
接着就是通过https进行接口调用(这里用到之前工具类中HTTPS的请求方法):
  1. /**
  2. * 请求调用,设置菜单信息
  3. * @param url
  4. * @param requestData
  5. * @return
  6. */
  7. private String createMenubyHttps(String access_token, String requestData)
  8. {
  9. // 返回报文
  10. String strResp = "";
  11. String path = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + access_token;
  12. try
  13. {
  14. strResp = WeChatUtil.doHttpsPost(path, requestData);
  15. }
  16. catch (HttpException e)
  17. {
  18. // 发生致命的异常,可能是协议不对或者返回的内容有问题
  19. System.out.println("Please check your provided http address!" + e);
  20. e.printStackTrace();
  21. }
  22. catch (IOException e)
  23. {
  24. // 发生网络异常
  25. }
  26. catch (Exception e)
  27. {
  28. System.out.println(e);
  29. }
  30. finally
  31. {}
  32. return strResp;
  33.  
  34. }

 自定义菜单的基本调用就实现了,可以看到效果图:
 
 
这里写的都是基本的点击事件,但是没有实现,具体的自己去发挥了~

玩玩微信公众号Java版之四:自定义公众号菜单的更多相关文章

  1. 玩玩微信公众号Java版之七:自定义微信分享

    前面已经学会了微信网页授权,现在微信网页的功能也可以开展起来啦! 首先,我们先来学习一下分享,如何在自己的页面获取分享接口及让小伙伴来分享呢? 今天的主人公: 微信 JS-SDK, 对应官方链接为:微 ...

  2. 微信公众平台Java版极速SDK

    JEEWX-API 是第一个微信公众平台Java版极速SDK,基于 jeewx-api 开发可以立即拥有简单易用的API,让开发更加轻松自如,节省更多时间 http://www.jeewx.com/

  3. 玩玩微信公众号Java版之六:微信网页授权

    我们经常会访问一些网站,用微信登录的时候需要用到授权,那么微信网页授权是怎么一回事呢,一起来看看吧!   参考官方文档:https://mp.weixin.qq.com/wiki?t=resource ...

  4. 微信5.4安卓版重回ios风格 导航菜单都放底栏位置

    微信5.4安卓版发布更新了,由于本人的手机设置软件自动更新,中午的时候才发现微信换成了5.4版本,启动微信后是一个大大的“转账,就是发消息”,进入微信界面有点小惊喜,导航菜单都改为底部tab方式,顶部 ...

  5. 玩玩微信公众号Java版之三:access_token及存储access_token

    微信官方参考文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183   基本说明: access_token是 ...

  6. 玩玩微信公众号Java版之一:配置微信公众平台服务器信息

    在进行微信公众平台开发前,前先做好准备工作,好了以后,我们可以开始啦!   第一.准备好服务端接口   定义一个http服务接口,主要分为如下几步:   1.创建一个servlet类,用来接收请求: ...

  7. 玩玩微信公众号Java版之准备

    微信自2013年流行起来,现在的发展已经超过了我们的想象,那么对应的公众平台,小程序等都是让人眼前一亮的东西,这里来学习一下微信工作号的对接,实现为Java,希望大家一起学习!   这里大概描述一下所 ...

  8. 玩玩微信公众号Java版之五:获取关注用户信息

    在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同).公众号可通过本接口来根据Op ...

  9. 玩玩微信公众号Java版之二:接收、处理及返回微信消息

    前面已经配置了微信服务器,那么先开始最简单的接收微信消息吧~   可以用我们的微信号来直接进行测试,下面先看测试效果图:   这是最基本的文本消息的接收.处理及返回,来看看是怎么实现的吧!   首先可 ...

随机推荐

  1. 开发Activity步骤

    第一步:写一个累继承Activity第二步:重写onCreate方法第三步:在主配置文件中注册activity <activity android:name=".类名" an ...

  2. map,zip,reduce函数

    lt=range(5,10) lw=range(8,13) def mul(a,b): return a*b def mul_list(param1,param2): return_list=[] f ...

  3. js获取地址栏某个参数

    一.获取单个参数: 若地址栏URL为:abc.html?id=123 function getString(){      var locurl=location.href;      var sta ...

  4. CSS 公共样式

    global.css | reset.css(格式化样式) common.css(公共组件样式) layout.css(当前页面样式) 清除全站所有页面的浏览器默认样式,保证在初始样式在所有浏览器下一 ...

  5. Bash变量扩展修改符

    1.未设置就临时替换(:-) 冒号:用来检验变量是否设置过,如果没有冒号,则认为设置过,不替换$fruit=peach$echo ${fruit:-plum}peach $fruit=$echo ${ ...

  6. 【LCA求最近公共祖先+vector构图】Distance Queries

    Distance Queries 时间限制: 1 Sec  内存限制: 128 MB 题目描述 约翰的奶牛们拒绝跑他的马拉松,因为她们悠闲的生活不能承受他选择的长长的赛道.因此他决心找一条更合理的赛道 ...

  7. noip借教室 题解

    题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自然 ...

  8. [Tool] Git 使用 与 Git Flow

    目录 简介 Git 命令 Git Flow 简介 Git是目前世界上最先进的分布式版本控制系统(没有之一). Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Lin ...

  9. Hybris 6.4 + Jrebel

    Jrebel官网参考地址:https://manuals.zeroturnaround.com/jrebel/standalone/hybris.html Wiki Hybris参考地址:https: ...

  10. Linux下如何启动svn服务器

    service svnserve start 启动服务 service svnserve stop 停止服务 service svnserve restart 重启服务 rpm -e --nodeps ...