咕咚怎么和微信的运动天数同步,微信运动数据怎么导入到咕咚

首页 > 实用技巧 > 作者:YD1662024-02-24 10:00:37

需求

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

先看一下最终实现效果:

咕咚怎么和微信的运动天数同步,微信运动数据怎么导入到咕咚(1)


微信运动规则

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

实现步骤

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

1、调用小程序API:wx.login获取code和sessionKey; 2、调用小程序API:wx.getWeRunData 获取微信运动数据(加密); 3、调用后端API将运动数据进行解密(Java); 4、小程序集成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: 'wx4167******16a0a1',//appid需自己提供,此处的appid我随机编写 secret: '5498fcab20f********df26bf854ba89',//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/jscode2session?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://127.0.0.1:8080/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 == 200) { let stepInfoList = res.data.stepInfoList; let data = []; let categories = []; for (let i = 0; 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: ["#37A2DA"], 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: #f0145a; width: 100%; height: 300rpx; } .userinfo-btn{ margin-top: 50rpx; background: none !important; color: #fff !important; font-size: 40rpx; } .userinfo-avatar { width: 108rpx; height: 108rpx; margin: 40rpx; border-radius: 50%; } .userinfo-nickname { color: #fff; } ec-canvas { width: 100%; height: 70%; position: absolute; margin-top: 300rpx; top: 0; bottom: 0; left: 0; right: 0; } 后端解密代码(Java)

EncryptedDataController.java

// 解密微信运动数据 @ApiImplicitParam(name = "map",value = "{\"encryptedData\":\"001\",\"sessionkey\":\"2123\",\"iv\":\"111\"}" ) @PostMapping(value = "/getEncryptedData", produces = MediaType.APPLICATION_JSON_UTF8_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 = base64.decode(encryptedData); // 加密秘钥 byte[] keyByte = Base64.decode(sessionkey); // 偏移量 byte[] ivByte = Base64.decode(iv); try { // 如果密钥不足16位,那么就补足 int base = 16; if (keyByte.length % base != 0) { int groups = keyByte.length / base (keyByte.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyByte, 0, temp, 0, keyByte.length); keyByte = temp; } // 初始化 Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "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 > 0) { String result = new String(resultByte, "UTF-8"); 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 = -4526066242748484991L; 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 可视化实现的具体做法就分享到这里了。如果大家有不明白的可以留言,需要源码的话可以留下邮箱,小编有时间将会把源码发送给大家。


咕咚怎么和微信的运动天数同步,微信运动数据怎么导入到咕咚(2)

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.