说下自己开发插件的一些经历吧
本人纯android开发者 接触过其他混合开发的插件开发 (注:并不是开发混合app只开发插件)
刚刚接触就发现了好多插件开发文档,一时间无头脑不知从何入手,旧的文档新的文档也不知道用哪个好一些,各种模式的开发弄得眼花缭乱,首次接触给我的感觉就是,乱,5+SDK 等等模式也不知道是干嘛的 具体简介也不知道在哪。
顺着文档和demo简单弄了下 ,
①遇到了第一个问题,无法调用sdk中的界面,期间找了很多帖子,也发了贴子也加了群,都是无果 ,帖子没人回答,回答也是敷衍了事,群里也是,期间也是很多其他方式的插件开发文档看的头晕目眩,真心不知道用那种,此处包括问帖子之类耗时从年前到年后只算工作时间 大概2个多月。
原因:文档用的依赖关键字过于老旧,目前android studio 早就放弃了这种方式 ,修改了之后可以了
②遇到第二个问题,无法找到assets下的文件,接着因为sdk中我们的模块需要用到授权,也就是assets中读取我们的资源文件,这里也是问了帖子,回复是官方摒弃了这种5+SDK的插件开发模式,那如果摒弃为何还能在官方找到这类文档误导开发者,并且没有任何官方摒弃和放弃维护与技术支持的声明?自此我前面的工作全部作废,因为官方不推荐后面也可能出现很多问题,历时也是2个月。
以上用了几个月的时间,完成了一个官方不维护不支持的一个插件开发的半成品都不算。
复工之后也就是3月份,由于客户用了年后最新的官方文档也就是另一种插件开发模式,是可以调通了,期间也是采坑无数,于是借鉴客户的demo进行了最新的尝试。
①第一个问题,根据最新的文档,开发者自己创建的项目,无法运行,无数尝试都无果,最后,使用官方提供的demo进行修改才可以正常运行。
②第二个问题,项目可以运行了,依旧是assets下的文件读取不到,具体原因不知,因为自己莫名其妙可以了又。
③第三个问题,插件在android studio下可以通过了,打包成arr插件文件,用Hbulid进行插件集成和测试,调用arr插件的时候直接找不到,插件里的桥接类,最后莫名自己又可以了
④第四个问题,在android下的assets中放的授权文件,再次无法读取。
以上用时,2周多的时间,目前还停留在第四个问题,
那我就请问,何来的开发时间段(针对插件开发而言),之前发的吐槽帖子有人说开发时间短等各种圆场官方,首先那是你作为web开发者,开发app,而我们是原生开发者开发插件,本质就不一样,这个东西出来新的想法和模式其实都不错但是,就插件开发这块对我们开发者很不友好,这样我们如何给好评。
本人纯android开发者 接触过其他混合开发的插件开发 (注:并不是开发混合app只开发插件)
刚刚接触就发现了好多插件开发文档,一时间无头脑不知从何入手,旧的文档新的文档也不知道用哪个好一些,各种模式的开发弄得眼花缭乱,首次接触给我的感觉就是,乱,5+SDK 等等模式也不知道是干嘛的 具体简介也不知道在哪。
顺着文档和demo简单弄了下 ,
①遇到了第一个问题,无法调用sdk中的界面,期间找了很多帖子,也发了贴子也加了群,都是无果 ,帖子没人回答,回答也是敷衍了事,群里也是,期间也是很多其他方式的插件开发文档看的头晕目眩,真心不知道用那种,此处包括问帖子之类耗时从年前到年后只算工作时间 大概2个多月。
原因:文档用的依赖关键字过于老旧,目前android studio 早就放弃了这种方式 ,修改了之后可以了
②遇到第二个问题,无法找到assets下的文件,接着因为sdk中我们的模块需要用到授权,也就是assets中读取我们的资源文件,这里也是问了帖子,回复是官方摒弃了这种5+SDK的插件开发模式,那如果摒弃为何还能在官方找到这类文档误导开发者,并且没有任何官方摒弃和放弃维护与技术支持的声明?自此我前面的工作全部作废,因为官方不推荐后面也可能出现很多问题,历时也是2个月。
以上用了几个月的时间,完成了一个官方不维护不支持的一个插件开发的半成品都不算。
复工之后也就是3月份,由于客户用了年后最新的官方文档也就是另一种插件开发模式,是可以调通了,期间也是采坑无数,于是借鉴客户的demo进行了最新的尝试。
①第一个问题,根据最新的文档,开发者自己创建的项目,无法运行,无数尝试都无果,最后,使用官方提供的demo进行修改才可以正常运行。
②第二个问题,项目可以运行了,依旧是assets下的文件读取不到,具体原因不知,因为自己莫名其妙可以了又。
③第三个问题,插件在android studio下可以通过了,打包成arr插件文件,用Hbulid进行插件集成和测试,调用arr插件的时候直接找不到,插件里的桥接类,最后莫名自己又可以了
④第四个问题,在android下的assets中放的授权文件,再次无法读取。
以上用时,2周多的时间,目前还停留在第四个问题,
那我就请问,何来的开发时间段(针对插件开发而言),之前发的吐槽帖子有人说开发时间短等各种圆场官方,首先那是你作为web开发者,开发app,而我们是原生开发者开发插件,本质就不一样,这个东西出来新的想法和模式其实都不错但是,就插件开发这块对我们开发者很不友好,这样我们如何给好评。
uniapp h5 位置选择,微信定位+腾讯位置服务获取当前地址,逆地址解析
uniapp h5 位置选择,微信定位+腾讯位置服务获取当前地址,逆地址解析
https://wanghuohuo.blog.csdn.net/article/details/105137028
一、获取当前地理坐标
首先引入JSSDK
npm install jweixin-module --save
使用
var jweixin = require('jweixin-module')
jweixin.ready(function(){
// TODO
});
DCloud官网的论坛,有分享的例子http://ask.dcloud.net.cn/article/36007。
我这里做个定位接口例子。
首先要看微信的文档。清楚大致的流程。https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
1、common目录,创建文件,名称是wechat.js。内容如下:
注意要点:
1、前端域名要放在微信公众平台js安全域名下。
2、 url:(window.location.href).split('#')[0] 当前页面url作为参数 进行数字签名。
// import request from './request';
var jweixin = require('jweixin-module');
import store from '@/store'
import api from '@/common/vmeitime-http/' //自己封装的网络请求类,也可以直接使用uni.request
export default {
//判断是否在微信中
isWechat: function() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/micromessenger/i) == 'micromessenger') {
// console.log('是微信客户端')
return true;
} else {
// console.log('不是微信客户端')
return false;
}
},
//初始化sdk配置
initJssdkShare: function(callback, url) {
//服务端进行签名 ,可使用uni.request替换。 签名算法请看文档
post(
'https://fbyc.microchainsoft.cn/index/wechat/getSignPackage',
{
url: url
},
function(res) {
// console.log(res)
if (res.data) {
jweixin.config({
debug: true,
appId: res.data.appId,
timestamp: res.data.timestamp,
nonceStr: res.data.nonceStr,
signature: res.data.signature,
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'getLocation'
]
});
//配置完成后,再执行分享等功能
if (callback) {
callback(res.data);
}
}
});
},
initJssdk:function(callback){
api.getAddressCoordinate({
appId:uni.getStorageSync('hmAppId'),
url:(window.location.href).split('#')[0]
}).then((res)=>{
if(res.data){
console.log(".data===="+JSON.stringify(res.data))
console.log(".data.data===="+JSON.stringify(res.data.data))
jweixin.config({
debug: false,
appId: res.data.data.appId,
timestamp: res.data.data.timestamp,
nonceStr: res.data.data.nonceStr,
signature: res.data.data.signature,
jsApiList: [
'checkJsApi',
'getLocation'
]
});
//配置完成后,再执行分享等功能
if (callback) {
callback(res.data);
}
}
}).catch((err) => {
console.log("微信signature失败"+err)
})
},
//在需要自定义分享的页面中调用
share: function(data, url) {
url = url ? url : window.location.href;
if (!this.isWechat()) {
return;
}
//每次都需要重新初始化配置,才可以进行分享
this.initJssdkShare(function(signData) {
jweixin.ready(function() {
var shareData = {
title: data && data.title ? data.title : signData.site_name,
desc: data && data.desc ? data.desc : signData.site_description,
link: url,
imgUrl: data && data.img ? data.img : signData.site_logo,
success: function(res) {
//用户点击分享后的回调,这里可以进行统计,例如分享送金币之类的
// post('/api/member/share');
},
cancel: function(res) {}
};
//分享给朋友接口
jweixin.onMenuShareAppMessage(shareData);
//分享到朋友圈接口
jweixin.onMenuShareTimeline(shareData);
});
}, url);
},
//在需要定位页面调用
location: function(callback) {
if (!this.isWechat()) {
console.log('不是微信客户端')
return;
}
console.info('定位')
this.initJssdk(function(res) {
jweixin.ready(function() {
console.info('定位ready')
jweixin.getLocation({
type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
// console.log(res);
callback(res)
},
fail:function(res){
console.log(res)
},
// complete:function(res){
// console.log(res)
// }
});
});
});
}
}
2、main.js加载该文件
// #ifdef H5
import wechat from './common/util/wechat'
if(wechat.isWechat()){
Vue.prototype.$wechat =wechat;
}
// #endif
3、页面中使用
// #ifdef H5
//获取定位经纬度
if (this.$wechat && this.$wechat.isWechat()) {
this.$wechat.location(function (res) {
console.log(res)
// let latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
// let longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
// todo
let latitude = 31.14979;
let longitude = 121.12426;
//根据经纬度,解析区域,提示用户输入
});
}
// #endif
二、逆地址解析
1、腾讯位置服务申请 服务调用前提 KEY
2、引入vue-jsonp 解决腾讯位置服务跨域请求问题
npm install vue-jsonp --save
使用
import VueJsonp from 'vue-jsonp'
Vue.use(VueJsonp)
调用
this.$jsonp(url,{
key: this.publicKey,
location: locationObj
}).then(e => {
res(e.result);
})
.catch(err => {
res(err);
})
3、引入mimap组件 https://ext.dcloud.net.cn/plugin?id=1448
qqmap-wx-jssdk.min.js 可从微信下载
- <template>
- <view class="server-place">
- <map
- id='map'
- ref='map'
- v-bind:style="{height: mapH + 'px'}"
- style="width: 100%;"
- latitude="latitude"
- longitude="longitude"
controls='controls' @regionchange='mapChange'>
</map><view class="map-tools"> <view class="my-location" @click.stop="toMyLocation"> <image class="left" src="/static/img/areame.png" mode=""></image> <view class="right"> <text class="title">我的位置</text> <text class="text">{{myAddress}}</text> </view> </view> <view class="start-place"> <view class="place"> <text class="title">{{tipText}}</text> <text class="text">{{addressObj.address.formatted_addresses.recommend}}</text> </view> <view class="tip">{{descText}}</view> <button @click.stop="submitAdress" class="sure" type="primary">确认选择</button> </view> </view></view>
</template>
<script>
var jweixin = require('jweixin-module');
const app = getApp()
var QQMapWX = require('./qqmap-wx-jssdk.min.js')
var qqmapsdk = new QQMapWX({
key: 'LXCBZ-NNIKD-UZ64F-H6AFI-UNJLH-OCFGE' //app的key
})
// 'YVEBZ-JS7LF-PK2JW-JJNFX-BITHO-ATB57'
export default {
props: {
tipText: {
type: String,
default: '选择位置'
},
descText: {
type: String,
default: '使用当前定位或在地图上标记位置'
},
},
data() {
return {
publicKey:'',// h5的key
mapH: 0, // 地图高度,可在initMapH()中设置高度
longitude: 0, // 初始经度
latitude: 0, // 初始纬度
myAddress: '', // 初始地址信息
addressObj: { // 地图选点信息
longitude: '',
latitude: '',
address: {
address:'',
formatted_addresses:{
recommend:'请选择位置'
}
}
},
controls: [ // 地图中心点图标, 可更换iconPath, 详情见官方文档关于map组件的介绍
{
iconPath: '/static/img/areacenter.png',
position: {
// left: 175,
left: window.screen.width/2-20,
top: 210,
width: 40,
height: 40,
},
clickable: false
}
],
};
},
mounted() {
let _this = this
_this.$api.getAddressKey({
appId: uni.getStorageSync('hmAppId'),
}).then(res=>{
if(res.data.code == 10000){
_this.publicKey=res.data.data.key;
this.getLocation()
this.initMapH()
}
}).catch(res=>{
console.error("查询key失败: " + JSON.stringify(res));
})
},
methods:{
// 查询现在的位置
getLocation() {
let this_ = this
if (this.$wechat && this.$wechat.isWechat()) {
this.$wechat.location(function (res) {
console.log(res)
let latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
let longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
let res2={
latitude: latitude ,
longitude: longitude
}
this_.initMap(res2)
//根据经纬度,解析区域,提示用户输入
});
}else{
console.error("不在微信环境中")
}
},
// 初始化我的位置
async initMap(res) {
this.longitude = res.longitude;
this.latitude = res.latitude;
this.addressObj = Object.assign({}, this.addressObj,{
longitude: res.longitude,
latitude: res.latitude,
address: await this.getAddressName(res)
})
this.myAddress = this.addressObj.address.formatted_addresses.recommend
},
// 地图选择位置后 查询地点名称
async checkMap(res) {
this.addressObj = Object.assign({}, this.addressObj,{
longitude: res.longitude,
latitude: res.latitude,
address: await this.getAddressName(res)
})
console.log('当前位置:' + res.latitude + '|' + res.longitude);
},
// 监听地图位置变化
mapChange(e) {
let that = this
clearTimeout(this.timer)
this.timer = setTimeout(() => {
if (e.type == 'end') {
that.mapCtx = uni.createMapContext('map', this)
that.mapCtx.getCenterLocation({
success: res => {
this.checkMap(res)
},
fail: err => {
console.log(err);
}
})
}
}, 200)
},
// 查询地图中心点的名称
getAddressName(addressObj) {
return new Promise((res) => {
// #ifdef APP-PLUS
qqmapsdk.reverseGeocoder({
location: {
latitude: addressObj.latitude,
longitude: addressObj.longitude
},
get_poi: 1,
poi_options: "page_size=1;page_index=1",
output: 'jsonp',
success: (e) => {
res(e.result.formatted_addresses.recommend);
},
fail: err => {
res(err);
}
})
// #endif
// #ifndef APP-PLUS
// ======================== jsonp跨域 ========================
let locationObj = addressObj.latitude+','+addressObj.longitude
let url = 'https://apis.map.qq.com/ws/geocoder/v1?coord_type=5&get_poi=1&output=jsonp&poi_options=page_size=1;page_index=1';
this.$jsonp(url,{
key: this.publicKey,
location: locationObj
}).then(e => {
res(e.result);
})
.catch(err => {
res(err);
})
// #endif
})
},
// 计算地图的高度
initMapH() {
// #ifdef APP-PLUS
this.mapH = uni.getSystemInfoSync().windowHeight - 210;
// #endif
// #ifndef APP-PLUS
this.mapH = uni.getSystemInfoSync().windowHeight - 170;
// #endif
},
// 移动到我的位置
toMyLocation() {
this.getLocation()
},
// 提交
submitAdress() {
this.controls = []
setTimeout(() => {
this.$emit('selectAddress', this.addressObj)
}, 100)
}
},
}
</script>
<style lang="scss" scoped>
.server-place{
position: fixed;
left: 0;
top: 0;
height: 100vh;
width: 100%;
background: #ffffff;
z-index: 999;
.icon-img{
width: 36px;
height: 36px;
display: block;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin-top: -70px;
}
.map-tools{
position: fixed;
width: 100%;
bottom: 0rem;
left: 0;
padding-bottom: .5rem;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.my-location{
width: 90%;
margin: 0 auto;
height: 2.5rem;
box-shadow: 0px 3px 20px rgba(0, 0, 0, 0.2);
background: #fff;
border-radius: 0.5rem;
display: flex;
justify-content: flex-start;
align-items: center;
overflow: hidden;
.left{
background: #3384ff;
// flex: 20%;
width: 2.5rem;
height: 100%;
}
.right{
font-size: 0.57rem;
margin-left: .5rem;
color: #111;
// flex: 80%;
display: flex;
justify-content: center;
align-items: flex-start;
flex-direction: column;
.text{
width: 12rem;
overflow: hidden;
white-space:nowrap;
text-overflow: ellipsis;
color: #3384FF;
margin-top: .3rem;
}
}
}
.start-place{
width: 85%;
margin: 0 auto;
height: 5.5rem;
margin: 0 auto;
margin-top: .6rem;
box-shadow: 0px 3px 20px rgba(0, 0, 0, 0.2);
background: #fff;
border-radius: 0.5rem;
padding: .5rem;
.place{
.title{
font-size: 0.67rem;
font-weight: bold;
color: #111;
}
.text{
font-size: 0.76rem;
color: #3384FF;
font-weight: bold;
width: 12rem;
vertical-align: middle;
display: inline-block;
margin-left: .5rem;
overflow: hidden;
white-space:nowrap;
text-overflow: ellipsis;
}
}
.tip{
font-size: 0.57rem;
color: #666;
margin-top: .5rem;
}
.sure{
margin-top: .5rem;
color: #FFFFFF;
background: #212121;
font-weight: 600;
}
}
}
}
</style>
4、相关图标
https://share.weiyun.com/5aMXvh8
uniapp h5 位置选择,微信定位+腾讯位置服务获取当前地址,逆地址解析
https://wanghuohuo.blog.csdn.net/article/details/105137028
一、获取当前地理坐标
首先引入JSSDK
npm install jweixin-module --save
使用
var jweixin = require('jweixin-module')
jweixin.ready(function(){
// TODO
});
DCloud官网的论坛,有分享的例子http://ask.dcloud.net.cn/article/36007。
我这里做个定位接口例子。
首先要看微信的文档。清楚大致的流程。https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
1、common目录,创建文件,名称是wechat.js。内容如下:
注意要点:
1、前端域名要放在微信公众平台js安全域名下。
2、 url:(window.location.href).split('#')[0] 当前页面url作为参数 进行数字签名。
// import request from './request';
var jweixin = require('jweixin-module');
import store from '@/store'
import api from '@/common/vmeitime-http/' //自己封装的网络请求类,也可以直接使用uni.request
export default {
//判断是否在微信中
isWechat: function() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/micromessenger/i) == 'micromessenger') {
// console.log('是微信客户端')
return true;
} else {
// console.log('不是微信客户端')
return false;
}
},
//初始化sdk配置
initJssdkShare: function(callback, url) {
//服务端进行签名 ,可使用uni.request替换。 签名算法请看文档
post(
'https://fbyc.microchainsoft.cn/index/wechat/getSignPackage',
{
url: url
},
function(res) {
// console.log(res)
if (res.data) {
jweixin.config({
debug: true,
appId: res.data.appId,
timestamp: res.data.timestamp,
nonceStr: res.data.nonceStr,
signature: res.data.signature,
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'getLocation'
]
});
//配置完成后,再执行分享等功能
if (callback) {
callback(res.data);
}
}
});
},
initJssdk:function(callback){
api.getAddressCoordinate({
appId:uni.getStorageSync('hmAppId'),
url:(window.location.href).split('#')[0]
}).then((res)=>{
if(res.data){
console.log(".data===="+JSON.stringify(res.data))
console.log(".data.data===="+JSON.stringify(res.data.data))
jweixin.config({
debug: false,
appId: res.data.data.appId,
timestamp: res.data.data.timestamp,
nonceStr: res.data.data.nonceStr,
signature: res.data.data.signature,
jsApiList: [
'checkJsApi',
'getLocation'
]
});
//配置完成后,再执行分享等功能
if (callback) {
callback(res.data);
}
}
}).catch((err) => {
console.log("微信signature失败"+err)
})
},
//在需要自定义分享的页面中调用
share: function(data, url) {
url = url ? url : window.location.href;
if (!this.isWechat()) {
return;
}
//每次都需要重新初始化配置,才可以进行分享
this.initJssdkShare(function(signData) {
jweixin.ready(function() {
var shareData = {
title: data && data.title ? data.title : signData.site_name,
desc: data && data.desc ? data.desc : signData.site_description,
link: url,
imgUrl: data && data.img ? data.img : signData.site_logo,
success: function(res) {
//用户点击分享后的回调,这里可以进行统计,例如分享送金币之类的
// post('/api/member/share');
},
cancel: function(res) {}
};
//分享给朋友接口
jweixin.onMenuShareAppMessage(shareData);
//分享到朋友圈接口
jweixin.onMenuShareTimeline(shareData);
});
}, url);
},
//在需要定位页面调用
location: function(callback) {
if (!this.isWechat()) {
console.log('不是微信客户端')
return;
}
console.info('定位')
this.initJssdk(function(res) {
jweixin.ready(function() {
console.info('定位ready')
jweixin.getLocation({
type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
// console.log(res);
callback(res)
},
fail:function(res){
console.log(res)
},
// complete:function(res){
// console.log(res)
// }
});
});
});
}
}
2、main.js加载该文件
// #ifdef H5
import wechat from './common/util/wechat'
if(wechat.isWechat()){
Vue.prototype.$wechat =wechat;
}
// #endif
3、页面中使用
// #ifdef H5
//获取定位经纬度
if (this.$wechat && this.$wechat.isWechat()) {
this.$wechat.location(function (res) {
console.log(res)
// let latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
// let longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
// todo
let latitude = 31.14979;
let longitude = 121.12426;
//根据经纬度,解析区域,提示用户输入
});
}
// #endif
二、逆地址解析
1、腾讯位置服务申请 服务调用前提 KEY
2、引入vue-jsonp 解决腾讯位置服务跨域请求问题
npm install vue-jsonp --save
使用
import VueJsonp from 'vue-jsonp'
Vue.use(VueJsonp)
调用
this.$jsonp(url,{
key: this.publicKey,
location: locationObj
}).then(e => {
res(e.result);
})
.catch(err => {
res(err);
})
3、引入mimap组件 https://ext.dcloud.net.cn/plugin?id=1448
qqmap-wx-jssdk.min.js 可从微信下载
- <template>
- <view class="server-place">
- <map
- id='map'
- ref='map'
- v-bind:style="{height: mapH + 'px'}"
- style="width: 100%;"
- latitude="latitude"
- longitude="longitude"
controls='controls' @regionchange='mapChange'>
</map><view class="map-tools"> <view class="my-location" @click.stop="toMyLocation"> <image class="left" src="/static/img/areame.png" mode=""></image> <view class="right"> <text class="title">我的位置</text> <text class="text">{{myAddress}}</text> </view> </view> <view class="start-place"> <view class="place"> <text class="title">{{tipText}}</text> <text class="text">{{addressObj.address.formatted_addresses.recommend}}</text> </view> <view class="tip">{{descText}}</view> <button @click.stop="submitAdress" class="sure" type="primary">确认选择</button> </view> </view></view>
</template>
<script>
var jweixin = require('jweixin-module');
const app = getApp()
var QQMapWX = require('./qqmap-wx-jssdk.min.js')
var qqmapsdk = new QQMapWX({
key: 'LXCBZ-NNIKD-UZ64F-H6AFI-UNJLH-OCFGE' //app的key
})
// 'YVEBZ-JS7LF-PK2JW-JJNFX-BITHO-ATB57'
export default {
props: {
tipText: {
type: String,
default: '选择位置'
},
descText: {
type: String,
default: '使用当前定位或在地图上标记位置'
},
},
data() {
return {
publicKey:'',// h5的key
mapH: 0, // 地图高度,可在initMapH()中设置高度
longitude: 0, // 初始经度
latitude: 0, // 初始纬度
myAddress: '', // 初始地址信息
addressObj: { // 地图选点信息
longitude: '',
latitude: '',
address: {
address:'',
formatted_addresses:{
recommend:'请选择位置'
}
}
},
controls: [ // 地图中心点图标, 可更换iconPath, 详情见官方文档关于map组件的介绍
{
iconPath: '/static/img/areacenter.png',
position: {
// left: 175,
left: window.screen.width/2-20,
top: 210,
width: 40,
height: 40,
},
clickable: false
}
],
};
},
mounted() {
let _this = this
_this.$api.getAddressKey({
appId: uni.getStorageSync('hmAppId'),
}).then(res=>{
if(res.data.code == 10000){
_this.publicKey=res.data.data.key;
this.getLocation()
this.initMapH()
}
}).catch(res=>{
console.error("查询key失败: " + JSON.stringify(res));
})
},
methods:{
// 查询现在的位置
getLocation() {
let this_ = this
if (this.$wechat && this.$wechat.isWechat()) {
this.$wechat.location(function (res) {
console.log(res)
let latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
let longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
let res2={
latitude: latitude ,
longitude: longitude
}
this_.initMap(res2)
//根据经纬度,解析区域,提示用户输入
});
}else{
console.error("不在微信环境中")
}
},
// 初始化我的位置
async initMap(res) {
this.longitude = res.longitude;
this.latitude = res.latitude;
this.addressObj = Object.assign({}, this.addressObj,{
longitude: res.longitude,
latitude: res.latitude,
address: await this.getAddressName(res)
})
this.myAddress = this.addressObj.address.formatted_addresses.recommend
},
// 地图选择位置后 查询地点名称
async checkMap(res) {
this.addressObj = Object.assign({}, this.addressObj,{
longitude: res.longitude,
latitude: res.latitude,
address: await this.getAddressName(res)
})
console.log('当前位置:' + res.latitude + '|' + res.longitude);
},
// 监听地图位置变化
mapChange(e) {
let that = this
clearTimeout(this.timer)
this.timer = setTimeout(() => {
if (e.type == 'end') {
that.mapCtx = uni.createMapContext('map', this)
that.mapCtx.getCenterLocation({
success: res => {
this.checkMap(res)
},
fail: err => {
console.log(err);
}
})
}
}, 200)
},
// 查询地图中心点的名称
getAddressName(addressObj) {
return new Promise((res) => {
// #ifdef APP-PLUS
qqmapsdk.reverseGeocoder({
location: {
latitude: addressObj.latitude,
longitude: addressObj.longitude
},
get_poi: 1,
poi_options: "page_size=1;page_index=1",
output: 'jsonp',
success: (e) => {
res(e.result.formatted_addresses.recommend);
},
fail: err => {
res(err);
}
})
// #endif
// #ifndef APP-PLUS
// ======================== jsonp跨域 ========================
let locationObj = addressObj.latitude+','+addressObj.longitude
let url = 'https://apis.map.qq.com/ws/geocoder/v1?coord_type=5&get_poi=1&output=jsonp&poi_options=page_size=1;page_index=1';
this.$jsonp(url,{
key: this.publicKey,
location: locationObj
}).then(e => {
res(e.result);
})
.catch(err => {
res(err);
})
// #endif
})
},
// 计算地图的高度
initMapH() {
// #ifdef APP-PLUS
this.mapH = uni.getSystemInfoSync().windowHeight - 210;
// #endif
// #ifndef APP-PLUS
this.mapH = uni.getSystemInfoSync().windowHeight - 170;
// #endif
},
// 移动到我的位置
toMyLocation() {
this.getLocation()
},
// 提交
submitAdress() {
this.controls = []
setTimeout(() => {
this.$emit('selectAddress', this.addressObj)
}, 100)
}
},
}
</script>
<style lang="scss" scoped>
.server-place{
position: fixed;
left: 0;
top: 0;
height: 100vh;
width: 100%;
background: #ffffff;
z-index: 999;
.icon-img{
width: 36px;
height: 36px;
display: block;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin-top: -70px;
}
.map-tools{
position: fixed;
width: 100%;
bottom: 0rem;
left: 0;
padding-bottom: .5rem;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.my-location{
width: 90%;
margin: 0 auto;
height: 2.5rem;
box-shadow: 0px 3px 20px rgba(0, 0, 0, 0.2);
background: #fff;
border-radius: 0.5rem;
display: flex;
justify-content: flex-start;
align-items: center;
overflow: hidden;
.left{
background: #3384ff;
// flex: 20%;
width: 2.5rem;
height: 100%;
}
.right{
font-size: 0.57rem;
margin-left: .5rem;
color: #111;
// flex: 80%;
display: flex;
justify-content: center;
align-items: flex-start;
flex-direction: column;
.text{
width: 12rem;
overflow: hidden;
white-space:nowrap;
text-overflow: ellipsis;
color: #3384FF;
margin-top: .3rem;
}
}
}
.start-place{
width: 85%;
margin: 0 auto;
height: 5.5rem;
margin: 0 auto;
margin-top: .6rem;
box-shadow: 0px 3px 20px rgba(0, 0, 0, 0.2);
background: #fff;
border-radius: 0.5rem;
padding: .5rem;
.place{
.title{
font-size: 0.67rem;
font-weight: bold;
color: #111;
}
.text{
font-size: 0.76rem;
color: #3384FF;
font-weight: bold;
width: 12rem;
vertical-align: middle;
display: inline-block;
margin-left: .5rem;
overflow: hidden;
white-space:nowrap;
text-overflow: ellipsis;
}
}
.tip{
font-size: 0.57rem;
color: #666;
margin-top: .5rem;
}
.sure{
margin-top: .5rem;
color: #FFFFFF;
background: #212121;
font-weight: 600;
}
}
}
}
</style>
4、相关图标
https://share.weiyun.com/5aMXvh8
收起阅读 »长期承接各类uniapp,公众号,H5,小程序,APP(原生、混合都ok) ,UI设计
本人独立开发淘客、多多客、京东客、自营商城商城开源项目:
https://ext.dcloud.net.cn/plugin?id=1229
部分可演示项目展示:
uni-app项目 Hi novelAPP
uni-app项目 掌鑫办公APP
uni-app项目 省钱兄APP
uni-app项目 省钱兄H5
https://www.gomyorder.cn/pc.html
uni-app项目 寻源家谱APP
http://www.xyjiapu.com:8063/#/pages/download/download
uni-app项目 寻源家谱H5
uni-app项目 优检通APP
vue 寻源家谱网站
uni-app项目 支付宝小程序
【淘淘省钱兄】【省钱能手】
uni-app项目 微信小程序
【狐淘】【省钱兄】【go offer】
uni-app项目 微信公众号
【省钱兄】【go省钱兄】
react 省钱兄PC端
http://www.shengqianxiong.com.cn
本人高级全栈工程师 拥有高级开发工程师团队
掌握vue、小程序原生开发、Android、IOS原生开发、
Java、node后台开发技术、大前端技术、react开发、
主要发展方向在移动端方向
专业开发移动端各类应用
如有问题可提供技术支持
承接各类uni-app项目
一站式软件开发服务
微信 710070994
咨询电话 13895585204
本人独立开发淘客、多多客、京东客、自营商城商城开源项目:
https://ext.dcloud.net.cn/plugin?id=1229
部分可演示项目展示:
uni-app项目 Hi novelAPP
uni-app项目 掌鑫办公APP
uni-app项目 省钱兄APP
uni-app项目 省钱兄H5
https://www.gomyorder.cn/pc.html
uni-app项目 寻源家谱APP
http://www.xyjiapu.com:8063/#/pages/download/download
uni-app项目 寻源家谱H5
uni-app项目 优检通APP
vue 寻源家谱网站
uni-app项目 支付宝小程序
【淘淘省钱兄】【省钱能手】
uni-app项目 微信小程序
【狐淘】【省钱兄】【go offer】
uni-app项目 微信公众号
【省钱兄】【go省钱兄】
react 省钱兄PC端
http://www.shengqianxiong.com.cn
本人高级全栈工程师 拥有高级开发工程师团队
掌握vue、小程序原生开发、Android、IOS原生开发、
Java、node后台开发技术、大前端技术、react开发、
主要发展方向在移动端方向
专业开发移动端各类应用
如有问题可提供技术支持
承接各类uni-app项目
一站式软件开发服务
微信 710070994
咨询电话 13895585204
收起阅读 »解决了cropper裁切图片toDataURL()跨域报错的问题,记录一下。
那些说 img.crossOrigin = 'anonymous' 能解决问题请绕道,害我纠结了一天。
这两天在弄头像裁切,发现toDataURL()不能用了,我以前根本没用过这个功能,所以不太了解,上网找了好些个例子,发现都不能用,我以为是发布者发的代码有问题,等我找了好多个DEMO后,发现都不能用,于是开始一行一行的读代码,试图找出问题所在。
等我把代码读到toDataURL() 这一行的时候,发现执行错误的问题就在这里,了解了一下,发现是WKwebview创建的时候跨域造成的, 而IOS从今年4月份也不再支持UIWebview了!而网络上的大神们给出的 img.crossOrigin = 'anonymous' 根本不管用,因为APP裁切的图片基本上都是拍照或本地相册,所以不存在这个问题。
于是,我找到了另一个图片裁切的插件,jquery photoclip ,发现这个插件能用,而且没有报跨域的错误,而且上传很方便,于是我懵了,都是jquery的插件,为啥一个能用一个不能用呢?
于是我读了读两个插件的源码,发现一个重要的不同:
crepper 是利用canvas直接读取img文件,尝试转成base64的时候出错,这个目前无解,官方给出的解决方案是用plus先转成base64再使用,还给出了例子,结果我是H5+的项目,没有尝试成功。
photoclip 是使用一个input file 控件,先选择本机文件,然后利用file控件读取用户上传的文件信息,然后再转成base64进行处理。
我想想算了,就用photoclip吧,能用就行,结果发现这破东西根本不能用,缩方功能做的和shi一样,根本不行,跳来跳去,抖来抖去的,而且要先点击input选择文件才行,用户体验非常不好。
于是我想到了一个解决方案:
为什么不用photoclip 读取文件的思路来解决cropper的跨域问题呢?各取所长。
于是想着怎么把一个本地图径的path地址转换成file控件里的文件内容,而且要直接调用相机,而不是文件选择框。
最后形成一个完美的解决方案:
Step1 调用相机拍照形成本地文件。
Step2 利用fileReader把文件读出来,转换成Base64。
Step3 把Base64的图片利用cropper渲染到canvas上进行裁切。
Step4 再次使用 cropper.toDataURL()方法的时候,就不再全报错,顺利解决!
我现在的代码因为各种尝试弄的很乱,就不发了,发了你们看的也费劲,好多冗余代码,等我清理好之后,可以发布上来和大家共享。
那些说 img.crossOrigin = 'anonymous' 能解决问题请绕道,害我纠结了一天。
这两天在弄头像裁切,发现toDataURL()不能用了,我以前根本没用过这个功能,所以不太了解,上网找了好些个例子,发现都不能用,我以为是发布者发的代码有问题,等我找了好多个DEMO后,发现都不能用,于是开始一行一行的读代码,试图找出问题所在。
等我把代码读到toDataURL() 这一行的时候,发现执行错误的问题就在这里,了解了一下,发现是WKwebview创建的时候跨域造成的, 而IOS从今年4月份也不再支持UIWebview了!而网络上的大神们给出的 img.crossOrigin = 'anonymous' 根本不管用,因为APP裁切的图片基本上都是拍照或本地相册,所以不存在这个问题。
于是,我找到了另一个图片裁切的插件,jquery photoclip ,发现这个插件能用,而且没有报跨域的错误,而且上传很方便,于是我懵了,都是jquery的插件,为啥一个能用一个不能用呢?
于是我读了读两个插件的源码,发现一个重要的不同:
crepper 是利用canvas直接读取img文件,尝试转成base64的时候出错,这个目前无解,官方给出的解决方案是用plus先转成base64再使用,还给出了例子,结果我是H5+的项目,没有尝试成功。
photoclip 是使用一个input file 控件,先选择本机文件,然后利用file控件读取用户上传的文件信息,然后再转成base64进行处理。
我想想算了,就用photoclip吧,能用就行,结果发现这破东西根本不能用,缩方功能做的和shi一样,根本不行,跳来跳去,抖来抖去的,而且要先点击input选择文件才行,用户体验非常不好。
于是我想到了一个解决方案:
为什么不用photoclip 读取文件的思路来解决cropper的跨域问题呢?各取所长。
于是想着怎么把一个本地图径的path地址转换成file控件里的文件内容,而且要直接调用相机,而不是文件选择框。
最后形成一个完美的解决方案:
Step1 调用相机拍照形成本地文件。
Step2 利用fileReader把文件读出来,转换成Base64。
Step3 把Base64的图片利用cropper渲染到canvas上进行裁切。
Step4 再次使用 cropper.toDataURL()方法的时候,就不再全报错,顺利解决!
我现在的代码因为各种尝试弄的很乱,就不发了,发了你们看的也费劲,好多冗余代码,等我清理好之后,可以发布上来和大家共享。
收起阅读 »uni-AD App端激励视频服务器回调使用指南
HBuilderX 2.7.0 版本起,uni-AD的激励视频广告支持穿山甲的服务器回调功能
HBuilderX 3.1.15 版本起,uni-AD的激励视频广告支持优量汇、快手的服务器回调功能
概述
激励视频服务端回调是指在用户看完激励视频达到奖励条件时,广告平台服务端会向开发者服务端发送一个验证请求,同时客户端会给出onVerify回调,开发者根据回调进行奖励发放,不同的广告平台onVerify回调和服务端验证请求时机不一样(比如:穿山甲的onVerify回调是在服务端验证请求之后进行的,优量汇和快手都是同时进行的),因为优量汇和快手的奖励回调onVerify事件和服务端验证请求是同时发送的,且开发者后台收到验证请求可能会有延迟或网络原因上的失败,所以开发者需要平衡用户体验与奖励验证。
相对来讲服务器回调将更加安全,可以依赖广告平台的反作弊机制来避免用户模拟观看广告完成的事件。
开通服务器回调
- 登录uni-AD后台
- 找到应用对应的广告位,配置激励视频
- 选择服务空间,如果没有点击新增即可
- 选择
业务在传统服务器, 输入接收服务器回调的http地址
App端创建激励视频广告时传入回调参数
uni-app项目
https://uniapp.dcloud.io/api/a-d/rewarded-video
5+ App(WAP2APP)项目
创建激励视频广告plus.ad.createRewardedVideoAd时传入服务器回调数据urlCallback,示例如下:
adReward = plus.ad.createRewardedVideoAd({
adpid: '1507000689',
urlCallback: {
userId: 'test111111', //可选的透传参数
extra: 'testdata' //可选的透传参数
}
});
调用激励视频广告对象的onVerify监听服务器是否发送验证请求
穿山甲:
adReward.onVerify(function(e){
console.log('服务器发送验证请求且回调校验完成');
var provider= e.provider;
var valid = e.isValid; //获取校验结果
//valid为true表示通过了服务器的校验,false表示可能没有通过服务器的校验,或是服务器延迟或失败(此时需增加逻辑:轮询向服务器请求并验证结果)
});
优量汇:
adReward.onVerify(function(e){
console.log('服务器已发送验证请求');
var provider= e.provider;
var transId = e.transId;
需增加逻辑:轮询向服务器请求并验证结果
});
快手:
adReward.onVerify(function(e){
console.log('服务器已发送验证请求');
var provider= e.provider;
需增加逻辑:轮询向服务器请求并验证结果
}); HBuilderX 2.7.0 版本起,uni-AD的激励视频广告支持穿山甲的服务器回调功能
HBuilderX 3.1.15 版本起,uni-AD的激励视频广告支持优量汇、快手的服务器回调功能
概述
激励视频服务端回调是指在用户看完激励视频达到奖励条件时,广告平台服务端会向开发者服务端发送一个验证请求,同时客户端会给出onVerify回调,开发者根据回调进行奖励发放,不同的广告平台onVerify回调和服务端验证请求时机不一样(比如:穿山甲的onVerify回调是在服务端验证请求之后进行的,优量汇和快手都是同时进行的),因为优量汇和快手的奖励回调onVerify事件和服务端验证请求是同时发送的,且开发者后台收到验证请求可能会有延迟或网络原因上的失败,所以开发者需要平衡用户体验与奖励验证。
相对来讲服务器回调将更加安全,可以依赖广告平台的反作弊机制来避免用户模拟观看广告完成的事件。
开通服务器回调
- 登录uni-AD后台
- 找到应用对应的广告位,配置激励视频
- 选择服务空间,如果没有点击新增即可
- 选择
业务在传统服务器, 输入接收服务器回调的http地址
App端创建激励视频广告时传入回调参数
uni-app项目
https://uniapp.dcloud.io/api/a-d/rewarded-video
5+ App(WAP2APP)项目
创建激励视频广告plus.ad.createRewardedVideoAd时传入服务器回调数据urlCallback,示例如下:
adReward = plus.ad.createRewardedVideoAd({
adpid: '1507000689',
urlCallback: {
userId: 'test111111', //可选的透传参数
extra: 'testdata' //可选的透传参数
}
});
调用激励视频广告对象的onVerify监听服务器是否发送验证请求
穿山甲:
adReward.onVerify(function(e){
console.log('服务器发送验证请求且回调校验完成');
var provider= e.provider;
var valid = e.isValid; //获取校验结果
//valid为true表示通过了服务器的校验,false表示可能没有通过服务器的校验,或是服务器延迟或失败(此时需增加逻辑:轮询向服务器请求并验证结果)
});
优量汇:
adReward.onVerify(function(e){
console.log('服务器已发送验证请求');
var provider= e.provider;
var transId = e.transId;
需增加逻辑:轮询向服务器请求并验证结果
});
快手:
adReward.onVerify(function(e){
console.log('服务器已发送验证请求');
var provider= e.provider;
需增加逻辑:轮询向服务器请求并验证结果
}); 收起阅读 »
HbuilderX 的主题
基于 2.6.5.20200314 版,,不知道兼容性如何
主题太少了,好不容易找了一个,结果发现配色还不对,干脆自己来搞一个。
界面
使用
壹、 如果不会配置,请参考自定义主题教程
贰、 主题选择【雅蓝】
叁、 在编辑器顶部位置找到【工具 / 设置】进入
肆、 选择源码视图
伍、 键入以下代码
"[Atom One Dark]": {
// 文本编辑区
"editor.background": "#282c34",
// 分栏
"editorGroup.border": "rgba(0,0,0,0)",
// 代码助手
"editorSuggestWidget.highlightForeground": "#e5c07b",
// 预览按钮
"extensionButton.border": "#181a1f",
// 文本框
"focusBorder": "#464646",
"input.background": "#21252b",
// 标签卡
"tab.activeBackground": "#282c34",
"tab.activeForeground": "#dcdcdc",
"tab.border": "rgba(0,0,0,0)",
"tab.hoverBackground": "#323842",
"tab.inactiveBackground": "#21252b",
// 设置
"inputOption.activeBorder": "#464646",
"settings.dropdownBackground": "#181a1f",
"settings.dropdownBorder": "#464646",
"settings.dropdownListBorder": "#181a1f",
"settings.textInputBackground": "#181a1f",
"settings.textInputBorder": "#181a1f",
// 工具栏
"toolBar.background": "#21252b",
"toolBar.border": "rgba(0,0,0,0)",
"toolBar.hoverBackground": "#2c313a",
// 控制台
"terminal.background": "#21252b",
"console.background": "#21252b",
"panelTitle.activeForeground": "#cccccc",
"debug.foreground": "#cccccc"
} 基于 2.6.5.20200314 版,,不知道兼容性如何
主题太少了,好不容易找了一个,结果发现配色还不对,干脆自己来搞一个。
界面
使用
壹、 如果不会配置,请参考自定义主题教程
贰、 主题选择【雅蓝】
叁、 在编辑器顶部位置找到【工具 / 设置】进入
肆、 选择源码视图
伍、 键入以下代码
"[Atom One Dark]": {
// 文本编辑区
"editor.background": "#282c34",
// 分栏
"editorGroup.border": "rgba(0,0,0,0)",
// 代码助手
"editorSuggestWidget.highlightForeground": "#e5c07b",
// 预览按钮
"extensionButton.border": "#181a1f",
// 文本框
"focusBorder": "#464646",
"input.background": "#21252b",
// 标签卡
"tab.activeBackground": "#282c34",
"tab.activeForeground": "#dcdcdc",
"tab.border": "rgba(0,0,0,0)",
"tab.hoverBackground": "#323842",
"tab.inactiveBackground": "#21252b",
// 设置
"inputOption.activeBorder": "#464646",
"settings.dropdownBackground": "#181a1f",
"settings.dropdownBorder": "#464646",
"settings.dropdownListBorder": "#181a1f",
"settings.textInputBackground": "#181a1f",
"settings.textInputBorder": "#181a1f",
// 工具栏
"toolBar.background": "#21252b",
"toolBar.border": "rgba(0,0,0,0)",
"toolBar.hoverBackground": "#2c313a",
// 控制台
"terminal.background": "#21252b",
"console.background": "#21252b",
"panelTitle.activeForeground": "#cccccc",
"debug.foreground": "#cccccc"
} 收起阅读 »
专业承接/电商APP定制开发、团队开发电商APP开发有哪些功能?
一、商品展示的功能
商品展示是电商APP最核心的部分,商家通过视频、图片、文字等方式向消费者展示商品,向消费者展示商城以及商品的优势,来吸引消费者购买。
二、搜索商品的功能
三、商品分类的功能
四、商品推荐的功能
五、在线咨询的功能
六、收藏商品的功能
七、分享商品的功能
八、加入购物车的功能
九、在线支付的功能
十、订单管理的功能
十一、查看物流的功能
一、商品展示的功能
商品展示是电商APP最核心的部分,商家通过视频、图片、文字等方式向消费者展示商品,向消费者展示商城以及商品的优势,来吸引消费者购买。
二、搜索商品的功能
三、商品分类的功能
四、商品推荐的功能
五、在线咨询的功能
六、收藏商品的功能
七、分享商品的功能
八、加入购物车的功能
九、在线支付的功能
十、订单管理的功能
十一、查看物流的功能
分享uniapp使用原生Android推送消息(内推)以及点击通知监听数据
前言
由于用uniapp官方的plus.push.createMessage()在Android平台下推送通知无法显示推送时间,需要调用原生Android推送通知。
在社区综合了各大神的代码,具体如下:
推送
推送事件:
/**
* android原生通知发送
* @param content 通知内容
* @param data json对象,存储通知的隐藏数据,用于点击通知时接收使用
*/
android_notify(content = '', data = {}) {
// #ifdef APP-PLUS
var title = '通知标题';
console.log('准备通知');
console.log(plus.os.name);
//Android平台下才使用此推送
if (plus.os.name != 'Android') {
return false;
}
//随机生成通知ID
var NotifyID = Math.floor(Math.random() * 10000) + 1;
var main = plus.android.runtimeMainActivity();
var Context = plus.android.importClass("android.content.Context");
var NotificationManager = plus.android.importClass("android.app.NotificationManager");
var nm = main.getSystemService(Context.NOTIFICATION_SERVICE);
var Notification = plus.android.importClass("android.app.Notification");
var Intent = plus.android.importClass("android.content.Intent");
var PendingIntent = plus.android.importClass("android.app.PendingIntent");
var intent = new Intent(main, main.getClass());
//传递参数
var payload = {
'msg':content,
'notify_id':NotifyID,
'data':data
};
intent.putExtra("receive", JSON.stringify(payload));
//PendingIntent.getActivity的第二个参数需要设置为随机数,否则多个通知时会导致前面的通知被后面的通知替换Extra的数据
var pendingIntent = PendingIntent.getActivity(main, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
var SystemVersion = plus.os.version;
var firstVersionNumber = Number(SystemVersion.split('.')[0]);
var r = plus.android.importClass("android.R");
var mNotification;
//判断当前系统版本在8.0及以上
if (firstVersionNumber >= 8){
var NotificationChannel = plus.android.importClass('android.app.NotificationChannel');
var channel = new NotificationChannel("s"+ NotifyID, "1", NotificationManager.IMPORTANCE_HIGH);
nm.createNotificationChannel(channel);
Notification = plus.android.importClass("android.support.v4.app.NotificationCompat");
mNotification = new Notification.Builder(main, "s" + NotifyID);
} else {
Notification = plus.android.importClass("android.app.Notification");
mNotification = new Notification.Builder(main);
}
mNotification.setContentTitle(title) //设置标题
mNotification.setContentText(content); //设置内容
//mNotification.setSubText(''); //子内容暂时去掉
mNotification.setAutoCancel(true); //设置点击消失
mNotification.setShowWhen(true); //显示通知时间,貌似不加这句也能显示
mNotification.setTicker("PadInfo"); //弹出通知
mNotification.setSmallIcon(17301620); //设置当前app图标
//mNotification.setDefaults(Notification.DEFAULT_VIBRATE); //声音、闪灯、震动效果,可叠加,此语句无效
mNotification.setPriority(Notification.PRIORITY_DEFAULT); //通知优先级
mNotification.flags=Notification.FLAG_ONLY_ALERT_ONCE; //发起通知时震动
mNotification.setContentIntent(pendingIntent);
var mNb = mNotification.build();
//判断当前系统版本在8.0及以上
if (firstVersionNumber >= 8){
nm.notify("s" + NotifyID, NotifyID, mNb);
} else {
nm.notify(NotifyID, mNb);
}
//void plus.device.beep(2);//bee bee叫
plus.device.vibrate(300);//震动
console.log('通知结束');
return true;
// #endif
}
调用方法:
android_notify('test', {
params1: 'params1',
params2: 'params2',
params3: 'params3',
params4: 'params4'
});
接收
点击通知接收通知数据
/**
* android原生通知接收
*/
android_receive() {
// #ifdef APP-PLUS
if (plus.os.name != 'Android') {
return false;
}
//android原生通知栏接收器(程序退出后无效)
var main = plus.android.runtimeMainActivity();
var intent = main.getIntent();
var message = intent && intent.getExtra != undefined ? intent.getExtra("receive") : null;
console.log(message);
message = message ? JSON.parse(message) : '';
if (message) {
//删除当前通知
// var Context = plus.android.importClass("android.content.Context");
// var nm = main.getSystemService(Context.NOTIFICATION_SERVICE);
// console.log(message.notify_id);
//nm.cancel('s' + message.notify_id, message.notify_id);//安卓版本大于等于8的
//nm.cancel(message.notify_id);//安卓版本小于8的
// nm.cancelAll();
//把消息数据置空,以免再次打开APP时重复执行此处
intent.putExtra("receive", '');
var params = message.data;
if (params1 == 'xxx') {
//TODO do something.
} else if (params1 == 'yyy') {
//TODO do something.
}
}
// #endif
}
调用方法
// App.Vue
onShow: function() {
...
// #ifdef APP-PLUS
android_receive();
// #endif
...
},
注意事项
- 已知问题:第一次通知会有通知延迟现象,大概2-3秒后才会收到通知,之后就不会了(官方的推送没有此问题);
- 程序被关闭后点击通知消息无法再接收到通知的数据(暂时没有好的解决方案,如果大家有好的方法,欢迎回复分享);
希望能帮助大家。
-
2020年4月3日补充:
-
多行显示通知消息
//创建大文本样式
var bigTextStyle = plus.android.importClass("android.support.v4.app.NotificationCompat$BigTextStyle");
var style = new bigTextStyle();
style.setBigContentTitle(title);
// style.setSummaryText("备注一行");
style.bigText(content);//这里可以设置超长的文本
mNotification.setStyle(style); //设置大文本样式
以上代码放到var mNb = mNotification.build();之前即可
前言
由于用uniapp官方的plus.push.createMessage()在Android平台下推送通知无法显示推送时间,需要调用原生Android推送通知。
在社区综合了各大神的代码,具体如下:
推送
推送事件:
/**
* android原生通知发送
* @param content 通知内容
* @param data json对象,存储通知的隐藏数据,用于点击通知时接收使用
*/
android_notify(content = '', data = {}) {
// #ifdef APP-PLUS
var title = '通知标题';
console.log('准备通知');
console.log(plus.os.name);
//Android平台下才使用此推送
if (plus.os.name != 'Android') {
return false;
}
//随机生成通知ID
var NotifyID = Math.floor(Math.random() * 10000) + 1;
var main = plus.android.runtimeMainActivity();
var Context = plus.android.importClass("android.content.Context");
var NotificationManager = plus.android.importClass("android.app.NotificationManager");
var nm = main.getSystemService(Context.NOTIFICATION_SERVICE);
var Notification = plus.android.importClass("android.app.Notification");
var Intent = plus.android.importClass("android.content.Intent");
var PendingIntent = plus.android.importClass("android.app.PendingIntent");
var intent = new Intent(main, main.getClass());
//传递参数
var payload = {
'msg':content,
'notify_id':NotifyID,
'data':data
};
intent.putExtra("receive", JSON.stringify(payload));
//PendingIntent.getActivity的第二个参数需要设置为随机数,否则多个通知时会导致前面的通知被后面的通知替换Extra的数据
var pendingIntent = PendingIntent.getActivity(main, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
var SystemVersion = plus.os.version;
var firstVersionNumber = Number(SystemVersion.split('.')[0]);
var r = plus.android.importClass("android.R");
var mNotification;
//判断当前系统版本在8.0及以上
if (firstVersionNumber >= 8){
var NotificationChannel = plus.android.importClass('android.app.NotificationChannel');
var channel = new NotificationChannel("s"+ NotifyID, "1", NotificationManager.IMPORTANCE_HIGH);
nm.createNotificationChannel(channel);
Notification = plus.android.importClass("android.support.v4.app.NotificationCompat");
mNotification = new Notification.Builder(main, "s" + NotifyID);
} else {
Notification = plus.android.importClass("android.app.Notification");
mNotification = new Notification.Builder(main);
}
mNotification.setContentTitle(title) //设置标题
mNotification.setContentText(content); //设置内容
//mNotification.setSubText(''); //子内容暂时去掉
mNotification.setAutoCancel(true); //设置点击消失
mNotification.setShowWhen(true); //显示通知时间,貌似不加这句也能显示
mNotification.setTicker("PadInfo"); //弹出通知
mNotification.setSmallIcon(17301620); //设置当前app图标
//mNotification.setDefaults(Notification.DEFAULT_VIBRATE); //声音、闪灯、震动效果,可叠加,此语句无效
mNotification.setPriority(Notification.PRIORITY_DEFAULT); //通知优先级
mNotification.flags=Notification.FLAG_ONLY_ALERT_ONCE; //发起通知时震动
mNotification.setContentIntent(pendingIntent);
var mNb = mNotification.build();
//判断当前系统版本在8.0及以上
if (firstVersionNumber >= 8){
nm.notify("s" + NotifyID, NotifyID, mNb);
} else {
nm.notify(NotifyID, mNb);
}
//void plus.device.beep(2);//bee bee叫
plus.device.vibrate(300);//震动
console.log('通知结束');
return true;
// #endif
}
调用方法:
android_notify('test', {
params1: 'params1',
params2: 'params2',
params3: 'params3',
params4: 'params4'
});
接收
点击通知接收通知数据
/**
* android原生通知接收
*/
android_receive() {
// #ifdef APP-PLUS
if (plus.os.name != 'Android') {
return false;
}
//android原生通知栏接收器(程序退出后无效)
var main = plus.android.runtimeMainActivity();
var intent = main.getIntent();
var message = intent && intent.getExtra != undefined ? intent.getExtra("receive") : null;
console.log(message);
message = message ? JSON.parse(message) : '';
if (message) {
//删除当前通知
// var Context = plus.android.importClass("android.content.Context");
// var nm = main.getSystemService(Context.NOTIFICATION_SERVICE);
// console.log(message.notify_id);
//nm.cancel('s' + message.notify_id, message.notify_id);//安卓版本大于等于8的
//nm.cancel(message.notify_id);//安卓版本小于8的
// nm.cancelAll();
//把消息数据置空,以免再次打开APP时重复执行此处
intent.putExtra("receive", '');
var params = message.data;
if (params1 == 'xxx') {
//TODO do something.
} else if (params1 == 'yyy') {
//TODO do something.
}
}
// #endif
}
调用方法
// App.Vue
onShow: function() {
...
// #ifdef APP-PLUS
android_receive();
// #endif
...
},
注意事项
- 已知问题:第一次通知会有通知延迟现象,大概2-3秒后才会收到通知,之后就不会了(官方的推送没有此问题);
- 程序被关闭后点击通知消息无法再接收到通知的数据(暂时没有好的解决方案,如果大家有好的方法,欢迎回复分享);
希望能帮助大家。
-
2020年4月3日补充:
-
多行显示通知消息
//创建大文本样式
var bigTextStyle = plus.android.importClass("android.support.v4.app.NotificationCompat$BigTextStyle");
var style = new bigTextStyle();
style.setBigContentTitle(title);
// style.setSummaryText("备注一行");
style.bigText(content);//这里可以设置超长的文本
mNotification.setStyle(style); //设置大文本样式
以上代码放到var mNb = mNotification.build();之前即可
uniapp打包成H5样式不生效问题
本来用uniapp写个小程序的,因为需求需要打包成H5,本来以为不会有什么问题的,打包完成之后发现一个button的样式没有了,原来该button的样式是通过id绑定的,后来折腾了半天都没有用,改成class绑定样式就可以了
本来用uniapp写个小程序的,因为需求需要打包成H5,本来以为不会有什么问题的,打包完成之后发现一个button的样式没有了,原来该button的样式是通过id绑定的,后来折腾了半天都没有用,改成class绑定样式就可以了
小团队承接APP定制开发项目、iOS、安卓版均可开发
小团队承接APP定制开发项目、iOS、安卓均可开发
首先提供项目整体需求逻辑;需求确认;
计算工期报价以及开发人员配备;
签订合同按合同约定支付合同款项;
线稿图、UI设计图确认;
UI设计图确认后,签订确认书;
前端代码编写切图;
后台搭建完成开发;
本团队开始测试,测试完毕无误后,交由客户进行测试;
客户测试无误,开始安排项目对接,后台不需要的数据进行清除;
客户安排上线时间,进行上线;
小团队承接APP定制开发项目、iOS、安卓均可开发
首先提供项目整体需求逻辑;需求确认;
计算工期报价以及开发人员配备;
签订合同按合同约定支付合同款项;
线稿图、UI设计图确认;
UI设计图确认后,签订确认书;
前端代码编写切图;
后台搭建完成开发;
本团队开始测试,测试完毕无误后,交由客户进行测试;
客户测试无误,开始安排项目对接,后台不需要的数据进行清除;
客户安排上线时间,进行上线;







