官方API
步骤
1,APP端拉起微信小程序
2,小程序端获取微信运动数据
3,后台解密获取的微信运动数据
实现
1,APP端调起微信小程序
准备工作:
1)微信开放平台,微信公众平台注册应用,小程序,并绑定。通过微信开放平台注册的appid我称为应用id,通过微信公众平台注册的appid我称为小程序id,然后微信公众平台还有一个小程序原始id。
2)开始拉起小程序的时候一直跳转失败,也没有详细信息提示。这方面微信也太次了,官方文档也有很多坑,说的不明不白。按照官方文档,拉起小程序时需要一个应用id,一个小程序原始id。用微信公众平台获取到的appid就是跳转失败。
3)这里传入微信开放平台注册的appid就可以了。
具体代码:
String appId = "wxb4c043ea********"; // 填应用AppId
IWXAPI api = WXAPIFactory.createWXAPI(this, appId);
WXLaunchMiniProgram.Req req = new WXLaunchMiniProgram.Req();
req.userName = "gh_ec76********"; // 填小程序原始id
req.path = "pages/index/index?userid="+UserInfo.getUserid(); //拉起小程序页面的可带参路径,不填默认拉起小程序首页
req.miniprogramType = WXLaunchMiniProgram.Req.MINIPTOGRAM_TYPE_RELEASE;// 可选打开 开发版,体验版和正式版//MINIPROGRAM_TYPE_PREVIEW
api.sendReq(req);
2,小程序获取微信运动数据
1)这个很简单,随便贴下代码就行了,不理解的可以看官方文档,这块没有坑。
onShow: function () {
// 展示本地存储能力
var logs = wx.getStorageSync('logs') || []
var _this = this;
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: resLogin => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
console.log(resLogin.code),
wx.request({
url: '**************************************************',
data: {
code: resLogin.code
},
success: res => {
wx.getSetting({
success: res => {
wx.getWeRunData({
success: resRun => {
const encryptedData = resRun.encryptedData
//console.log('ssss' + encryptedData);
wx.request({
url: '****************************',
data: {
encryptedData: resRun.encryptedData,
iv: resRun.iv,
},
success: resDecrypt => {
console.log(resDecrypt)
var runData = JSON.parse(resDecrypt.data.data)
console.info(runData);
// _this.aaa(runData)
_this.globalData.step = runData;
if (_this.stepCallBack) {
_this.stepCallBack(runData);
}
},
})
},
fail: res => {
wx.showModal({
title: '提示',
//content: '开发者未开通微信运动,请关注“微信运动”公众号后重试',
content: '获取微信运动步数,需要开启计步权限',
showCancel: false,
success: function (res) {
if (res.confirm) {
//跳转去设置
wx.openSetting({
success: res => {
}
})
}
}
// showCancel: false,
// confirmText: '知道了'
})
}
})
//}
}
})
}
})
}
})
},
3,后台解密运动数据
1)第一步获取session_key:
String code = para.getString("code");
String appid = para.getString("appid");
String appSecret = para.getString("appSecret");
String result = GetSession(appid, appSecret, code);
JSONObject jsonObject = JSONObject.fromObject(result);
String sessionkey = jsonObject.getString("session_key");
Cache.put("sessionkey", sessionkey);
GetSession方法:
public static String GetSession(String appid,String appSecret,String code){
String WX_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=APPSECRET&js_code=acode&grant_type=authorization_code";
String requestUrl = WX_URL.replace("APPID", appid).replace("APPSECRET", appSecret).replace("acode",code).replace("authorization_code", "authorization_code");
String value = sendGet(requestUrl);
return value;
}
sendGet方法:
public static String sendGet(String url) {
String result = "";
BufferedReader in = null;
try {
//String urlNameString = url + "?" + param;
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
/*for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}*/
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
这就可以获取到session_key,并且存储到缓存中。
2)解密数据
public void onDecrypt(String encryptedData, String iv, String appId,) throws Exception {
String sessionkey = Cache.get("sessionkey");
// 被加密的数据
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);
// vdo.put("data", result);
JSONObject jsonObject = JSONObject.fromObject(result);
JSONArray jsonArray = jsonObject.getJSONArray("stepInfoList");
//这就是解密的数据
JSONObject json = (JSONObject) jsonArray.get(30);
}
} 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();
}
}
就先贴代码吧,等有时间再加工加工。
有问题留言讨论,互相学习。