
安卓检查升级及安装包下载进度
代码来源
另:极力推荐官方的upgrade-center https://uniapp.dcloud.io/uniCloud/upgrade-center,非常方便
App.vue中的代码,负责检测
<script>
import { serverUrl } from '@/util/http'
export default {
globalData: {
title: '管理系统',
ver: 101,
},
onLaunch: function() {
console.log('App Launch')
this.checkVer()
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
},
methods: {
checkVer: function() {
uni.getSystemInfo({
success: (res) => {
console.log(res.platform);
//检测当前平台,如果是安卓则启动安卓更新
if (res.platform == "android") {
this.AndroidCheckUpdate();
}
}
})
},
AndroidCheckUpdate: function() {
var _this = this;
uni.request({
url: serverUrl + '/check-ver',
method: 'GET',
data: {},
success: res => {
console.log('res', res.data.data)
const data = res.data.data
const ver = data.ver
const downUrl = data.url
if (ver > this.globalData.ver) {
uni.showToast({
title: '有新的版本发布,程序已启动自动更新。新版本下载完成后将自动弹出安装程序。',
mask: true,
duration: 5000,
icon: "none"
});
var prg = 0;
var dtask = plus.downloader.createDownload(downUrl, {}, function(d, status) {
// 下载完成
if (status == 200) {
plus.runtime.install(plus.io.convertLocalFileSystemURL(d.filename), {}, {}, function(
error) {
uni.showToast({
title: '安装失败',
mask: false,
duration: 1500
});
})
} else {
uni.showToast({
title: '更新失败',
mask: false,
duration: 1500
});
}
});
dtask.start();
var showLoading = plus.nativeUI.showWaiting("正在下载");
dtask.addEventListener('statechanged', function(task, status) {
// 给下载任务设置一个监听 并根据状态 做操作
switch (task.state) {
case 1:
showLoading.setTitle("正在下载");
break;
case 2:
showLoading.setTitle("已连接到服务器");
break;
case 3:
prg = parseInt(
(parseFloat(task.downloadedSize) /
parseFloat(task.totalSize)) *
100
);
showLoading.setTitle("版本更新,正在下载" + prg + "% ");
break;
case 4:
plus.nativeUI.closeWaiting();
//下载完成
break;
}
});
}
},
fail: () => {},
complete: () => {}
});
},
}
}
</script>
服务器响应的代码
返回内容
{code: 0, message: '', data: {ver: 102, url: 'http://...com/file_102.apk'}}
代码来源
另:极力推荐官方的upgrade-center https://uniapp.dcloud.io/uniCloud/upgrade-center,非常方便
App.vue中的代码,负责检测
<script>
import { serverUrl } from '@/util/http'
export default {
globalData: {
title: '管理系统',
ver: 101,
},
onLaunch: function() {
console.log('App Launch')
this.checkVer()
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
},
methods: {
checkVer: function() {
uni.getSystemInfo({
success: (res) => {
console.log(res.platform);
//检测当前平台,如果是安卓则启动安卓更新
if (res.platform == "android") {
this.AndroidCheckUpdate();
}
}
})
},
AndroidCheckUpdate: function() {
var _this = this;
uni.request({
url: serverUrl + '/check-ver',
method: 'GET',
data: {},
success: res => {
console.log('res', res.data.data)
const data = res.data.data
const ver = data.ver
const downUrl = data.url
if (ver > this.globalData.ver) {
uni.showToast({
title: '有新的版本发布,程序已启动自动更新。新版本下载完成后将自动弹出安装程序。',
mask: true,
duration: 5000,
icon: "none"
});
var prg = 0;
var dtask = plus.downloader.createDownload(downUrl, {}, function(d, status) {
// 下载完成
if (status == 200) {
plus.runtime.install(plus.io.convertLocalFileSystemURL(d.filename), {}, {}, function(
error) {
uni.showToast({
title: '安装失败',
mask: false,
duration: 1500
});
})
} else {
uni.showToast({
title: '更新失败',
mask: false,
duration: 1500
});
}
});
dtask.start();
var showLoading = plus.nativeUI.showWaiting("正在下载");
dtask.addEventListener('statechanged', function(task, status) {
// 给下载任务设置一个监听 并根据状态 做操作
switch (task.state) {
case 1:
showLoading.setTitle("正在下载");
break;
case 2:
showLoading.setTitle("已连接到服务器");
break;
case 3:
prg = parseInt(
(parseFloat(task.downloadedSize) /
parseFloat(task.totalSize)) *
100
);
showLoading.setTitle("版本更新,正在下载" + prg + "% ");
break;
case 4:
plus.nativeUI.closeWaiting();
//下载完成
break;
}
});
}
},
fail: () => {},
complete: () => {}
});
},
}
}
</script>
服务器响应的代码
返回内容
{code: 0, message: '', data: {ver: 102, url: 'http://...com/file_102.apk'}}
收起阅读 »

App微信登录{"errcode":40029,"errmsg":"invalid code, rid: 6306ee95-187a67c0-5f5d2ec7"}
uni.login 获取 code 去后台换取 openid,这个操作一定不要放在 app.vue 的 onLaunch 里面,否则一直报错{"errcode":40029,"errmsg":"invalid code, rid: 6306ee95-187a67c0-5f5d2ec7"},浪费一上午时间,虽然不知道原因。
uni.login 获取 code 去后台换取 openid,这个操作一定不要放在 app.vue 的 onLaunch 里面,否则一直报错{"errcode":40029,"errmsg":"invalid code, rid: 6306ee95-187a67c0-5f5d2ec7"},浪费一上午时间,虽然不知道原因。
收起阅读 »
未配置appkey在模拟器需要重启设备才能生效
用了模拟器,测试了几十次,实在没办法查了下apk签名发现一致,然后重启下了设备(不重启清理设备缓存)就可以了,浪费了三个小时!
用了模拟器,测试了几十次,实在没办法查了下apk签名发现一致,然后重启下了设备(不重启清理设备缓存)就可以了,浪费了三个小时!

项目简要 uniapp框架会员移动网页客户端
项目简要
uniapp框架会员移动网页客户端
工作要求
- 增加功能, 优化和长期维护.
- 迁移 uniapp vue2 到 vue3.
开发者要求:
全职独立开发者, 谢绝团队.
至少2年 uniapp 项目开发经验.
至少1年 typescript 项目开发经验.
熟悉或使用过 thorui 优先.
有 迁移 uniapp vue2 到 vue3 的项目经验优先
使用过Gitflow
具备英文读写能力.
三,待遇:
- 基本底薪,月结 (考虑到接任何项目如果想提升代码质量,都需要熟悉,需要能优化,模块化代码)
- 底薪之外,按页面和功能付钱,多劳多得.
- 联系方式微信18872319732 邮箱xuqu911@126.com
项目简要
uniapp框架会员移动网页客户端
工作要求
- 增加功能, 优化和长期维护.
- 迁移 uniapp vue2 到 vue3.
开发者要求:
全职独立开发者, 谢绝团队.
至少2年 uniapp 项目开发经验.
至少1年 typescript 项目开发经验.
熟悉或使用过 thorui 优先.
有 迁移 uniapp vue2 到 vue3 的项目经验优先
使用过Gitflow
具备英文读写能力.
三,待遇:
- 基本底薪,月结 (考虑到接任何项目如果想提升代码质量,都需要熟悉,需要能优化,模块化代码)
- 底薪之外,按页面和功能付钱,多劳多得.
- 联系方式微信18872319732 邮箱xuqu911@126.com

阿里云的全部ip名单,可用于需要固定ip的服务
阿里云的ip是不固定的,但是是有限的,下面我给大家总结了全部的ip,直接复制到需要固定ip的地方(比如公众号开发以及微信支付开发),就可以使用
"106.55.29.200",
"120.231.66.200",
"120.239.43.174",
"39.103.221.6",
"8.142.75.1",
"8.142.83.203",
"39.99.151.148",
"8.142.31.50",
"39.103.228.214",
"8.142.86.138",
"8.142.108.54",
"39.103.144.175",
"8.142.44.148",
"8.142.94.233",
"8.142.87.84",
"39.103.202.108",
"121.89.199.46",
"8.142.93.173",
"8.142.99.25",
"8.142.85.206",
"39.101.204.97",
"39.99.157.94",
"39.101.167.155",
"8.142.88.23",
"8.142.47.50",
"8.142.179.15",
"39.103.193.98",
"8.142.138.9",
"121.89.212.145",
"8.142.87.158",
"39.101.201.16",
"39.101.182.192",
"8.142.42.137",
"39.99.132.159",
"39.99.137.216",
"8.142.22.15",
"8.142.95.141",
"39.99.251.65",
"39.101.129.61",
"39.99.250.2",
"39.101.173.37",
"39.101.142.99",
"121.89.193.70",
"39.99.240.217",
"39.99.146.78",
"39.99.132.65",
"39.101.191.40",
"8.142.67.254",
"8.142.80.242",
"8.142.81.80",
"8.142.32.185",
"8.142.87.23",
"8.142.72.42",
"8.142.77.108",
"39.101.244.65",
"8.142.40.226",
"39.103.148.233",
"8.142.173.109",
"39.103.145.49",
"8.142.95.18",
"8.142.176.18",
"8.142.98.127",
"39.101.141.231",
"121.89.197.154",
"39.101.197.200",
"8.142.81.141",
"8.142.138.201",
"39.101.164.90",
"8.142.171.162",
"39.103.161.119",
"39.103.152.225",
"121.89.222.174",
"39.103.183.106",
"8.142.9.24",
"39.99.234.169",
"39.103.165.245",
"8.142.94.109",
"39.103.212.201",
"8.142.178.207",
"39.103.222.215",
"121.89.205.102",
"39.99.246.77",
"121.89.247.104",
"39.98.109.221",
"39.101.190.159",
"121.89.210.4",
"8.142.178.97",
"39.99.134.234",
"8.142.79.219",
"8.142.132.52",
"8.142.178.7",
"39.103.157.151",
"39.99.144.235",
"8.142.95.241",
"39.103.146.215",
"39.101.167.224",
"39.101.195.123",
"8.142.178.156",
"8.142.47.165",
"39.101.189.210",
"8.142.8.54",
"39.101.128.177",
"8.142.137.190",
"8.142.112.255",
"8.142.38.212",
"8.142.34.149",
"39.103.189.27",
"8.142.177.67",
"39.99.242.182",
"39.103.191.229",
"39.101.151.72",
"39.99.137.10",
"39.101.180.174",
"39.101.194.204",
"8.142.175.108",
"39.99.225.246",
"39.103.175.44",
"121.89.216.225",
"8.142.102.247",
"39.103.193.188",
"8.142.81.253",
"39.103.169.76",
"8.142.139.61",
"8.142.129.165",
"39.103.153.141",
"39.98.123.208",
"39.103.187.241",
"121.89.192.168",
"8.142.104.215",
"8.142.112.199",
"39.103.235.149",
"8.142.108.16",
"39.101.198.114",
"8.142.130.158",
"8.142.28.178",
"8.142.122.80",
"8.142.100.107",
"8.142.33.161",
"8.142.124.208",
"8.142.70.82",
"8.142.69.207",
"39.103.226.236",
"8.142.104.109",
"8.142.201.83",
"8.142.245.139",
"8.142.201.94",
"8.142.242.43",
"8.142.242.29",
"8.142.241.195",
"8.142.207.222",
"8.142.201.77",
"8.142.245.236",
"8.142.251.249",
"8.142.252.124",
"8.142.201.62",
"8.142.242.188",
"8.142.234.66",
"8.142.252.80"
阿里云的ip是不固定的,但是是有限的,下面我给大家总结了全部的ip,直接复制到需要固定ip的地方(比如公众号开发以及微信支付开发),就可以使用
"106.55.29.200",
"120.231.66.200",
"120.239.43.174",
"39.103.221.6",
"8.142.75.1",
"8.142.83.203",
"39.99.151.148",
"8.142.31.50",
"39.103.228.214",
"8.142.86.138",
"8.142.108.54",
"39.103.144.175",
"8.142.44.148",
"8.142.94.233",
"8.142.87.84",
"39.103.202.108",
"121.89.199.46",
"8.142.93.173",
"8.142.99.25",
"8.142.85.206",
"39.101.204.97",
"39.99.157.94",
"39.101.167.155",
"8.142.88.23",
"8.142.47.50",
"8.142.179.15",
"39.103.193.98",
"8.142.138.9",
"121.89.212.145",
"8.142.87.158",
"39.101.201.16",
"39.101.182.192",
"8.142.42.137",
"39.99.132.159",
"39.99.137.216",
"8.142.22.15",
"8.142.95.141",
"39.99.251.65",
"39.101.129.61",
"39.99.250.2",
"39.101.173.37",
"39.101.142.99",
"121.89.193.70",
"39.99.240.217",
"39.99.146.78",
"39.99.132.65",
"39.101.191.40",
"8.142.67.254",
"8.142.80.242",
"8.142.81.80",
"8.142.32.185",
"8.142.87.23",
"8.142.72.42",
"8.142.77.108",
"39.101.244.65",
"8.142.40.226",
"39.103.148.233",
"8.142.173.109",
"39.103.145.49",
"8.142.95.18",
"8.142.176.18",
"8.142.98.127",
"39.101.141.231",
"121.89.197.154",
"39.101.197.200",
"8.142.81.141",
"8.142.138.201",
"39.101.164.90",
"8.142.171.162",
"39.103.161.119",
"39.103.152.225",
"121.89.222.174",
"39.103.183.106",
"8.142.9.24",
"39.99.234.169",
"39.103.165.245",
"8.142.94.109",
"39.103.212.201",
"8.142.178.207",
"39.103.222.215",
"121.89.205.102",
"39.99.246.77",
"121.89.247.104",
"39.98.109.221",
"39.101.190.159",
"121.89.210.4",
"8.142.178.97",
"39.99.134.234",
"8.142.79.219",
"8.142.132.52",
"8.142.178.7",
"39.103.157.151",
"39.99.144.235",
"8.142.95.241",
"39.103.146.215",
"39.101.167.224",
"39.101.195.123",
"8.142.178.156",
"8.142.47.165",
"39.101.189.210",
"8.142.8.54",
"39.101.128.177",
"8.142.137.190",
"8.142.112.255",
"8.142.38.212",
"8.142.34.149",
"39.103.189.27",
"8.142.177.67",
"39.99.242.182",
"39.103.191.229",
"39.101.151.72",
"39.99.137.10",
"39.101.180.174",
"39.101.194.204",
"8.142.175.108",
"39.99.225.246",
"39.103.175.44",
"121.89.216.225",
"8.142.102.247",
"39.103.193.188",
"8.142.81.253",
"39.103.169.76",
"8.142.139.61",
"8.142.129.165",
"39.103.153.141",
"39.98.123.208",
"39.103.187.241",
"121.89.192.168",
"8.142.104.215",
"8.142.112.199",
"39.103.235.149",
"8.142.108.16",
"39.101.198.114",
"8.142.130.158",
"8.142.28.178",
"8.142.122.80",
"8.142.100.107",
"8.142.33.161",
"8.142.124.208",
"8.142.70.82",
"8.142.69.207",
"39.103.226.236",
"8.142.104.109",
"8.142.201.83",
"8.142.245.139",
"8.142.201.94",
"8.142.242.43",
"8.142.242.29",
"8.142.241.195",
"8.142.207.222",
"8.142.201.77",
"8.142.245.236",
"8.142.251.249",
"8.142.252.124",
"8.142.201.62",
"8.142.242.188",
"8.142.234.66",
"8.142.252.80"
收起阅读 »

关于数组去重和获取重复元素的数组
var arr=[1,2,3,4,3,5,4,6,7,2,1,4];
var newArr=[];
for (let i = 0; i < arr.length; i++) {
// let num=0;
for (let j = i+1; j < arr.length; j++) {
if(arr[i]==arr[j]){
// num++
arr.splice(j,1);//去重
}
}
if(num==1){//这里用num==1来做判断的好处,用倒数第二个元素作参考,打印出重复的元素。不会出现多次打印相同的重复元素,表现了打印出结果的唯一性。
newArr.push(arr[i]);
console.log("重复元素:"+arr[i])
}
num=0;
if(num>=1&&arr.indexOf(arr[i])==i){
console.log("重复元素:"+arr[i]+",重复次数:"+num)//打印出重复元素的次数
}
}
var arr=[1,2,3,4,3,5,4,6,7,2,1,4];
var newArr=[];
for (let i = 0; i < arr.length; i++) {
// let num=0;
for (let j = i+1; j < arr.length; j++) {
if(arr[i]==arr[j]){
// num++
arr.splice(j,1);//去重
}
}
if(num==1){//这里用num==1来做判断的好处,用倒数第二个元素作参考,打印出重复的元素。不会出现多次打印相同的重复元素,表现了打印出结果的唯一性。
newArr.push(arr[i]);
console.log("重复元素:"+arr[i])
}
num=0;
if(num>=1&&arr.indexOf(arr[i])==i){
console.log("重复元素:"+arr[i]+",重复次数:"+num)//打印出重复元素的次数
}
}

后台保活、不保证所有场景下有效(ios)
后台保活、不保证所有场景下有效(ios) :https://ext.dcloud.net.cn/plugin?id=9118
后台保活、不保证所有场景下有效(ios) :https://ext.dcloud.net.cn/plugin?id=9118

个推TechDay直播预告 | 8月24日晚19:30,实时数仓搭建保姆级教程开课
当下,企业的实时计算需求越来越高频,很多企业和组织选择建设实时数据仓库,以敏捷支撑实时报表分析、智能算法推荐、系统风险预警等多元业务场景需求。
相比离线数仓,实时数仓有哪些特性?如何进行实时数仓的技术选型?
个推TechDay“治数训练营”系列直播课第二期来了!
8月24日(下周三)晚上19:30-20:30,个推资深数据研发工程师为您解读实时数仓架构演进,分享实时数仓技术选型要点,并结合实战案例详细剖析实时数仓的搭建秘诀。
更有超多惊喜福利等你拿!
当下,企业的实时计算需求越来越高频,很多企业和组织选择建设实时数据仓库,以敏捷支撑实时报表分析、智能算法推荐、系统风险预警等多元业务场景需求。
相比离线数仓,实时数仓有哪些特性?如何进行实时数仓的技术选型?
个推TechDay“治数训练营”系列直播课第二期来了!
8月24日(下周三)晚上19:30-20:30,个推资深数据研发工程师为您解读实时数仓架构演进,分享实时数仓技术选型要点,并结合实战案例详细剖析实时数仓的搭建秘诀。
更有超多惊喜福利等你拿!
收起阅读 »
个推支持海外消息推送,助力APP扬帆出海
在全球化的浪潮之下,越来越多的国内开发者选择“乘风出海”。消息推送作为APP连接用户的有效途径,成为开发者进军海外市场的刚需。但由于海内外网络环境、应用生态等的差异,APP在海外推送的过程中,也面临着消息通道建设、海外用户精细运营、数据安全合规等方面的诸多挑战。
为此,个推推出海外消息推送解决方案,帮助APP高效整合海外消息通道,构建智能、精细、高效的用户触达体系,促进APP海外业务快速增长。
多链路触达体系,提升用户触达
用户触达通道,是APP与用户高效沟通的“桥梁”。但在APP构建海外消息通道的过程中,也存在着不少“隐痛”:一方面,自建通道或逐一对接各厂商海外通道,不仅费时费力且成本居高不下;另一方面,面对全球复杂的网络环境,若APP只采用FCM或APNs的系统通道,又会遇到消息送达率的瓶颈。
个推为APP构建了海外多链路触达体系,助其打破用户触达的壁垒。基于APP海外推送需求,个推不仅提供自有在线渠道,无缝对接FCM、APNs系统通道,还高效整合了小米、华为、荣耀、魅族、 OPPO等厂商推送能力。APP只需一次集成即可接入多厂商海外推送服务,实现在线、离线推送,保障消息稳定、高效送达。同时,个推还支持国际短信推送,帮助APP进一步拓宽海外用户触达渠道,全面提升消息到达率。
依托海外多链路触达体系, APP不仅可以自选消息下发通道触达海外用户,还能通过消息并发、分发、补发等方式,提高消息到达率。此外,个推还提供离线消息库、超长消息自动截短、厂商推送余量查询管理等能力,支持各阶段、各渠道推送数据后效分析,帮助APP科学管理渠道资源,以更低的成本实现用户触达效率的全面升级。
多样化推送策略,提升用户转化
消息点击率与运营转化效果密不可分。
基于海外推送场景,个推支持丰富的消息展示样式以及亮屏推送、A/B Test、消息分组、定时推送等消息运营工具,帮助APP精细化触达海外目标人群,提高消息点击转化率,提升用户活跃与留存。
保障数据合规,护航APP“扬帆出海
数据安全是全球关注的焦点,也是APP出海的“必修课”。
为全方位护航APP扬帆出海,个推构建了全球化的云服务集群,实现全球服务器多节点部署,保障海外推送的稳定性。此外,个推还提供分层权限管理、鉴权体系、日志监控、敏感内容审核过滤等多重保护机制,帮助APP降低运营风险,全方位保障数据安全、系统安全和内容安全。
深耕移动开发领域十余年,个推通过安全、稳定、可靠的产品及服务赢得了全球开发者的信赖。大航海时代,个推还将持续创新产品和技术服务,帮助更多开发者提升增长效率、开拓海外市场版图。
合作咨询
如果您对个推海外推送解决方案感兴趣,欢迎“码”上咨询,个推专属顾问,为您提供一对一服务!
在全球化的浪潮之下,越来越多的国内开发者选择“乘风出海”。消息推送作为APP连接用户的有效途径,成为开发者进军海外市场的刚需。但由于海内外网络环境、应用生态等的差异,APP在海外推送的过程中,也面临着消息通道建设、海外用户精细运营、数据安全合规等方面的诸多挑战。
为此,个推推出海外消息推送解决方案,帮助APP高效整合海外消息通道,构建智能、精细、高效的用户触达体系,促进APP海外业务快速增长。
多链路触达体系,提升用户触达
用户触达通道,是APP与用户高效沟通的“桥梁”。但在APP构建海外消息通道的过程中,也存在着不少“隐痛”:一方面,自建通道或逐一对接各厂商海外通道,不仅费时费力且成本居高不下;另一方面,面对全球复杂的网络环境,若APP只采用FCM或APNs的系统通道,又会遇到消息送达率的瓶颈。
个推为APP构建了海外多链路触达体系,助其打破用户触达的壁垒。基于APP海外推送需求,个推不仅提供自有在线渠道,无缝对接FCM、APNs系统通道,还高效整合了小米、华为、荣耀、魅族、 OPPO等厂商推送能力。APP只需一次集成即可接入多厂商海外推送服务,实现在线、离线推送,保障消息稳定、高效送达。同时,个推还支持国际短信推送,帮助APP进一步拓宽海外用户触达渠道,全面提升消息到达率。
依托海外多链路触达体系, APP不仅可以自选消息下发通道触达海外用户,还能通过消息并发、分发、补发等方式,提高消息到达率。此外,个推还提供离线消息库、超长消息自动截短、厂商推送余量查询管理等能力,支持各阶段、各渠道推送数据后效分析,帮助APP科学管理渠道资源,以更低的成本实现用户触达效率的全面升级。
多样化推送策略,提升用户转化
消息点击率与运营转化效果密不可分。
基于海外推送场景,个推支持丰富的消息展示样式以及亮屏推送、A/B Test、消息分组、定时推送等消息运营工具,帮助APP精细化触达海外目标人群,提高消息点击转化率,提升用户活跃与留存。
保障数据合规,护航APP“扬帆出海
数据安全是全球关注的焦点,也是APP出海的“必修课”。
为全方位护航APP扬帆出海,个推构建了全球化的云服务集群,实现全球服务器多节点部署,保障海外推送的稳定性。此外,个推还提供分层权限管理、鉴权体系、日志监控、敏感内容审核过滤等多重保护机制,帮助APP降低运营风险,全方位保障数据安全、系统安全和内容安全。
深耕移动开发领域十余年,个推通过安全、稳定、可靠的产品及服务赢得了全球开发者的信赖。大航海时代,个推还将持续创新产品和技术服务,帮助更多开发者提升增长效率、开拓海外市场版图。
合作咨询
如果您对个推海外推送解决方案感兴趣,欢迎“码”上咨询,个推专属顾问,为您提供一对一服务!
收起阅读 »