当前位置:首页 » 新媒体运营 » 正文

微信刷步数,小程序获取微信运动步数并可视化显示

5407 人参与  2022年10月27日 09:56  分类 : 新媒体运营  评论
需求

现在运动计步非常的火,大家常用的计步工具一般有keep、咕咚、微信运动和其他移动设备等,本文是基于微信小程序获取用户的微信运动数据并可视化呈现出来。

先看一下最终实现效果:

微信刷步数,小程序获取微信运动步数并可视化显示-百度竞价优化_微商推广_今日头条自媒体_新媒体运营_剑谦网络



微信运动规则

在开发之前需要了解一下微信运动信息的使用规则,这样会规避掉很多问题。
、微信运动数据必须在微信生态内获取,即小程序、公众号等,且需要用户进行授权。
、用户主动进入小程序时可以获取到最近天的运动数据,且一次性获取全部,不能获取指定时间段内的运动数据。
、目前只能获取到运动“步数”,其他的获取不到(例如:卡路里、公里数、运动轨迹等)。

实现步骤

如果要实现上图示例中的效果需要完成一下几个步骤:

、调用小程序API:wx.login获取code和sessionKey;、调用小程序API:wx.getWeRunData 获取微信运动数据(加密);、调用后端API将运动数据进行解密(Java);、小程序集成echarts.js 实现线状图展示;
小程序代码(原生)第一步:配置页面

在app.json 文件pages内增加WeRunData配置将会自动创建WeRunData.js、WeRunData.json、WeRunData.wxml和WeRunData.wxss 四个文件。

"pages":[    "pages/WeRunData/WeRunData"],
第二步:获取微信授权
var app = getApp()var userInfo = null;
Page({  globalData: {    appid: &#;wx******aa&#;,//appid需自己提供,此处的appid我随机编写    secret: &#;fcabf********dfbfba&#;,//secret需自己提供,此处的secret我随机编写
  },  data: {    userInfo: {},    hasUserInfo: false,    canIUse: wx.canIUse(&#;button.open-type.getUserInfo&#;),    encryptedData:null,    sessionkey:null,    iv:null
  },  onLoad: function () {    var that = this;    if (app.globalData.userInfo) {      this.setData({        userInfo: app.globalData.userInfo,        hasUserInfo: true
      })
    } else if (this.data.canIUse) {      // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回      // 所以此处加入 callback 以防止这种情况
      app.userInfoReadyCallback = res => {        this.setData({          userInfo: res.userInfo,          hasUserInfo: true
        })
      }
    } else {      // 在没有 open-type=getUserInfo 版本的兼容处理
      wx.getUserInfo({        success: res => {
          app.globalData.userInfo = res.userInfo          this.setData({            userInfo: res.userInfo,            hasUserInfo: true
          })
        }
      })
    }    //登录凭证校验。通过 wx.login() 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。
    wx.login({      success: function (res) {        if (res.code) {          console.log("res.code:" + res.code);          var d = that.globalData;//这里存储了appid、secret、token串          var l = &#;https://api.weixin.qq.com/sns/jscodesession?appid=&#; + d.appid + &#;&secret=&#; + d.secret + &#;&js_code=&#; + res.code + &#;&grant_type=authorization_code&#;;
          wx.request({            url: l,            data: {},            method: &#;GET&#;,            success: function (res) {              var obj = {};
              obj.openid = res.data.openid;              console.log("openid:" + obj.openid);              console.log("session_key:" + res.data.session_key);
              obj.expires_in = Date.now() + res.data.expires_in;
              that.setData({                sessionkey: res.data.session_key,
              })
              wx.setStorageSync(&#;user&#;, obj);//存储openid
              wx.getWeRunData({
                success(res) {                  // 拿 encryptedData 到开发者后台解密开放数据                  const encryptedData = res.encryptedData                  console.log("encryptedData:" + encryptedData)                  // 或拿 cloudID 通过云调用直接获取开放数据                  const cloudID = res.cloudID                  console.log("cloudID:" + cloudID)                  console.log("iv:" + res.iv)                  // 解密运动数据
                  that.setData({                    encryptedData: res.encryptedData,                    iv: res.iv
                  })                  // 调用第三步去解密
                  that.getEncryptedData();
                }
              })
            }
          });
        } else {          console.log(&#;获取用户登录态失败!&#; + res.errMsg)
        }
      }
    });
  },  getUserInfo: function (e) {    console.log(e)
    app.globalData.userInfo = e.detail.userInfo    this.setData({      userInfo: e.detail.userInfo,      hasUserInfo: true
    })
  }
})
第三步:解密运动数据

WeRunData.js 解密

getEncryptedData: function () {    var that = this;
    wx.request({
      url: &#;http://...:/getEncryptedData&#;, // 这里需要去请求后端代码进行解密,示例中使用Java实现。
      method: "POST",      data: {
        encryptedData: this.data.encryptedData,
        sessionkey: this.data.sessionkey,
        iv: this.data.iv
      },
      header: {        "Content-Type": "application/json"
      },
      success: function (res) {
        console.log("解密后的数据为:", res);        if (res.statusCode == ) {
          let stepInfoList = res.data.stepInfoList;
          let data = [];
          let categories = [];          for (let i = ; i < stepInfoList.length; i++) {
            categories.push(stepInfoList[i].stepTime);            data.push(stepInfoList[i].step);
          }
          chartData.main.categories = categories;
          chartData.main.data = data;          // 调用第四步 可视化加载
          that.stepChartLine();
        }
      }
    })
  },
第四步:集成echarts.js 运动数据可视化

集成步骤可以参考Echarts官方步骤:
https://github.com/ecomfe/echarts-for-weixin
WeRunData.js 渲染图表

import * as echarts from &#;../../ec-canvas/echarts&#;;var chartData = {
  main: {    data: [], // 运动步数集合
    categories: []  // 运动日期集合
  }
};//初始化图表
  init_echarts: function () {    this.echartsComponnet.init((canvas, width, height) => {      // 初始化图表      const Chart = echarts.init(canvas, null, {
        width: width,
        height: height
      });
      Chart.setOption(this.getOption());      // 注意这里一定要返回 chart 实例,否则会影响事件处理等      return Chart;
    });
  },    // 获取数据
    getOption: function () {      var that = this      var legendList = []      var option = {
        title: {
          left: &#;center&#;
        },
        color: ["#ADA"],
        grid: {
          containLabel: true
        },
        tooltip: {
          show: true,
          trigger: &#;axis&#;
        },
        xAxis: {
          type: &#;category&#;,
          boundaryGap: false,          data: chartData.main.categories
        },
        yAxis: {
          x: &#;center&#;,
          type: &#;value&#;,
          splitLine: {
            lineStyle: {
              type: &#;dashed&#;
            }
          }
        },
        series: [{
          type: &#;line&#;,
          smooth: true,          data: chartData.main.data
        }]
      };      return option
    }
第五步:页面布局

WeRunData.wxml

<view class="userinfo">  <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo" class="userinfo-btn"> 点击微信授权 </button>  <block wx:else>    <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>    <text class="userinfo-nickname">{{userInfo.nickName}}</text>  </block></view><view class="container">  <ec-canvas id="mychart-dom-line" canvas-id="mychart-line" ec="{{ ec }}"></ec-canvas></view>

WeRunData.wxss

.userinfo {  display: flex;  flex-direction: column;  align-items: center;  background: #fa;   width: %;  height: rpx;
}.userinfo-btn{  margin-top: rpx;  background: none !important;  color: #fff !important;  font-size: rpx;
}.userinfo-avatar {  width: rpx;  height: rpx;  margin: rpx;  border-radius: %;
}.userinfo-nickname {  color: #fff;
}ec-canvas {  width: %;  height: %;  position: absolute;  margin-top: rpx;  top: ;  bottom: ;  left: ;  right: ;
}
后端解密代码(Java)

EncryptedDataController.java

// 解密微信运动数据@ApiImplicitParam(name = "map",value = "{"encryptedData":"","sessionkey":"","iv":""}" )@PostMapping(value = "/getEncryptedData", produces = MediaType.APPLICATION_JSON_UTF_VALUE)public WxChartStepInfoDTO getEncryptedData(@RequestBody Map<String,String> map) {
  String encryptedData = map.get("encryptedData");
  String sessionkey = map.get("sessionkey");
  String iv = map.get("iv");  // 被加密的数据  byte[] dataByte = Base.decode(encryptedData);  // 加密秘钥  byte[] keyByte = Base.decode(sessionkey);  // 偏移量  byte[] ivByte = Base.decode(iv);  try {       // 如果密钥不足位,那么就补足      int base = ;      if (keyByte.length % base != ) {          int groups = keyByte.length / base + (keyByte.length % base !=  ?  : );          byte[] temp = new byte[groups * base];
          Arrays.fill(temp, (byte) );
          System.arraycopy(keyByte, , temp, , keyByte.length);
          keyByte = temp;
       }      // 初始化
      Security.addProvider(new BouncyCastleProvider());
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCSPadding", "BC");
      SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
      AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
      parameters.init(new IvParameterSpec(ivByte));
      cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化      byte[] resultByte = cipher.doFinal(dataByte);      if (null != resultByte && resultByte.length > ) {
          String result = new String(resultByte, "UTF-");
          System.out.println("result:" + result);
          Gson gson = new Gson();
          WxChartStepInfoDTO wxChartStepInfoDTO = gson.fromJson(result,WxChartStepInfoDTO.class);          return wxChartStepInfoDTO;
        }
     } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
     } catch (NoSuchPaddingException e) {
        e.printStackTrace();
     } catch (InvalidParameterSpecException e) {
        e.printStackTrace();
     } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
     } catch (BadPaddingException e) {
        e.printStackTrace();
     } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
     } catch (InvalidKeyException e) {
        e.printStackTrace();
     } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        e.printStackTrace();
    }    return null;
 }

WxChartStepInfoDTO.java

@NoArgsConstructor@Data@ApiModel(value = "微信运动实体")public class WxChartStepInfoDTO implements Serializable{    private static final long serialVersionUID = -L;    private List<StepListBean> stepInfoList;    private WatermarkBean watermark;    @NoArgsConstructor    @Data    public static class StepListBean implements Serializable {
        Long timestamp; // 运动日期
        Integer step; // 运动步数        @JsonFormat(pattern = "MM-dd")
        Date stepTime; // 运动日期(格式化为:yyyy-MM-dd HH:mm:ss)        public Date getStepTime() {            return StringUtil.getSecondToDate(this.timestamp,"yyyy-MM-dd HH:mm:ss");
        }
    }    @NoArgsConstructor    @Data    public static class WatermarkBean implements Serializable {        @ApiModelProperty(value = "同步微信运动时间")        private Long timestamp;        @ApiModelProperty(value = "appid",required = true)        private String appid;        @ApiModelProperty(value = "格式化运动时间")        @JsonFormat(pattern = "MM-dd")
        Date time; // 运动日期(格式化为:yyyy-MM-dd HH:mm:ss)        public Date getTime() {            return StringUtil.getSecondToDate(timestamp,"yyyy-MM-dd HH:mm:ss");
        }
    }
}
最后

好了,小程序获取微信运动步数并集成echarts.js 可视化实现的具体做法就分享到这里了。如果大家有不明白的可以留言,需要源码的话可以留下邮箱,小编有时间将会把源码发送给大家。

本文链接:https://www.woshiqian.com/post/156432.html

百度分享获取地址:https://share.baidu.com/code
一键刷步数微信  

我是钱微信/QQ:5087088

广告位、广告合作QQ:5087088

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

       

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。