获取手机设备信息、app版本信息、ip地址
获取手机设备的相关信息,如IMEI、IMSI、型号、厂商等。通过plus.device获取设备信息管理对象。
获取当前运行环境信息、与其它程序进行通讯等。通过plus.runtime可获取运行环境管理对象。
直接上demo,复制即可用。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="../../css/mui.min.css" rel="stylesheet" />
<script src="../../js/mui.js"></script>
<script src="../../js/vue.js"></script>
<style>
body{max-width: 750px; min-width: 320px; margin: 0 auto; background-color: #F5F5F5;overflow-x: hidden;
font-family: -apple-system,Helvetica,sans-serif;}
div{font-size: .26rem; color: #474747;line-height: 2;}
span{font-size: .28rem; color: #D1021F;}
</style>
<script>
(function(doc, win) {
var w = document.documentElement.clientWidth;
if (w > 750) {
w = 750
} else if (w < 320) {
w = 320
}
var f = w / 750 * 100 + "px";
document.documentElement.style.fontSize = f;
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function() {
var clientWidth = docEl.clientWidth > 750 ? 750 : docEl.clientWidth;
if (clientWidth > 750) {
clientWidth = 750
} else if (clientWidth < 320) {
clientWidth = 320
}
if (!clientWidth) return;
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
</script>
</head>
<body>
<header class="mui-bar mui-bar-nav">
<h1 class="mui-title">我的手机信息</h1>
</header>
<div id="content" class="mui-content mui-content-padded">
<div class="mui-text-left" v-for="item in list">
{{item.title}}
<span>
{{item.value}}
</span>
</div>
</div>
<script type="text/javascript">
var spans = document.getElementsByTagName('span');
var VM = new Vue({
el: ".mui-content",
data: {
list:[]
},
})
mui.plusReady(function() {
//获取系统名称
var name = plus.os.name;
VM.list.push({
"title": "系统名称",
"value": name
})
//获取系统版本
var version = plus.os.version;
VM.list.push({
"title": "系统版本",
"value": version
})
//设备型号
VM.list.push({
"title": "设备型号",
"value": plus.device.model
})
//获取生产厂商
var vendor2 = plus.device.vendor
VM.list.push({
"title": "生产厂商",
"value": vendor2
})
//获取系统供应商
var vendor = plus.os.vendor
VM.list.push({
"title": "系统供应商",
"value": vendor
})
//获取系统语言信息
var language = plus.os.language;
VM.list.push({
"title": "系统语言信息",
"value": language
})
var types = {}; //网络类型
types[plus.networkinfo.CONNECTION_UNKNOW] = "未知";
types[plus.networkinfo.CONNECTION_NONE] = "未连接网络";
types[plus.networkinfo.CONNECTION_ETHERNET] = "有线网络";
types[plus.networkinfo.CONNECTION_WIFI] = "WiFi网络";
types[plus.networkinfo.CONNECTION_CELL2G] = "2G蜂窝网络";
types[plus.networkinfo.CONNECTION_CELL3G] = "3G蜂窝网络";
types[plus.networkinfo.CONNECTION_CELL4G] = "4G蜂窝网络";
var network = types[plus.networkinfo.getCurrentType()];
VM.list.push({
"title": "网络类型",
"value": network
})
//获取设备的唯一标示
plus.device.getInfo({
success: function(e) {
VM.list.push({
"title": "国际移动设备身份码imei",
"value": e.imei
})
VM.list.push({
"title": "国际移动用户识别码imsi",
"value": e.imsi
})
VM.list.push({
"title": "设备的唯一标识",
"value": e.uuid
})
},
fail: function(e) {
console.log('getDeviceInfo failed: ' + JSON.stringify(e));
}
});
//获取APP版本信息
plus.runtime.getProperty(plus.runtime.appid, function(inf) {
var ver = inf.version;
VM.list.push({
"title": "APP名称",
"value": inf.name
})
VM.list.push({
"title": "APP版本信息",
"value": "版本:"+inf.version+";版本号:"+inf.versionCode
})
console.log(JSON.stringify(inf))
})
});
//获取IP地址信息
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type", "text/javascript");
script.src = src;
document.body.appendChild(script);
}
function foo(data) {
var json = data.data[0];
VM.list.push({
"title": "位置",
"value": json.location
})
VM.list.push({
"title": "IP地址",
"value": json.origip
})
console.log("IPInfo:"+ JSON.stringify(json));
};
window.onload = function() {
addScriptTag(
'https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=ip&co=&resource_id=6006&t=1562124098965&ie=utf8&oe=gbk&cb=foo&format=json&tn=baidu'
);
}
</script>
</body>
</html>
注意:
获取IP地址和plus.device.getInfo都是异步的,所以在使用的时候要注意时机
运行结果:
Android和IOS获取imei、imsi、uuid时须知:
imei: (String 类型 )设备的国际移动设备身份码
如果设备不支持或无法获取(如用户未授权)则返回空字符串。 如果设备存在多个身份码,则以“,”字符分割拼接,如“862470039452950,862470039452943”。
平台支持
Android - ALL (支持): 需要用户授权才能获取,如果用户拒绝获取设备信息则返回空字符串。
iOS - ALL (不支持): 无法获取设备身份码,返回空字符串。
imsi: (Array[ String ] 类型 )设备的国际移动用户识别码
字符串数组类型,获取设备上插入SIM的国际移动设备身份码。 如果设备支持多卡模式则返回所有SIM身份码。 如果设备不支持或没有插入SIM卡则返回空数组。
平台支持
Android - ALL (支持): 如果无法获取国际移动用户标识(如用户未授权)则返回空数组。
iOS - ALL (不支持): 无法获取设备移动用户识别码,返回空数组。
uuid: (String 类型 )设备标识
设备的唯一标识号。
平台支持
Android - ALL (支持): 与设备的imei号一致。 注意:如果无法获取设备imei则使用设备wifi的mac地址,如果无法获取设备mac地址则随机生成设备标识号(不同App在同一台设备上获取的值一致)。
iOS - ALL (不支持): 根据包名随机生成的设备标识号。 注意:设备重置(刷机)后会重新生成
其他的属性和方法,参考html5plus官网:
http://www.html5plus.org/doc/zh_cn/device.html
获取手机设备的相关信息,如IMEI、IMSI、型号、厂商等。通过plus.device获取设备信息管理对象。
获取当前运行环境信息、与其它程序进行通讯等。通过plus.runtime可获取运行环境管理对象。
直接上demo,复制即可用。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="../../css/mui.min.css" rel="stylesheet" />
<script src="../../js/mui.js"></script>
<script src="../../js/vue.js"></script>
<style>
body{max-width: 750px; min-width: 320px; margin: 0 auto; background-color: #F5F5F5;overflow-x: hidden;
font-family: -apple-system,Helvetica,sans-serif;}
div{font-size: .26rem; color: #474747;line-height: 2;}
span{font-size: .28rem; color: #D1021F;}
</style>
<script>
(function(doc, win) {
var w = document.documentElement.clientWidth;
if (w > 750) {
w = 750
} else if (w < 320) {
w = 320
}
var f = w / 750 * 100 + "px";
document.documentElement.style.fontSize = f;
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function() {
var clientWidth = docEl.clientWidth > 750 ? 750 : docEl.clientWidth;
if (clientWidth > 750) {
clientWidth = 750
} else if (clientWidth < 320) {
clientWidth = 320
}
if (!clientWidth) return;
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
</script>
</head>
<body>
<header class="mui-bar mui-bar-nav">
<h1 class="mui-title">我的手机信息</h1>
</header>
<div id="content" class="mui-content mui-content-padded">
<div class="mui-text-left" v-for="item in list">
{{item.title}}
<span>
{{item.value}}
</span>
</div>
</div>
<script type="text/javascript">
var spans = document.getElementsByTagName('span');
var VM = new Vue({
el: ".mui-content",
data: {
list:[]
},
})
mui.plusReady(function() {
//获取系统名称
var name = plus.os.name;
VM.list.push({
"title": "系统名称",
"value": name
})
//获取系统版本
var version = plus.os.version;
VM.list.push({
"title": "系统版本",
"value": version
})
//设备型号
VM.list.push({
"title": "设备型号",
"value": plus.device.model
})
//获取生产厂商
var vendor2 = plus.device.vendor
VM.list.push({
"title": "生产厂商",
"value": vendor2
})
//获取系统供应商
var vendor = plus.os.vendor
VM.list.push({
"title": "系统供应商",
"value": vendor
})
//获取系统语言信息
var language = plus.os.language;
VM.list.push({
"title": "系统语言信息",
"value": language
})
var types = {}; //网络类型
types[plus.networkinfo.CONNECTION_UNKNOW] = "未知";
types[plus.networkinfo.CONNECTION_NONE] = "未连接网络";
types[plus.networkinfo.CONNECTION_ETHERNET] = "有线网络";
types[plus.networkinfo.CONNECTION_WIFI] = "WiFi网络";
types[plus.networkinfo.CONNECTION_CELL2G] = "2G蜂窝网络";
types[plus.networkinfo.CONNECTION_CELL3G] = "3G蜂窝网络";
types[plus.networkinfo.CONNECTION_CELL4G] = "4G蜂窝网络";
var network = types[plus.networkinfo.getCurrentType()];
VM.list.push({
"title": "网络类型",
"value": network
})
//获取设备的唯一标示
plus.device.getInfo({
success: function(e) {
VM.list.push({
"title": "国际移动设备身份码imei",
"value": e.imei
})
VM.list.push({
"title": "国际移动用户识别码imsi",
"value": e.imsi
})
VM.list.push({
"title": "设备的唯一标识",
"value": e.uuid
})
},
fail: function(e) {
console.log('getDeviceInfo failed: ' + JSON.stringify(e));
}
});
//获取APP版本信息
plus.runtime.getProperty(plus.runtime.appid, function(inf) {
var ver = inf.version;
VM.list.push({
"title": "APP名称",
"value": inf.name
})
VM.list.push({
"title": "APP版本信息",
"value": "版本:"+inf.version+";版本号:"+inf.versionCode
})
console.log(JSON.stringify(inf))
})
});
//获取IP地址信息
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type", "text/javascript");
script.src = src;
document.body.appendChild(script);
}
function foo(data) {
var json = data.data[0];
VM.list.push({
"title": "位置",
"value": json.location
})
VM.list.push({
"title": "IP地址",
"value": json.origip
})
console.log("IPInfo:"+ JSON.stringify(json));
};
window.onload = function() {
addScriptTag(
'https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=ip&co=&resource_id=6006&t=1562124098965&ie=utf8&oe=gbk&cb=foo&format=json&tn=baidu'
);
}
</script>
</body>
</html>
注意:
获取IP地址和plus.device.getInfo都是异步的,所以在使用的时候要注意时机
运行结果:
Android和IOS获取imei、imsi、uuid时须知:
imei: (String 类型 )设备的国际移动设备身份码
如果设备不支持或无法获取(如用户未授权)则返回空字符串。 如果设备存在多个身份码,则以“,”字符分割拼接,如“862470039452950,862470039452943”。
平台支持
Android - ALL (支持): 需要用户授权才能获取,如果用户拒绝获取设备信息则返回空字符串。
iOS - ALL (不支持): 无法获取设备身份码,返回空字符串。
imsi: (Array[ String ] 类型 )设备的国际移动用户识别码
字符串数组类型,获取设备上插入SIM的国际移动设备身份码。 如果设备支持多卡模式则返回所有SIM身份码。 如果设备不支持或没有插入SIM卡则返回空数组。
平台支持
Android - ALL (支持): 如果无法获取国际移动用户标识(如用户未授权)则返回空数组。
iOS - ALL (不支持): 无法获取设备移动用户识别码,返回空数组。
uuid: (String 类型 )设备标识
设备的唯一标识号。
平台支持
Android - ALL (支持): 与设备的imei号一致。 注意:如果无法获取设备imei则使用设备wifi的mac地址,如果无法获取设备mac地址则随机生成设备标识号(不同App在同一台设备上获取的值一致)。
iOS - ALL (不支持): 根据包名随机生成的设备标识号。 注意:设备重置(刷机)后会重新生成
其他的属性和方法,参考html5plus官网:
http://www.html5plus.org/doc/zh_cn/device.html
uni-app仿微信聊天uni_chatroom实例|uniapp仿微信
前几天给大家分享了一个uniapp自定义弹窗组件,今天给大家分享基于uniapp+vue+vuex等技术开发的仿微信界面App聊天室UniChatRoom,实现了发送消息、图片预览、红包、长按菜单、地图位置、仿朋友圈等功能。
uni-app自定义仿微信/ios弹出框:https://ask.dcloud.net.cn/article/36440
三端效果图如下:
使用技术:
- 编辑器:HBuilder X
- 技术框架:uni-app + vue
- 状态管理:Vuex
- iconfont图标:阿里字体图标库
- 自定义导航栏 + 底部Tabbar
- 弹窗组件:uniPop(基于uni-app封装模态弹窗)
- 测试环境:H5端 + 小程序 + App端(三端均兼容)
引入公共部分组件及样式
import Vue from 'vue'
import App from './App'
// >>>引入css
import './assets/fonts/iconfont.css'
import './assets/css/reset.css'
import './assets/css/layout.css'
// >>>引入状态管理
import store from './store'
Vue.prototype.$store = store
// >>>引入公共组件
import headerBar from './components/header/header.vue'
import tabBar from './components/tabbar/tabbar.vue'
import popupWindow from './components/popupWindow.vue'
Vue.component('header-bar', headerBar)
Vue.component('tab-bar', tabBar)
Vue.component('popup-window', popupWindow)
// >>>引入uniPop弹窗组件
import uniPop from './components/uniPop/uniPop.vue'
Vue.component('uni-pop', uniPop)
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
uniapp朋友圈功能实现
/**
* @tpl 朋友圈模板
*/
<template>
<view class="flexbox flex_col">
<header-bar :isBack="true" title="朋友圈" :bgColor="{background: headerBarBackground}" transparent>
<text slot="back" class="uni_btnIco iconfont icon-arrL"></text>
<text slot="iconfont" class="uni_btnIco iconfont icon-publish mr_5" @tap="handlePublish"></text>
</header-bar>
<view class="uni__scrollview flex1">
<view class="uni-friendZone">
...
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
headerBarBackground: 'transparent'
}
},
onPageScroll : function(e) {
// console.log("滚动距离为:" + e.scrollTop);
this.headerBarBackground = 'rgba(65,168,99,'+e.scrollTop / 200+')'
},
methods: {
...
}
}
</script>
<style scoped>
</style>
uniapp使用scroll-view组件,通过判断聊天内容高度和scroll-view高度的大小设置滚动距离
<scroll-view id="scrollview" scroll-y="true" :scroll-top="scrollTop" style="height: 100%;">
<view class="uni-chatMsgCnt" id="msglistview">
<view class="msgitem">xxx</view>
<view class="msgitem">xxx</view>
<view class="msgitem">xxx</view>
...
</view>
</scroll-view>
export default {
data() {
return {
scrollTop: 0,
...
}
},
mounted() {
this.scrollToBottom()
},
updated() {
this.scrollToBottom()
},
methods: {
// 滚动至聊天底部
scrollToBottom(t) {
let that = this
let query = uni.createSelectorQuery()
query.select('#scrollview').boundingClientRect()
query.select('#msglistview').boundingClientRect()
query.exec((res) => {
// console.log(res)
if(res[1].height > res[0].height){
that.scrollTop = res[1].height - res[0].height
}
})
},
...
}
}
作者:xiaoyan2015
链接: https://segmentfault.com/a/1190000020636455
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
前几天给大家分享了一个uniapp自定义弹窗组件,今天给大家分享基于uniapp+vue+vuex等技术开发的仿微信界面App聊天室UniChatRoom,实现了发送消息、图片预览、红包、长按菜单、地图位置、仿朋友圈等功能。
uni-app自定义仿微信/ios弹出框:https://ask.dcloud.net.cn/article/36440
三端效果图如下:
使用技术:
- 编辑器:HBuilder X
- 技术框架:uni-app + vue
- 状态管理:Vuex
- iconfont图标:阿里字体图标库
- 自定义导航栏 + 底部Tabbar
- 弹窗组件:uniPop(基于uni-app封装模态弹窗)
- 测试环境:H5端 + 小程序 + App端(三端均兼容)
引入公共部分组件及样式
import Vue from 'vue'
import App from './App'
// >>>引入css
import './assets/fonts/iconfont.css'
import './assets/css/reset.css'
import './assets/css/layout.css'
// >>>引入状态管理
import store from './store'
Vue.prototype.$store = store
// >>>引入公共组件
import headerBar from './components/header/header.vue'
import tabBar from './components/tabbar/tabbar.vue'
import popupWindow from './components/popupWindow.vue'
Vue.component('header-bar', headerBar)
Vue.component('tab-bar', tabBar)
Vue.component('popup-window', popupWindow)
// >>>引入uniPop弹窗组件
import uniPop from './components/uniPop/uniPop.vue'
Vue.component('uni-pop', uniPop)
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
uniapp朋友圈功能实现
/**
* @tpl 朋友圈模板
*/
<template>
<view class="flexbox flex_col">
<header-bar :isBack="true" title="朋友圈" :bgColor="{background: headerBarBackground}" transparent>
<text slot="back" class="uni_btnIco iconfont icon-arrL"></text>
<text slot="iconfont" class="uni_btnIco iconfont icon-publish mr_5" @tap="handlePublish"></text>
</header-bar>
<view class="uni__scrollview flex1">
<view class="uni-friendZone">
...
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
headerBarBackground: 'transparent'
}
},
onPageScroll : function(e) {
// console.log("滚动距离为:" + e.scrollTop);
this.headerBarBackground = 'rgba(65,168,99,'+e.scrollTop / 200+')'
},
methods: {
...
}
}
</script>
<style scoped>
</style>
uniapp使用scroll-view组件,通过判断聊天内容高度和scroll-view高度的大小设置滚动距离
<scroll-view id="scrollview" scroll-y="true" :scroll-top="scrollTop" style="height: 100%;">
<view class="uni-chatMsgCnt" id="msglistview">
<view class="msgitem">xxx</view>
<view class="msgitem">xxx</view>
<view class="msgitem">xxx</view>
...
</view>
</scroll-view>
export default {
data() {
return {
scrollTop: 0,
...
}
},
mounted() {
this.scrollToBottom()
},
updated() {
this.scrollToBottom()
},
methods: {
// 滚动至聊天底部
scrollToBottom(t) {
let that = this
let query = uni.createSelectorQuery()
query.select('#scrollview').boundingClientRect()
query.select('#msglistview').boundingClientRect()
query.exec((res) => {
// console.log(res)
if(res[1].height > res[0].height){
that.scrollTop = res[1].height - res[0].height
}
})
},
...
}
}
作者:xiaoyan2015
链接: https://segmentfault.com/a/1190000020636455
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
安卓禁止弹出软件盘
最近在做一个项目,其中有个功能需要自动输入数据(扫码枪或者是IC读卡器)。用input每次都会弹出虚拟键盘,非常不方便,然后在论坛里面找到加上readonly就行,实测不行。最后发现扫码枪(部分)、IC读卡器是模拟键盘输入的,就想到了另外一个解决方案。
问题:禁止安卓输入框弹出软键盘
解决思路:用jQuery获取按键值,然后把按键值转换回按键,之后累加到自己想要的数位后可以直接填充到相应位置或操作。
代码如下:
card_id = "";
old_card_id = "";
$("body").on("keyup", function(event) {//获取键值
old_card_id = "";
switch(event.which){//键值转换为所按按键(下面为数字0-9键值)
case 48:
old_card_id = 0;
break;
case 49:
old_card_id = 1;
break;
case 50:
old_card_id = 2;
break;
case 51:
old_card_id = 3;
break;
case 52:
old_card_id = 4;
break;
case 53:
old_card_id = 5;
break;
case 54:
old_card_id = 6;
break;
case 55:
old_card_id = 7;
break;
case 56:
old_card_id = 8;
break;
case 57:
old_card_id = 9;
break;
default:
card_id = "";
document.onkeydown=null;
break;
};
card_id = card_id + old_card_id;//把转换后的按键累计成字符串
if (card_id.length == 10) {//需要的字符个数
console.log(card_id);
alert(card_id);
card_id = "";
}if(card_id.length > 10){//本处可不需要,因为我的IC读卡器是18位的,我只需要10位数字,所以这里我过滤了超过10位数字的字符串
card_id = "";
}
});
最后,也许代码有些乱或者冗余。各位需要的小伙伴看一下思路就行。
最近在做一个项目,其中有个功能需要自动输入数据(扫码枪或者是IC读卡器)。用input每次都会弹出虚拟键盘,非常不方便,然后在论坛里面找到加上readonly就行,实测不行。最后发现扫码枪(部分)、IC读卡器是模拟键盘输入的,就想到了另外一个解决方案。
问题:禁止安卓输入框弹出软键盘
解决思路:用jQuery获取按键值,然后把按键值转换回按键,之后累加到自己想要的数位后可以直接填充到相应位置或操作。
代码如下:
card_id = "";
old_card_id = "";
$("body").on("keyup", function(event) {//获取键值
old_card_id = "";
switch(event.which){//键值转换为所按按键(下面为数字0-9键值)
case 48:
old_card_id = 0;
break;
case 49:
old_card_id = 1;
break;
case 50:
old_card_id = 2;
break;
case 51:
old_card_id = 3;
break;
case 52:
old_card_id = 4;
break;
case 53:
old_card_id = 5;
break;
case 54:
old_card_id = 6;
break;
case 55:
old_card_id = 7;
break;
case 56:
old_card_id = 8;
break;
case 57:
old_card_id = 9;
break;
default:
card_id = "";
document.onkeydown=null;
break;
};
card_id = card_id + old_card_id;//把转换后的按键累计成字符串
if (card_id.length == 10) {//需要的字符个数
console.log(card_id);
alert(card_id);
card_id = "";
}if(card_id.length > 10){//本处可不需要,因为我的IC读卡器是18位的,我只需要10位数字,所以这里我过滤了超过10位数字的字符串
card_id = "";
}
});
最后,也许代码有些乱或者冗余。各位需要的小伙伴看一下思路就行。
收起阅读 »Android检查手机是否被root
论坛里找了好久,没找到demo,只好自己摸索,借鉴了一下,自己测试了一下是可以的,分享出来,欢迎补充
let isRoot = false;
const paths = ["/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su",
"/system/bin/failsafe/su", "/data/local/su"];
var File = plus.android.importClass("java.io.File");
for (let i = 0; i < paths.length; i++) {
let path = paths[i];
var fd = new File(path);
if(fd.exists()){
isRoot = true;
break;
}
}
论坛里找了好久,没找到demo,只好自己摸索,借鉴了一下,自己测试了一下是可以的,分享出来,欢迎补充
let isRoot = false;
const paths = ["/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su",
"/system/bin/failsafe/su", "/data/local/su"];
var File = plus.android.importClass("java.io.File");
for (let i = 0; i < paths.length; i++) {
let path = paths[i];
var fd = new File(path);
if(fd.exists()){
isRoot = true;
break;
}
}
收起阅读 »
HBuilderX初级安装使用教程
1. 安装HBuilderX
HBuilderX官网下载地址https://www.dcloud.io/hbuilderx.html
打开网站后,点击Download
按钮,弹窗如下:
- App开发版,包含大部分App开发插件。App开发,指的是手机应用开发。
- 如果您是
初学者
或开发前端
,建议下载 标准版 。后期如果学习App开发,可以到【插件安装】中,安装相关插件
-
压缩过程,不要中断。不要在压缩软件中打开exe。
-
解压完成后,点击HBuilderX.exe ,如下图
注意:如果您无法打开或启动报错,请参考此贴 windows启动问题排查
2. 初识HBuilderX
HBuilderX首次启动后,打开了一个HBuilderX自述文件.md
, 如下图:
HBuilderX自述文件.md
: 是一个markdown文件,什么是markdown呢?就是个文本语言。 有兴趣的同学,点此了解Markdown
有兴趣的同学,可以读一读这个文件。或者直接点击右上角的x,关闭此文件。
关闭后的页面窗口如下:
3. 创建项目,开始HX旅程
点击【新建项目】、或点击工具栏上第一个图标(就是带有红色+号)、或直接 Ctrl + N ,调出创建项目窗口
新建项目后,如下图:
4. 编写代码
如上图所示,HBuilderX拥有强大的代码助手提示,可以帮您少敲很多代码。
5. 查看代码效果
如下图所示,点击【预览】可以查看代码效果。
如果您首次点击【预览】,又没有安装【内置浏览器】,点击预览的时候,会提示您安装插件,点击确定即可。
6. 安装插件
点击菜单【工具】【插件安装】
7. 文件单击与文件双击
如上图,标红部分,显示效果不一样。
这是因为:单击预览文件,双击打开文件
1. 安装HBuilderX
HBuilderX官网下载地址https://www.dcloud.io/hbuilderx.html
打开网站后,点击Download
按钮,弹窗如下:
- App开发版,包含大部分App开发插件。App开发,指的是手机应用开发。
- 如果您是
初学者
或开发前端
,建议下载 标准版 。后期如果学习App开发,可以到【插件安装】中,安装相关插件
-
压缩过程,不要中断。不要在压缩软件中打开exe。
-
解压完成后,点击HBuilderX.exe ,如下图
注意:如果您无法打开或启动报错,请参考此贴 windows启动问题排查
2. 初识HBuilderX
HBuilderX首次启动后,打开了一个HBuilderX自述文件.md
, 如下图:
HBuilderX自述文件.md
: 是一个markdown文件,什么是markdown呢?就是个文本语言。 有兴趣的同学,点此了解Markdown
有兴趣的同学,可以读一读这个文件。或者直接点击右上角的x,关闭此文件。
关闭后的页面窗口如下:
3. 创建项目,开始HX旅程
点击【新建项目】、或点击工具栏上第一个图标(就是带有红色+号)、或直接 Ctrl + N ,调出创建项目窗口
新建项目后,如下图:
4. 编写代码
如上图所示,HBuilderX拥有强大的代码助手提示,可以帮您少敲很多代码。
5. 查看代码效果
如下图所示,点击【预览】可以查看代码效果。
如果您首次点击【预览】,又没有安装【内置浏览器】,点击预览的时候,会提示您安装插件,点击确定即可。
6. 安装插件
点击菜单【工具】【插件安装】
7. 文件单击与文件双击
如上图,标红部分,显示效果不一样。
这是因为:单击预览文件,双击打开文件
收起阅读 »关于MUI安卓方向急需改进的方面
安卓项目很多都需要依赖Jar包各方面的扩展,但是MUI这方面支持很不好,需要自定义增加sdk的话,就必须离线打包,处理起来很麻烦
安卓项目很多都需要依赖Jar包各方面的扩展,但是MUI这方面支持很不好,需要自定义增加sdk的话,就必须离线打包,处理起来很麻烦
在uni-app中对优博讯和新大陆安卓(Android)PDA的条码扫码广播监听(带示例附件)
我们在开发的时候需要获取优博讯PDA的条码扫码内容,根据前人的分享及自己找的一些资料整理示例代码如下,希望能帮助到有需要的人。为了避免刚入门的人无从下手,特增加了附件。
以下是示例,真正在用的时候,建议在app启动之后就开始监听,并通过全局事件来推送给需要的页面,而不是在每个页面都自己去监听,有利于代码的维护和提升性能。全局事件的监听和释放可参考我的另一个帖子:关于uni-app全局事件监听和释放监听的分享
另外优博讯的PDA需要在系统的:设置->扫描->Default->关闭(键盘方式输出) 才能使用广播监听。
onLoad() {
page = this;
this.title = "开始监听!";
var main = plus.android.runtimeMainActivity(); //获取activity
var context = plus.android.importClass('android.content.Context'); //上下文
var receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: doReceive
});
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
var Intent = plus.android.importClass('android.content.Intent');
var filter = new IntentFilter();
//针对优博讯安卓PDA-i6300A添加监听,其它优博讯的型号应该一样或类似
filter.addAction("android.intent.ACTION_DECODE_DATA"); //监听扫描
main.registerReceiver(receiver, filter); //注册监听
function doReceive(context, intent) {
//通过intent实例引入intent类,方便以后的‘.’操作
plus.android.importClass(intent);
//条码内容
var barcodeBytes = intent.getByteArrayExtra("barcode");
var barcode = byteToString(barcodeBytes);
//条码长度
var barcodeLength = intent.getIntExtra("length", 0);
//var myArray = new ArrayBuffer(0);
//条码类型
var barcodeTypeBytes = intent.getByteExtra("barcodeType", (0 | 0));
var barcodeType = byteToString(barcodeTypeBytes);
// uni.showModal({
// content: '条码:' + barcode + '\r\n长度:' + barcodeLength + '\r\n类型:' + barcodeType,
// showCancel: false
// });
page.title = barcode;
//console.log(barcode);
//main.unregisterReceiver(receiver);//取消监听
}
function byteToString(arr) {
if (typeof arr === 'string') {
return arr;
}
var str = '',
_arr = arr;
for (var i = 0; i < _arr.length; i++) {
var one = _arr[i].toString(2),
v = one.match(/^1+?(?=0)/);
if (v && one.length == 8) {
var bytesLength = v[0].length;
var store = _arr[i].toString(2).slice(7 - bytesLength);
for (var st = 1; st < bytesLength; st++) {
store += _arr[st + i].toString(2).slice(2);
}
str += String.fromCharCode(parseInt(store, 2));
i += bytesLength - 1;
} else {
str += String.fromCharCode(_arr[i]);
}
}
return str;
}
}
下面是新大陆PDA的扫码方式
//新大陆 智联天地 N7000R 获取方法
//#ifdef APP-PLUS
//this.title = "开始监听!";
var main = plus.android.runtimeMainActivity(); //获取activity
var context = plus.android.importClass('android.content.Context'); //上下文
var receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: doReceive
});
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
var Intent = plus.android.importClass('android.content.Intent');
var filter = new IntentFilter();
filter.addAction("com.android.server.scannerservice.broadcast"); //监听扫描
// filter.addAction("android.intent.extra.SCAN_DATA"); //监听扫描
main.registerReceiver(receiver, filter); //注册监听
function doReceive(context, intent) {
//通过intent实例引入intent类,方便以后的‘.’操作
plus.android.importClass(intent);
var barcodeBytes1 = intent.getStringExtra("scannerdata");
console.log(page.openCustmerScan);
if (page.openCustmerScan) {
page.cylinderRecovery.customerId = barcodeBytes1
} else {
page.setval(barcodeBytes1)
}
}
//#ifdef APP-PLUS
//this.title = "开始监听!";
var main = plus.android.runtimeMainActivity(); //获取activity
var context = plus.android.importClass('android.content.Context'); //上下文
var receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: doReceive
});
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
var Intent = plus.android.importClass('android.content.Intent');
var filter = new IntentFilter();
filter.addAction("com.android.server.scannerservice.broadcast"); //监听扫描
// filter.addAction("android.intent.extra.SCAN_DATA"); //监听扫描
main.registerReceiver(receiver, filter); //注册监听
function doReceive(context, intent) {
//通过intent实例引入intent类,方便以后的‘.’操作
plus.android.importClass(intent);
var barcodeBytes1 = intent.getStringExtra("scannerdata");
console.log(page.openCustmerScan);
if (page.openCustmerScan) {
page.cylinderRecovery.customerId = barcodeBytes1
} else {
page.setval(barcodeBytes1)
}
}
//#endif
//#endif
我们在开发的时候需要获取优博讯PDA的条码扫码内容,根据前人的分享及自己找的一些资料整理示例代码如下,希望能帮助到有需要的人。为了避免刚入门的人无从下手,特增加了附件。
以下是示例,真正在用的时候,建议在app启动之后就开始监听,并通过全局事件来推送给需要的页面,而不是在每个页面都自己去监听,有利于代码的维护和提升性能。全局事件的监听和释放可参考我的另一个帖子:关于uni-app全局事件监听和释放监听的分享
另外优博讯的PDA需要在系统的:设置->扫描->Default->关闭(键盘方式输出) 才能使用广播监听。
onLoad() {
page = this;
this.title = "开始监听!";
var main = plus.android.runtimeMainActivity(); //获取activity
var context = plus.android.importClass('android.content.Context'); //上下文
var receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: doReceive
});
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
var Intent = plus.android.importClass('android.content.Intent');
var filter = new IntentFilter();
//针对优博讯安卓PDA-i6300A添加监听,其它优博讯的型号应该一样或类似
filter.addAction("android.intent.ACTION_DECODE_DATA"); //监听扫描
main.registerReceiver(receiver, filter); //注册监听
function doReceive(context, intent) {
//通过intent实例引入intent类,方便以后的‘.’操作
plus.android.importClass(intent);
//条码内容
var barcodeBytes = intent.getByteArrayExtra("barcode");
var barcode = byteToString(barcodeBytes);
//条码长度
var barcodeLength = intent.getIntExtra("length", 0);
//var myArray = new ArrayBuffer(0);
//条码类型
var barcodeTypeBytes = intent.getByteExtra("barcodeType", (0 | 0));
var barcodeType = byteToString(barcodeTypeBytes);
// uni.showModal({
// content: '条码:' + barcode + '\r\n长度:' + barcodeLength + '\r\n类型:' + barcodeType,
// showCancel: false
// });
page.title = barcode;
//console.log(barcode);
//main.unregisterReceiver(receiver);//取消监听
}
function byteToString(arr) {
if (typeof arr === 'string') {
return arr;
}
var str = '',
_arr = arr;
for (var i = 0; i < _arr.length; i++) {
var one = _arr[i].toString(2),
v = one.match(/^1+?(?=0)/);
if (v && one.length == 8) {
var bytesLength = v[0].length;
var store = _arr[i].toString(2).slice(7 - bytesLength);
for (var st = 1; st < bytesLength; st++) {
store += _arr[st + i].toString(2).slice(2);
}
str += String.fromCharCode(parseInt(store, 2));
i += bytesLength - 1;
} else {
str += String.fromCharCode(_arr[i]);
}
}
return str;
}
}
下面是新大陆PDA的扫码方式
//新大陆 智联天地 N7000R 获取方法
//#ifdef APP-PLUS
//this.title = "开始监听!";
var main = plus.android.runtimeMainActivity(); //获取activity
var context = plus.android.importClass('android.content.Context'); //上下文
var receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: doReceive
});
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
var Intent = plus.android.importClass('android.content.Intent');
var filter = new IntentFilter();
filter.addAction("com.android.server.scannerservice.broadcast"); //监听扫描
// filter.addAction("android.intent.extra.SCAN_DATA"); //监听扫描
main.registerReceiver(receiver, filter); //注册监听
function doReceive(context, intent) {
//通过intent实例引入intent类,方便以后的‘.’操作
plus.android.importClass(intent);
var barcodeBytes1 = intent.getStringExtra("scannerdata");
console.log(page.openCustmerScan);
if (page.openCustmerScan) {
page.cylinderRecovery.customerId = barcodeBytes1
} else {
page.setval(barcodeBytes1)
}
}
//#ifdef APP-PLUS
//this.title = "开始监听!";
var main = plus.android.runtimeMainActivity(); //获取activity
var context = plus.android.importClass('android.content.Context'); //上下文
var receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: doReceive
});
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
var Intent = plus.android.importClass('android.content.Intent');
var filter = new IntentFilter();
filter.addAction("com.android.server.scannerservice.broadcast"); //监听扫描
// filter.addAction("android.intent.extra.SCAN_DATA"); //监听扫描
main.registerReceiver(receiver, filter); //注册监听
function doReceive(context, intent) {
//通过intent实例引入intent类,方便以后的‘.’操作
plus.android.importClass(intent);
var barcodeBytes1 = intent.getStringExtra("scannerdata");
console.log(page.openCustmerScan);
if (page.openCustmerScan) {
page.cylinderRecovery.customerId = barcodeBytes1
} else {
page.setval(barcodeBytes1)
}
}
//#endif
//#endif
收起阅读 »
关于uni-app全局事件监听和释放监听的分享
我们在使用uni-app开发的时候,需要在某个页面监听全局事件,并且需要再退出页面的时候释放监听,结果发现释放不了页面的监听,并且找了官方和网上的资料没有明确的解决示例。所以分享一下避免大家采坑。我的理解,之前之所以释放监听无效是因为绑定监听和释放监听并没有使用相同的方法。目前可行的解决方法是把要绑定的方法单独定义出来,这样在绑定和释放监听的时候就能确保都是相同的方法,就能真正释放监听的绑定。示例如下,有问题欢迎留言。
// 我的页面
onLoad(){
// 监听事件
uni.$on('scancode',this.callback) ;
},
onUnload() {
// 移除监听事件
uni.$off('scancode',this.callback);
},
methods: {
callback(data) {
todo.....
}
}
我们在使用uni-app开发的时候,需要在某个页面监听全局事件,并且需要再退出页面的时候释放监听,结果发现释放不了页面的监听,并且找了官方和网上的资料没有明确的解决示例。所以分享一下避免大家采坑。我的理解,之前之所以释放监听无效是因为绑定监听和释放监听并没有使用相同的方法。目前可行的解决方法是把要绑定的方法单独定义出来,这样在绑定和释放监听的时候就能确保都是相同的方法,就能真正释放监听的绑定。示例如下,有问题欢迎留言。
// 我的页面
onLoad(){
// 监听事件
uni.$on('scancode',this.callback) ;
},
onUnload() {
// 移除监听事件
uni.$off('scancode',this.callback);
},
methods: {
callback(data) {
todo.....
}
}
收起阅读 »
解决Android8.0及以上版本系统通知消息无法显示问题
新手代码写的有点乱。。 之前借鉴了几位大神的代码,在8.0之前非常好用,最近需要投标突然发现自己手机收不到推送消息了,折磨了我一天啊。。
话不多说,放代码,希望对大家有用!!!!
var mNotification;
var SystemVersion = plus.os.version;
var firstVersionNumber = Number(SystemVersion.split('.')[0]);
var main = plus.android.runtimeMainActivity();
var Context = plus.android.importClass("android.content.Context");
var Noti = plus.android.importClass("android.app.Notification");
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 pendingIntent = PendingIntent.getActivity(main, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
var r = plus.android.importClass("android.R");
if (firstVersionNumber>=8) {
Notification = plus.android.importClass("android.support.v4.app.NotificationCompat");
} else {
Notification = plus.android.importClass("android.app.Notification");
}
if(firstVersionNumber>=8){//判断当前系统版本在8.0及以上
var NotificationChannel = plus.android.importClass('android.app.NotificationChannel');
var channel = new NotificationChannel("s"+ NotifyID, "1", NotificationManager.IMPORTANCE_HIGH);
nm.createNotificationChannel(channel);
mNotification = new Notification.Builder(main,"s" +NotifyID);
}else{
//设为true代表常驻状态栏
//this.mNotificationBuild.setNumber(defaultNumber)
mNotification = new Notification.Builder(main);
}
mNotification.setContentTitle("xxxxx")
mNotification.setContentText(str);
mNotification.setSubText(str1);
mNotification.setSmallIcon(17301620);
mNotification.setDefaults(Noti.DEFAULT_VIBRATE);//声音、闪灯、震动效果,可叠加
mNotification.setPriority(Noti.PRIORITY_DEFAULT);//通知优先级
mNotification.flags=Notification.FLAG_ONLY_ALERT_ONCE;//发起通知时震动
mNotification.setContentIntent(pendingIntent);
var mNb = mNotification.build();
if(firstVersionNumber>=8){//判断当前系统版本在8.0及以上
nm.notify("s"+ NotifyID,NotifyID, mNb);
}else{
nm.notify(NotifyID, mNb);
}
void plus.device.beep(5);
plus.device.vibrate(300);
NotifyID ;
新手代码写的有点乱。。 之前借鉴了几位大神的代码,在8.0之前非常好用,最近需要投标突然发现自己手机收不到推送消息了,折磨了我一天啊。。
话不多说,放代码,希望对大家有用!!!!
var mNotification;
var SystemVersion = plus.os.version;
var firstVersionNumber = Number(SystemVersion.split('.')[0]);
var main = plus.android.runtimeMainActivity();
var Context = plus.android.importClass("android.content.Context");
var Noti = plus.android.importClass("android.app.Notification");
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 pendingIntent = PendingIntent.getActivity(main, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
var r = plus.android.importClass("android.R");
if (firstVersionNumber>=8) {
Notification = plus.android.importClass("android.support.v4.app.NotificationCompat");
} else {
Notification = plus.android.importClass("android.app.Notification");
}
if(firstVersionNumber>=8){//判断当前系统版本在8.0及以上
var NotificationChannel = plus.android.importClass('android.app.NotificationChannel');
var channel = new NotificationChannel("s"+ NotifyID, "1", NotificationManager.IMPORTANCE_HIGH);
nm.createNotificationChannel(channel);
mNotification = new Notification.Builder(main,"s" +NotifyID);
}else{
//设为true代表常驻状态栏
//this.mNotificationBuild.setNumber(defaultNumber)
mNotification = new Notification.Builder(main);
}
mNotification.setContentTitle("xxxxx")
mNotification.setContentText(str);
mNotification.setSubText(str1);
mNotification.setSmallIcon(17301620);
mNotification.setDefaults(Noti.DEFAULT_VIBRATE);//声音、闪灯、震动效果,可叠加
mNotification.setPriority(Noti.PRIORITY_DEFAULT);//通知优先级
mNotification.flags=Notification.FLAG_ONLY_ALERT_ONCE;//发起通知时震动
mNotification.setContentIntent(pendingIntent);
var mNb = mNotification.build();
if(firstVersionNumber>=8){//判断当前系统版本在8.0及以上
nm.notify("s"+ NotifyID,NotifyID, mNb);
}else{
nm.notify(NotifyID, mNb);
}
void plus.device.beep(5);
plus.device.vibrate(300);
NotifyID ;
收起阅读 »
uni-popup滚动时,父组件跟随滚动
定义CSS
.wos-scroll-no{
height:98vh;
overflow-y: hidden;
}
.wos-scroll-yes{
height:auto;
overflow-y:auto;
}
父组件绑定data
<view :class="wosScroll">
...
<view>
...
data() {
return {
wosScroll:"wos-scroll-yes",
...
修改uni-popup.vue。找到以下部分加入
open () {
this.$parent.wosScroll = 'wos-scroll-no' //新加入的 ++++++
this.$emit('change', {
show: true
})
this.showPopup = true
this.$nextTick(() => {
setTimeout(() => {
this.ani = '' + this.type
}, 30)
})
},
close (type) {
this.$parent.wosScroll = 'wos-scroll-yes' //新加入的 +++++++++
if (!this.maskClick && type) return
this.$emit('change', {
show: false
})
this.ani = ''
this.$nextTick(() => {
setTimeout(() => {
this.showPopup = false
}, 300)
})
}
定义CSS
.wos-scroll-no{
height:98vh;
overflow-y: hidden;
}
.wos-scroll-yes{
height:auto;
overflow-y:auto;
}
父组件绑定data
<view :class="wosScroll">
...
<view>
...
data() {
return {
wosScroll:"wos-scroll-yes",
...
修改uni-popup.vue。找到以下部分加入
open () {
this.$parent.wosScroll = 'wos-scroll-no' //新加入的 ++++++
this.$emit('change', {
show: true
})
this.showPopup = true
this.$nextTick(() => {
setTimeout(() => {
this.ani = '' + this.type
}, 30)
})
},
close (type) {
this.$parent.wosScroll = 'wos-scroll-yes' //新加入的 +++++++++
if (!this.maskClick && type) return
this.$emit('change', {
show: false
})
this.ani = ''
this.$nextTick(() => {
setTimeout(() => {
this.showPopup = false
}, 300)
})
}
收起阅读 »
Mac: 关于HBuilderX在 macOS Catalina 10.15新系统上的运行说明
.
10月8日凌晨, 苹果正式推送了macOS Catalina 10.15系统。
操作系统主要更新了权限相关方面,为了大家更好使用,小编汇总了一下可能遇到的问题。
.
问题:项目管理器:以前的项目无法展开了,或文件无法保存了
原因: mac 10.15, 访问文稿
目录,需要授权
解决方案:
- 打开【设置App】-->【安全性与隐私】--> 【隐私】--> 【文件与文件夹】
- 找到HBuilderX,勾选复选框
更新:10月16日起,HBuilderX 2.3.3已经通过了苹果的认证,默认即可获得授权,无需再进行额外设置。
.
10月8日凌晨, 苹果正式推送了macOS Catalina 10.15系统。
操作系统主要更新了权限相关方面,为了大家更好使用,小编汇总了一下可能遇到的问题。
.
问题:项目管理器:以前的项目无法展开了,或文件无法保存了
原因: mac 10.15, 访问文稿
目录,需要授权
解决方案:
- 打开【设置App】-->【安全性与隐私】--> 【隐私】--> 【文件与文件夹】
- 找到HBuilderX,勾选复选框
更新:10月16日起,HBuilderX 2.3.3已经通过了苹果的认证,默认即可获得授权,无需再进行额外设置。
收起阅读 »