uniapp打包上架遇到要求SDK权限延后处理的问题
uniapp的坑也是不少,个人也是第一次开发安卓端的app,因此遇到的问题也是不少,特此记录一下。
此文章要记录的是关于应用宝上架遇到的问题(包括vivo平台),要求是权限请求必须在用户同意用户协议和隐私权限后才行。我当时是在首页里加入了一个弹窗,在第一次进入app时调用打开弹窗,就这样打包提交平台审核,然后回了一整页的隐私权限问题。
看到这个我人都要看傻了,这都啥啊?在百度了无数东西之后,终于发现了一个最重要的问题,权限请求必须在用户同意用户协议和隐私权限后!
可是我已点开app权限就开始请求啊,比如请求手机的通话状态、请求写入手机内部文件存储,然后才到我的首页去打开隐私协议弹窗,这压根没法子啊?于是去QQ官群问,技术群问,奈何没人回我(可能是我菜?)
就这个时候我点开了人家的app,清空数据后重新进入,诶?人家的都是弹窗先出来,然后再请求权限。
难道是我菜?于是怀着不平的心情,继续挖百度,终于是让我挖到了:
Android平台隐私与政策提示框配置方法
配置方式
打开项目的manifest.json文件,切换到“源码视图”项
uni-app项目
在 "app-plus" -> "privacy" 节点下添加 prompt节点
"privacy": {
"prompt": "template",
"template": {
"title": "服务协议和隐私政策",
"message": " 请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/> 你可阅读<a href=\"https:\//www.xxx.com\">《用户协议》</a>和<a href=\"https:\//www.xxx.com\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"buttonAccept": "同意",
"buttonRefuse": "暂不同意",
"second": {
"title": "温馨提示",
"message": " 进入应用前,你需先同意<a href=\"https:\//www.xxx.com\">《服务协议》</a>和<a href=\"https:\//www.xxx.com\">《隐私政策》</a>,否则将退出应用。",
"buttonAccept": "同意并继续",
"buttonRefuse": "退出应用",
}
}
}
这个就是在启动页就能出现的弹窗提示框,按配置进行即可(不看文档的坑!!!)
文档链接:
完成之后需要重新云端打包后才能生效
uniapp的坑也是不少,个人也是第一次开发安卓端的app,因此遇到的问题也是不少,特此记录一下。
此文章要记录的是关于应用宝上架遇到的问题(包括vivo平台),要求是权限请求必须在用户同意用户协议和隐私权限后才行。我当时是在首页里加入了一个弹窗,在第一次进入app时调用打开弹窗,就这样打包提交平台审核,然后回了一整页的隐私权限问题。
看到这个我人都要看傻了,这都啥啊?在百度了无数东西之后,终于发现了一个最重要的问题,权限请求必须在用户同意用户协议和隐私权限后!
可是我已点开app权限就开始请求啊,比如请求手机的通话状态、请求写入手机内部文件存储,然后才到我的首页去打开隐私协议弹窗,这压根没法子啊?于是去QQ官群问,技术群问,奈何没人回我(可能是我菜?)
就这个时候我点开了人家的app,清空数据后重新进入,诶?人家的都是弹窗先出来,然后再请求权限。
难道是我菜?于是怀着不平的心情,继续挖百度,终于是让我挖到了:
Android平台隐私与政策提示框配置方法
配置方式
打开项目的manifest.json文件,切换到“源码视图”项
uni-app项目
在 "app-plus" -> "privacy" 节点下添加 prompt节点
"privacy": {
"prompt": "template",
"template": {
"title": "服务协议和隐私政策",
"message": " 请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/> 你可阅读<a href=\"https:\//www.xxx.com\">《用户协议》</a>和<a href=\"https:\//www.xxx.com\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"buttonAccept": "同意",
"buttonRefuse": "暂不同意",
"second": {
"title": "温馨提示",
"message": " 进入应用前,你需先同意<a href=\"https:\//www.xxx.com\">《服务协议》</a>和<a href=\"https:\//www.xxx.com\">《隐私政策》</a>,否则将退出应用。",
"buttonAccept": "同意并继续",
"buttonRefuse": "退出应用",
}
}
}
这个就是在启动页就能出现的弹窗提示框,按配置进行即可(不看文档的坑!!!)
文档链接:
完成之后需要重新云端打包后才能生效
Uniapp发布为H5版本时如何隐藏访问路径的#符号
在使用Uniapp发布为H5端时,我们的页面访问路径都会带上一个“#”号,这个不仅影响美观,还会在某些场合被过滤到“#”号导致路由错误,比如我们在做H5端的微信公众号登录的时候,返回地址带有“#”号就会被自动过滤掉,导致无法回调到正确页面,解决办法如下:
一、使用Hbuilder 工具打开manifest.json 文件,定位到:H5配置->路由模式->选择 history 模式
二、服务器配置
打包好H5代码上传到服务器还需要做伪静态的配置。
history模式下配置nginx
location / {
try_files $uri $uri/ /index.html;
}
history模式下配置Apache
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
三、经过以上处理之后,我们原先的H5端的访问地址:https://h5.shopwind.net/#/pages/index/index 就会自动转化为:https://h5.shopwind.net/pages/index/index , 已经完美的去掉了“#”符合,并且我们在填写微信公众号登录的回调地址后,能正常跳回。
在使用Uniapp发布为H5端时,我们的页面访问路径都会带上一个“#”号,这个不仅影响美观,还会在某些场合被过滤到“#”号导致路由错误,比如我们在做H5端的微信公众号登录的时候,返回地址带有“#”号就会被自动过滤掉,导致无法回调到正确页面,解决办法如下:
一、使用Hbuilder 工具打开manifest.json 文件,定位到:H5配置->路由模式->选择 history 模式
二、服务器配置
打包好H5代码上传到服务器还需要做伪静态的配置。
history模式下配置nginx
location / {
try_files $uri $uri/ /index.html;
}
history模式下配置Apache
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
三、经过以上处理之后,我们原先的H5端的访问地址:https://h5.shopwind.net/#/pages/index/index 就会自动转化为:https://h5.shopwind.net/pages/index/index , 已经完美的去掉了“#”符合,并且我们在填写微信公众号登录的回调地址后,能正常跳回。
收起阅读 »旧版HBuilder X(3.2.1以前的版本)创建的uni-app开发快手小程序指南
最新版的HBuilderX(3.2.1+版本)创建的uni-app项目,已经支持直接在编辑器菜单:运行/发行快手小程序
====================================
我们强烈建议通过升级HBuilderX至3.2.1+版本,开发快手小程序。
如下介绍的开发方式,主要针对旧版编辑器不支持直接运行到快手小程序。
如果由于特殊原因,你仍然坚持使用旧版HBuilderX(3.2.1以前的版本),那样你只能通过cli方式创建uni-app项目才能运行到快手小程序。
步骤如下:
准备工作:
1.安装快手开发者工具,点此下载
2.cli创建uni-app。详情:通过vue-cli命令行
如果你的项目是由hbuilderx创建的,需要先转成cli项目。详情:uni-app HBuilderX 工程与 vue-cli 工程相互转换
运行快手小程序:
npm run dev:mp-kuaishou
3.打开快手开发者工具,点击导入。目录:cli创建的uni-app项目/dist/dev/mp-kuaishou
提醒:命令行创建uni-app,推荐使用alpha版(对应HBuilderX最新alpha版)。该版本的快手小程序更稳定。
如果你是早期创建的升级方式 点击:修改依赖为指定版本
最新版的HBuilderX(3.2.1+版本)创建的uni-app项目,已经支持直接在编辑器菜单:运行/发行快手小程序
====================================
我们强烈建议通过升级HBuilderX至3.2.1+版本,开发快手小程序。
如下介绍的开发方式,主要针对旧版编辑器不支持直接运行到快手小程序。
如果由于特殊原因,你仍然坚持使用旧版HBuilderX(3.2.1以前的版本),那样你只能通过cli方式创建uni-app项目才能运行到快手小程序。
步骤如下:
准备工作:
1.安装快手开发者工具,点此下载
2.cli创建uni-app。详情:通过vue-cli命令行
如果你的项目是由hbuilderx创建的,需要先转成cli项目。详情:uni-app HBuilderX 工程与 vue-cli 工程相互转换
运行快手小程序:
npm run dev:mp-kuaishou
3.打开快手开发者工具,点击导入。目录:cli创建的uni-app项目/dist/dev/mp-kuaishou
提醒:命令行创建uni-app,推荐使用alpha版(对应HBuilderX最新alpha版)。该版本的快手小程序更稳定。
如果你是早期创建的升级方式 点击:修改依赖为指定版本
uni.createInnerAudioContext() 报错{"errMsg":"MediaError","errCode":-5}解决方案
接了腾讯的tim 现在遇到了ios播放不了tim返回的音频链接报错{"errMsg":"MediaError","errCode":-5} 但是经过自己的摸索 发现video可以播放 所以写一系列骚操作
个人感觉是uniapp的uni.createInnerAudioContext()事件底层 ios原生这块的io报错 也求官方早日修复吧
不多说 直接上代码
<template>
<video
:id="payload.uuid"
:muted="isFirstLoad"//第一次获取音频时长静音播放
style="display: none;"
:src="payload.url"
@timeupdate="handleTimeUp"//第一次获取音频时长事件
/>
</template>
<script>
export default {
props: {
payload: {
type: Object,
required: true
}
},
methods:{
handleTimeUp(e) {
const { duration } = e.detail
if (this.isFirstLoad) {
this.videoContext.pause()
this.second = duration.toFixed(0)
this.isFirstLoad = false
}
},}
}
</script>
剩下的播放就不多说了 记录一下坑 日后给需要的兄弟
接了腾讯的tim 现在遇到了ios播放不了tim返回的音频链接报错{"errMsg":"MediaError","errCode":-5} 但是经过自己的摸索 发现video可以播放 所以写一系列骚操作
个人感觉是uniapp的uni.createInnerAudioContext()事件底层 ios原生这块的io报错 也求官方早日修复吧
不多说 直接上代码
<template>
<video
:id="payload.uuid"
:muted="isFirstLoad"//第一次获取音频时长静音播放
style="display: none;"
:src="payload.url"
@timeupdate="handleTimeUp"//第一次获取音频时长事件
/>
</template>
<script>
export default {
props: {
payload: {
type: Object,
required: true
}
},
methods:{
handleTimeUp(e) {
const { duration } = e.detail
if (this.isFirstLoad) {
this.videoContext.pause()
this.second = duration.toFixed(0)
this.isFirstLoad = false
}
},}
}
</script>
剩下的播放就不多说了 记录一下坑 日后给需要的兄弟
收起阅读 »郑州工作室接外包项目
app
小程序
pc官网
语言:
uni-app
原生安卓 ios
php
有意向联系微信ciyujuzi
app
小程序
pc官网
语言:
uni-app
原生安卓 ios
php
有意向联系微信ciyujuzi
subNVue的一些实验
最近在熟悉uni-app的api,准备在demo里使用遮罩层,找官方文档,一顿搜索点到了subNVue,于是跟着开发指南和文档用subNVue写一个遮罩试试(毕竟官方说这个很强大,可以盖住原生组件,还能实现内部滚动)。
根据我的测试结果,如果仅仅根据uni-app的文档,我不能写出一个令自己满意的遮罩层,比如说,你不能阻止手机上的虚拟返回键关闭遮罩,你不能自己控制是否通过点击遮罩关闭遮罩层。
根据文档中的一些线索:
- ‘Android平台4.0以上系统才支持“transparent”背景透明样式’。
-
除 popup 外,其他值域参考 5+ webview position 文档。
去查看H5+的webview文档(subNVue是对H5+webview的一层封装,但是封装的功能不全,要真正发挥subNVue的强大功能还是要结合plus对象)。
下面是我的测试代码():
在page.json里添加如下配置:{ "path": "pages/tabBar/home/home", "style": { "enablePullDownRefresh": false, "navigationStyle": "default", "navigationBarTitleText": "Home", "app-plus": { "titleNView": { // 标题栏样式 // "homeButton": true, "buttons": [ { "type": "back", "float": "left" }, ] }, "subNVues":[{ "id": "test", // 唯一标识 "path": "/paltform/app-plus/subNVue/overlay", // 页面路径 "type": "popup", "style": { // 应该对应的是H5+中的webviewStyle "position": "absolute", "dock": "right", "width": "100upx", "height": "150upx", // "background": "rgba(0,0,0,0.5)", "mask": "none",//mask的值很重要,设置成none点击遮罩不会再关闭遮罩了 "backButtonAutoControl": "none" // 如果值是quit点击虚拟返回键会直接退出app } }] } } }overlay.vue:
<template>
<view class="tt">
<image class="swiper-item home-banner-item" mode="widthFix" src="https://pic2.zhimg.com/v2-25f301124c7524029d043a038655c829_1440w.jpg?source=172ae18b"></image>
</view>
</template>
<script>
export default {
data() {
return {
}
},
onLoad: function () {
const subNVue = uni.getCurrentSubNVue(); // subNVue对应的webview 对象
console.log(plus.webview.currentWebview().id); // package.json里设置的subNVue的id
console.log(subNVue.id); // package.json里设置的subNVue的id
console.log(plus.webview.currentWebview().opener());//创建subNVue对应的webview 的父webview,与 home.vue的webview是同一个webview
subNVue.canBack(function(e){
console.log('是否可返回:'+e.canBack);
});
// subNVue.addEventListener('hide', function(){
// // subNVue.setStyle({mask:'rgba(0,0,0,1)'});
// console.log(123000);
// },false);
// console.log(subNVue.parent());
subNVue.setStyle({
background: '#ff4050',
})
plus.key.addEventListener('backbutton',function() {
console.log('backbutton'); // 这个可以拦截手机上的虚拟返回键
return true;
})
},
onUnload:function(){
},
onBackPress() {
return true; // 这个貌似不起作用
},
methods: {
}
}
</script>
<style>
</style>
只是初步测试,希望uni-app官方能把文档给写清楚,不要让开发者猜,提高大家的工作效率。
最近在熟悉uni-app的api,准备在demo里使用遮罩层,找官方文档,一顿搜索点到了subNVue,于是跟着开发指南和文档用subNVue写一个遮罩试试(毕竟官方说这个很强大,可以盖住原生组件,还能实现内部滚动)。
根据我的测试结果,如果仅仅根据uni-app的文档,我不能写出一个令自己满意的遮罩层,比如说,你不能阻止手机上的虚拟返回键关闭遮罩,你不能自己控制是否通过点击遮罩关闭遮罩层。
根据文档中的一些线索:
- ‘Android平台4.0以上系统才支持“transparent”背景透明样式’。
-
除 popup 外,其他值域参考 5+ webview position 文档。
去查看H5+的webview文档(subNVue是对H5+webview的一层封装,但是封装的功能不全,要真正发挥subNVue的强大功能还是要结合plus对象)。
下面是我的测试代码():
在page.json里添加如下配置:{ "path": "pages/tabBar/home/home", "style": { "enablePullDownRefresh": false, "navigationStyle": "default", "navigationBarTitleText": "Home", "app-plus": { "titleNView": { // 标题栏样式 // "homeButton": true, "buttons": [ { "type": "back", "float": "left" }, ] }, "subNVues":[{ "id": "test", // 唯一标识 "path": "/paltform/app-plus/subNVue/overlay", // 页面路径 "type": "popup", "style": { // 应该对应的是H5+中的webviewStyle "position": "absolute", "dock": "right", "width": "100upx", "height": "150upx", // "background": "rgba(0,0,0,0.5)", "mask": "none",//mask的值很重要,设置成none点击遮罩不会再关闭遮罩了 "backButtonAutoControl": "none" // 如果值是quit点击虚拟返回键会直接退出app } }] } } }overlay.vue:
<template>
<view class="tt">
<image class="swiper-item home-banner-item" mode="widthFix" src="https://pic2.zhimg.com/v2-25f301124c7524029d043a038655c829_1440w.jpg?source=172ae18b"></image>
</view>
</template>
<script>
export default {
data() {
return {
}
},
onLoad: function () {
const subNVue = uni.getCurrentSubNVue(); // subNVue对应的webview 对象
console.log(plus.webview.currentWebview().id); // package.json里设置的subNVue的id
console.log(subNVue.id); // package.json里设置的subNVue的id
console.log(plus.webview.currentWebview().opener());//创建subNVue对应的webview 的父webview,与 home.vue的webview是同一个webview
subNVue.canBack(function(e){
console.log('是否可返回:'+e.canBack);
});
// subNVue.addEventListener('hide', function(){
// // subNVue.setStyle({mask:'rgba(0,0,0,1)'});
// console.log(123000);
// },false);
// console.log(subNVue.parent());
subNVue.setStyle({
background: '#ff4050',
})
plus.key.addEventListener('backbutton',function() {
console.log('backbutton'); // 这个可以拦截手机上的虚拟返回键
return true;
})
},
onUnload:function(){
},
onBackPress() {
return true; // 这个貌似不起作用
},
methods: {
}
}
</script>
<style>
</style>
只是初步测试,希望uni-app官方能把文档给写清楚,不要让开发者猜,提高大家的工作效率。
收起阅读 »打包APP 页面出现白屏最新解决方案
首先还是应该将tabbar页面用nvue编写,就不会出现这种问题了。
但是我的使用了过多组件,相当于要重构了。。。就放弃改为nvue了。下面是我根据之前版本的方法修改的,大概能解决大部分问题?
先贴原来用的方法,这个是在社区找到的,新版不能使用原因请看注释
function reloadCurrentPage(_self, isTab = true) {
// #ifdef APP-PLUS
if (plus.os.name === 'iOS') {
var route = _self.$scope.route
var data = _self.$scope.options && _self.$scope.options.data
var url = '/' + route
if (data) {
url = '/' + route + '?data=' + data
}
var isRecovery = true;
const query = uni.createSelectorQuery().in(_self);
//新版本这里在获取节点失败后不再调用boundingClientRect方法了
query.select('#containerId').boundingClientRect(data => {
isRecovery = false
}).exec();
setTimeout(() => {
if (isRecovery) {
if (isTab) {
uni.reLaunch({
url
})
} else {
uni.redirectTo({
url
})
}
}
}, 600)
}
// #endif
}
然后我根据这个改了一版,在使用前需要以下条件
1、需要一个全局挂载的工具类,Vue.prototype.$utils = utils
2、在需要使用的页面(一般为tab页)最外层<view>需要设置为同一个class名称
3、在onshow方法调用
目前好像就tab页出现白屏比较严重,只需要在tabbar页使用应该就够了
let pageList = {};
const utils = {
reloadCurrentPage: function(_self, isTab = true) {
// #ifdef APP-PLUS
var route = _self.$scope.route
var data = _self.$scope.options && _self.$scope.options.data
var url = '/' + route
if (data) {
url = '/' + route + '?data=' + data
}
var isRecovery = true;
let newTime = Date.now();
if (pageList[url]) {
const query = uni.createSelectorQuery().in(_self);
//这里select()中替换为自己的样式class名称
query.select('.container').fields({size:true}, data => {
isRecovery = false
}).exec();
setTimeout(() => {
if (isRecovery) {
//如果获取不到节点
//确保只刷新一次
if (newTime - pageList[url] > 3000) {
//超过3秒才重新刷新,这里设置几秒就行,目的是防止无限刷新
//因为刷新后页面肯定会出来,但是立马再次调用该方法不一定能获取节点
pageList[url] = newTime;
if (isTab) {
uni.reLaunch({
url
})
} else {
uni.redirectTo({
url
})
}
}
}
}, 600)
} else {
pageList[url] = newTime;
}
// if (plus.os.name === 'iOS') {
// }
// #endif
}
} 首先还是应该将tabbar页面用nvue编写,就不会出现这种问题了。
但是我的使用了过多组件,相当于要重构了。。。就放弃改为nvue了。下面是我根据之前版本的方法修改的,大概能解决大部分问题?
先贴原来用的方法,这个是在社区找到的,新版不能使用原因请看注释
function reloadCurrentPage(_self, isTab = true) {
// #ifdef APP-PLUS
if (plus.os.name === 'iOS') {
var route = _self.$scope.route
var data = _self.$scope.options && _self.$scope.options.data
var url = '/' + route
if (data) {
url = '/' + route + '?data=' + data
}
var isRecovery = true;
const query = uni.createSelectorQuery().in(_self);
//新版本这里在获取节点失败后不再调用boundingClientRect方法了
query.select('#containerId').boundingClientRect(data => {
isRecovery = false
}).exec();
setTimeout(() => {
if (isRecovery) {
if (isTab) {
uni.reLaunch({
url
})
} else {
uni.redirectTo({
url
})
}
}
}, 600)
}
// #endif
}
然后我根据这个改了一版,在使用前需要以下条件
1、需要一个全局挂载的工具类,Vue.prototype.$utils = utils
2、在需要使用的页面(一般为tab页)最外层<view>需要设置为同一个class名称
3、在onshow方法调用
目前好像就tab页出现白屏比较严重,只需要在tabbar页使用应该就够了
let pageList = {};
const utils = {
reloadCurrentPage: function(_self, isTab = true) {
// #ifdef APP-PLUS
var route = _self.$scope.route
var data = _self.$scope.options && _self.$scope.options.data
var url = '/' + route
if (data) {
url = '/' + route + '?data=' + data
}
var isRecovery = true;
let newTime = Date.now();
if (pageList[url]) {
const query = uni.createSelectorQuery().in(_self);
//这里select()中替换为自己的样式class名称
query.select('.container').fields({size:true}, data => {
isRecovery = false
}).exec();
setTimeout(() => {
if (isRecovery) {
//如果获取不到节点
//确保只刷新一次
if (newTime - pageList[url] > 3000) {
//超过3秒才重新刷新,这里设置几秒就行,目的是防止无限刷新
//因为刷新后页面肯定会出来,但是立马再次调用该方法不一定能获取节点
pageList[url] = newTime;
if (isTab) {
uni.reLaunch({
url
})
} else {
uni.redirectTo({
url
})
}
}
}
}, 600)
} else {
pageList[url] = newTime;
}
// if (plus.os.name === 'iOS') {
// }
// #endif
}
} 收起阅读 »




