
安卓-电池优化、白名单
从 Android 6.0 开始,系统为了省电增加了休眠模式,系统待机一段时间后,会杀死后台正在运行的进程。但系统会有一个后台运行白名单,白名单里的应用将不会受到影响,在原生系统下,通过「设置」 - 「电池」 - 「电池优化」 - 「未优化应用」,可以看到这个白名单。
从网上查了些资料,找到:android应用申请加入电池优化白名单
根据上面资料转native.js,上代码。
-
① 添加权限
在manifest.json源码视图中添加<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />,就加在那一堆permissions中。 -
② 判断我们的应用是否在白名单中
// 白名单 var main = plus.android.runtimeMainActivity(); var packName = main.getPackageName(); var Context = plus.android.importClass("android.content.Context"); var PowerManager = plus.android.importClass("android.os.PowerManager"); // 获取电源类 var pm = main.getSystemService(Context.POWER_SERVICE); console.log('是否在白名单:',pm.isIgnoringBatteryOptimizations(packName)); //是否白名单 let whiteList = pm.isIgnoringBatteryOptimizations(packName);
-
③ 调起服务
try{ var Uri = plus.android.importClass("android.net.Uri"); var Settings = plus.android.importClass("android.provider.Settings"); var packageURI = Uri.parse("package:" + packName); var intents = plus.android.newObject("android.content.Intent", Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,packageURI); // 电池 main.startActivity(intents); }catch{ // console.log('调起失败') }
-
④ 发行-云打包测试
测试多次HbuliderX里是调不起来,打包后才能出来
总结:自己测试-打开应用,然后锁屏(半小时为例)
华为():仍然可以运行,收到消息
小米():中断,除了设置中的电池优化,还有应用详情的“省电策略”,需要再调试
从 Android 6.0 开始,系统为了省电增加了休眠模式,系统待机一段时间后,会杀死后台正在运行的进程。但系统会有一个后台运行白名单,白名单里的应用将不会受到影响,在原生系统下,通过「设置」 - 「电池」 - 「电池优化」 - 「未优化应用」,可以看到这个白名单。
从网上查了些资料,找到:android应用申请加入电池优化白名单
根据上面资料转native.js,上代码。
-
① 添加权限
在manifest.json源码视图中添加<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />,就加在那一堆permissions中。 -
② 判断我们的应用是否在白名单中
// 白名单 var main = plus.android.runtimeMainActivity(); var packName = main.getPackageName(); var Context = plus.android.importClass("android.content.Context"); var PowerManager = plus.android.importClass("android.os.PowerManager"); // 获取电源类 var pm = main.getSystemService(Context.POWER_SERVICE); console.log('是否在白名单:',pm.isIgnoringBatteryOptimizations(packName)); //是否白名单 let whiteList = pm.isIgnoringBatteryOptimizations(packName);
-
③ 调起服务
try{ var Uri = plus.android.importClass("android.net.Uri"); var Settings = plus.android.importClass("android.provider.Settings"); var packageURI = Uri.parse("package:" + packName); var intents = plus.android.newObject("android.content.Intent", Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,packageURI); // 电池 main.startActivity(intents); }catch{ // console.log('调起失败') }
-
④ 发行-云打包测试
测试多次HbuliderX里是调不起来,打包后才能出来
总结:自己测试-打开应用,然后锁屏(半小时为例)
华为():仍然可以运行,收到消息
小米():中断,除了设置中的电池优化,还有应用详情的“省电策略”,需要再调试

NFC 读取指定扇区,写入指定扇区
<script>
let Context = plus.android.importClass('android.content.Context');
let NfcManager = plus.android.importClass('android.nfc.NfcManager');
let NfcAdapter = plus.android.importClass('android.nfc.NfcAdapter');
let Settings = plus.android.importClass('android.provider.Settings');
let Intent = plus.android.importClass('android.content.Intent');
let Parcelable = plus.android.importClass('android.os.Parcelable');
let PendingIntent = plus.android.importClass('android.app.PendingIntent');
let IntentFilter = plus.android.importClass('android.content.IntentFilter');
let NdefRecord = plus.android.importClass('android.nfc.NdefRecord');
let NdefMessage = plus.android.importClass('android.nfc.NdefMessage');
let Tag = plus.android.importClass('android.nfc.Tag');
let MifareClassic = plus.android.importClass('android.nfc.tech.MifareClassic');
let invoke = plus.android.invoke;
export default {
data() {
return {
sector: 1,
keyType: 'A',
keyVal: 'FFFFFFFFFFFF', //'E58583E69C94', //'FFFFFFFFFFFF',
ICUID: '',
ICData: 'IC卡扇区数据:',
ICERROR: '',
nfcAdapter: null,
main: null,
intent: null,
IntervalId: null,
techListsArray: [
['android.nfc.tech.IsoDep'],
['android.nfc.tech.NfcA'],
['android.nfc.tech.NfcB'],
['android.nfc.tech.NfcF'],
['android.nfc.tech.NfcV'],
['android.nfc.tech.Ndef'],
['android.nfc.tech.NdefFormatable'],
['android.nfc.tech.MifareClassic'],
['android.nfc.tech.MifareUltralight']
]
};
},
created() {
this.nfcinit();
},
beforeDestroy() {
this.nfcclose();
},
methods: {
nfcinit() {
this.main = plus.android.runtimeMainActivity();
var nfchManager = this.main.getSystemService(Context.NFC_SERVICE);
var nfcAdapter = nfchManager.getDefaultAdapter();
if (!nfcAdapter.isEnabled()) {
this.intent = new Intent(Settings.ACTION_NFC_SETTINGS);
this.main.startActivity(this.intent);
}
var intent = new Intent(this.main, this.main.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
var pendingIntent = PendingIntent.getActivity(this.main, 0, intent, 0);
var ndef = new IntentFilter('android.nfc.action.TECH_DISCOVERED');
ndef.addDataType('*/*');
var intentFiltersArray = [ndef];
nfcAdapter.enableForegroundDispatch(this.main, pendingIntent, intentFiltersArray, this.techListsArray);
this.nfcAdapter = nfcAdapter;
},
nfcclose() {
if (this.nfcAdapter) this.nfcAdapter.disableForegroundDispatch(this.main);
this.nfcAdapter = null;
clearInterval(this.IntervalId);
},
handle_nfc_data(obj) {
var intent = this.main.getIntent();
if (intent.getAction() == 'android.nfc.action.TECH_DISCOVERED') {
clearInterval(this.IntervalId);
this.readData(intent, obj);
}
},
// 读扇区 请参考 https://ask.dcloud.net.cn/article/35593
readData(intent, obj) {
var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
var techList = tag.getTechList();
var bisMfc = false;
for (var i = 0; i < techList.length; i++) {
if (techList[i].indexOf('MifareClassic') >= 0) {
bisMfc = true;
break;
}
}
if (!bisMfc) {
this.ICERROR = '卡片类型错误!';
return;
}
var mfc = MifareClassic.get(tag);
if (!mfc) {
this.ICERROR = '卡片获取错误!';
return;
}
mfc.setTimeout(3000);
if (!mfc.isConnected()) {
try {
invoke(mfc, 'connect');
} catch (e) {
this.ICERROR = '卡片连接错误!';
return;
}
}
try {
this.ICUID = this.ByteArrayToHexString(tag.getId());
var cmdBytes = this.HexStringToByteArray(this.keyVal);
var auth = false;
//使用密钥A对扇区进行身份验证。
if (this.keyType == 'A') {
auth = invoke(mfc, 'authenticateSectorWithKeyA', parseInt(this.sector), cmdBytes);
} else {
//使用密钥B对扇区进行身份验证。
auth = invoke(mfc, 'authenticateSectorWithKeyB', parseInt(this.sector), cmdBytes);
}
if (!auth) {
this.ICERROR = '扇区验证失败';
return;
}
var sectorData = [];
var tmpRet;
this.ICData = 'IC卡扇区数据>>';
// 调用 MifareClassic 读指定块 返回的是字节数组
// 若需读取扇区中的所有块 请参考 https://ask.dcloud.net.cn/article/35593
tmpRet = invoke(mfc, 'readBlock', 5);
// 此项目写入的时候有中文,用网上的字节转字符串 会出现解析乱码
// 所以此处导入 java String 类
var String = plus.android.importClass('java.lang.String');
// 将自己数组转换成java 字符串
var str = new String(tmpRet);
// 调用java String 类的 concat 方法 拼接一个空的字符串,不然输出str 是一个类名 plus.android.java.lang.String
obj.success(str.trim());
this.ICERROR = '读卡完成';
} catch (e) {
this.ICERROR = e.message;
obj.fail(e);
} finally {
mfc.close();
}
},
readcard(obj) {
var that = this;
(this.ICUID = ''),
(this.ICData = ''),
(this.ICERROR = ''),
(this.IntervalId = setInterval(function() {
that.handle_nfc_data(obj);
}, 1000));
},
//
handle_nfc_write(sectorIndex, text, obj) {
var intent = this.main.getIntent();
if (intent.getAction() == 'android.nfc.action.TECH_DISCOVERED') {
this.write(intent, sectorIndex, text, obj);
}
},
//sectorIndex 扇区
// text 要写入的内容
// obj callback()
write(intent, sectorIndex, text, obj) {
try {
// 将要写入的内容转成字节数组
var textBytes = plus.android.invoke(text, 'getBytes', 'utf-8');
// android api参考地址
// https://developer.android.google.cn/reference/android/nfc/tech/MifareClassic?hl=en#writeBlock(int,%20byte[])
// 写入16个字节的块。不够补0
for (var i = textBytes.length; i < 16; i++) {
textBytes.push(0);
}
var textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, plus.android.invoke('text/plain', 'getBytes'), plus.android.invoke('', 'getBytes'), textBytes);
var message = new NdefMessage([textRecord]);
var NdefFormatable = plus.android.importClass('android.nfc.tech.NdefFormatable');
var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
var mfc = MifareClassic.get(tag);
if (mfc != null) {
mfc.connect();
// 默认密钥
var cmdBytes = this.HexStringToByteArray('FFFFFFFFFFFF');
// 使用密钥A对扇区进行身份验证。
let auth = mfc.authenticateSectorWithKeyA(sectorIndex, cmdBytes);
// var pass = 'E58583E69C94';
// var password =this.HexStringToByteArray(pass);
// for (var i = password.length; i < 16; i++) {
// password.push(0);
// }
if (auth) {
//返回给定扇区的第一个块。
let block = mfc.sectorToBlock(sectorIndex);
// 写入块 我们项目写在 扇区1,第2块
mfc.writeBlock(block + 1, textBytes);
obj.success('写卡成功');
//写入密钥
//mfc.writeBlock(block + 3, password);
mfc.close();
} else {
obj.fail('认证失败');
}
return;
}
} catch (e) {
obj.fail(e);
console.log('error=' + e);
}
},
ByteArrayToHexString: function(inarray) {
var i, j, inn;
var hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
var out = '';
for (j = 0; j < inarray.length; ++j) {
inn = inarray[j] & 0xff;
i = (inn >>> 4) & 0x0f;
out += hex[i];
i = inn & 0x0f;
out += hex[i];
}
return out;
},
HexStringToByteArray: function(instr) {
var hexA = new Array();
var pos = 0;
var len = instr.length / 2;
for (var i = 0; i < len; i++) {
var s = instr.substr(pos, 2);
var v = parseInt(s, 16);
if (v >= 128) v = v - 256;
hexA.push(v);
pos += 2;
}
return hexA;
}
}
};
</script>
<style></style>
<script>
let Context = plus.android.importClass('android.content.Context');
let NfcManager = plus.android.importClass('android.nfc.NfcManager');
let NfcAdapter = plus.android.importClass('android.nfc.NfcAdapter');
let Settings = plus.android.importClass('android.provider.Settings');
let Intent = plus.android.importClass('android.content.Intent');
let Parcelable = plus.android.importClass('android.os.Parcelable');
let PendingIntent = plus.android.importClass('android.app.PendingIntent');
let IntentFilter = plus.android.importClass('android.content.IntentFilter');
let NdefRecord = plus.android.importClass('android.nfc.NdefRecord');
let NdefMessage = plus.android.importClass('android.nfc.NdefMessage');
let Tag = plus.android.importClass('android.nfc.Tag');
let MifareClassic = plus.android.importClass('android.nfc.tech.MifareClassic');
let invoke = plus.android.invoke;
export default {
data() {
return {
sector: 1,
keyType: 'A',
keyVal: 'FFFFFFFFFFFF', //'E58583E69C94', //'FFFFFFFFFFFF',
ICUID: '',
ICData: 'IC卡扇区数据:',
ICERROR: '',
nfcAdapter: null,
main: null,
intent: null,
IntervalId: null,
techListsArray: [
['android.nfc.tech.IsoDep'],
['android.nfc.tech.NfcA'],
['android.nfc.tech.NfcB'],
['android.nfc.tech.NfcF'],
['android.nfc.tech.NfcV'],
['android.nfc.tech.Ndef'],
['android.nfc.tech.NdefFormatable'],
['android.nfc.tech.MifareClassic'],
['android.nfc.tech.MifareUltralight']
]
};
},
created() {
this.nfcinit();
},
beforeDestroy() {
this.nfcclose();
},
methods: {
nfcinit() {
this.main = plus.android.runtimeMainActivity();
var nfchManager = this.main.getSystemService(Context.NFC_SERVICE);
var nfcAdapter = nfchManager.getDefaultAdapter();
if (!nfcAdapter.isEnabled()) {
this.intent = new Intent(Settings.ACTION_NFC_SETTINGS);
this.main.startActivity(this.intent);
}
var intent = new Intent(this.main, this.main.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
var pendingIntent = PendingIntent.getActivity(this.main, 0, intent, 0);
var ndef = new IntentFilter('android.nfc.action.TECH_DISCOVERED');
ndef.addDataType('*/*');
var intentFiltersArray = [ndef];
nfcAdapter.enableForegroundDispatch(this.main, pendingIntent, intentFiltersArray, this.techListsArray);
this.nfcAdapter = nfcAdapter;
},
nfcclose() {
if (this.nfcAdapter) this.nfcAdapter.disableForegroundDispatch(this.main);
this.nfcAdapter = null;
clearInterval(this.IntervalId);
},
handle_nfc_data(obj) {
var intent = this.main.getIntent();
if (intent.getAction() == 'android.nfc.action.TECH_DISCOVERED') {
clearInterval(this.IntervalId);
this.readData(intent, obj);
}
},
// 读扇区 请参考 https://ask.dcloud.net.cn/article/35593
readData(intent, obj) {
var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
var techList = tag.getTechList();
var bisMfc = false;
for (var i = 0; i < techList.length; i++) {
if (techList[i].indexOf('MifareClassic') >= 0) {
bisMfc = true;
break;
}
}
if (!bisMfc) {
this.ICERROR = '卡片类型错误!';
return;
}
var mfc = MifareClassic.get(tag);
if (!mfc) {
this.ICERROR = '卡片获取错误!';
return;
}
mfc.setTimeout(3000);
if (!mfc.isConnected()) {
try {
invoke(mfc, 'connect');
} catch (e) {
this.ICERROR = '卡片连接错误!';
return;
}
}
try {
this.ICUID = this.ByteArrayToHexString(tag.getId());
var cmdBytes = this.HexStringToByteArray(this.keyVal);
var auth = false;
//使用密钥A对扇区进行身份验证。
if (this.keyType == 'A') {
auth = invoke(mfc, 'authenticateSectorWithKeyA', parseInt(this.sector), cmdBytes);
} else {
//使用密钥B对扇区进行身份验证。
auth = invoke(mfc, 'authenticateSectorWithKeyB', parseInt(this.sector), cmdBytes);
}
if (!auth) {
this.ICERROR = '扇区验证失败';
return;
}
var sectorData = [];
var tmpRet;
this.ICData = 'IC卡扇区数据>>';
// 调用 MifareClassic 读指定块 返回的是字节数组
// 若需读取扇区中的所有块 请参考 https://ask.dcloud.net.cn/article/35593
tmpRet = invoke(mfc, 'readBlock', 5);
// 此项目写入的时候有中文,用网上的字节转字符串 会出现解析乱码
// 所以此处导入 java String 类
var String = plus.android.importClass('java.lang.String');
// 将自己数组转换成java 字符串
var str = new String(tmpRet);
// 调用java String 类的 concat 方法 拼接一个空的字符串,不然输出str 是一个类名 plus.android.java.lang.String
obj.success(str.trim());
this.ICERROR = '读卡完成';
} catch (e) {
this.ICERROR = e.message;
obj.fail(e);
} finally {
mfc.close();
}
},
readcard(obj) {
var that = this;
(this.ICUID = ''),
(this.ICData = ''),
(this.ICERROR = ''),
(this.IntervalId = setInterval(function() {
that.handle_nfc_data(obj);
}, 1000));
},
//
handle_nfc_write(sectorIndex, text, obj) {
var intent = this.main.getIntent();
if (intent.getAction() == 'android.nfc.action.TECH_DISCOVERED') {
this.write(intent, sectorIndex, text, obj);
}
},
//sectorIndex 扇区
// text 要写入的内容
// obj callback()
write(intent, sectorIndex, text, obj) {
try {
// 将要写入的内容转成字节数组
var textBytes = plus.android.invoke(text, 'getBytes', 'utf-8');
// android api参考地址
// https://developer.android.google.cn/reference/android/nfc/tech/MifareClassic?hl=en#writeBlock(int,%20byte[])
// 写入16个字节的块。不够补0
for (var i = textBytes.length; i < 16; i++) {
textBytes.push(0);
}
var textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, plus.android.invoke('text/plain', 'getBytes'), plus.android.invoke('', 'getBytes'), textBytes);
var message = new NdefMessage([textRecord]);
var NdefFormatable = plus.android.importClass('android.nfc.tech.NdefFormatable');
var tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
var mfc = MifareClassic.get(tag);
if (mfc != null) {
mfc.connect();
// 默认密钥
var cmdBytes = this.HexStringToByteArray('FFFFFFFFFFFF');
// 使用密钥A对扇区进行身份验证。
let auth = mfc.authenticateSectorWithKeyA(sectorIndex, cmdBytes);
// var pass = 'E58583E69C94';
// var password =this.HexStringToByteArray(pass);
// for (var i = password.length; i < 16; i++) {
// password.push(0);
// }
if (auth) {
//返回给定扇区的第一个块。
let block = mfc.sectorToBlock(sectorIndex);
// 写入块 我们项目写在 扇区1,第2块
mfc.writeBlock(block + 1, textBytes);
obj.success('写卡成功');
//写入密钥
//mfc.writeBlock(block + 3, password);
mfc.close();
} else {
obj.fail('认证失败');
}
return;
}
} catch (e) {
obj.fail(e);
console.log('error=' + e);
}
},
ByteArrayToHexString: function(inarray) {
var i, j, inn;
var hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
var out = '';
for (j = 0; j < inarray.length; ++j) {
inn = inarray[j] & 0xff;
i = (inn >>> 4) & 0x0f;
out += hex[i];
i = inn & 0x0f;
out += hex[i];
}
return out;
},
HexStringToByteArray: function(instr) {
var hexA = new Array();
var pos = 0;
var len = instr.length / 2;
for (var i = 0; i < len; i++) {
var s = instr.substr(pos, 2);
var v = parseInt(s, 16);
if (v >= 128) v = v - 256;
hexA.push(v);
pos += 2;
}
return hexA;
}
}
};
</script>
<style></style>
收起阅读 »

uniCloud admin:token不合法,请重新登录,30201,解决方案
框架:uniCloud admin
问题:在调用增删改查功能时,老遇到token不合法的问题
原因:uni-id验证token时,默认开启了绑定设备
解决:取消绑定设备bindTokenToDevice=false
/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/node_modules/uni-config-center/uni-id/config.json

框架:uniCloud admin
问题:在调用增删改查功能时,老遇到token不合法的问题
原因:uni-id验证token时,默认开启了绑定设备
解决:取消绑定设备bindTokenToDevice=false
/uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/node_modules/uni-config-center/uni-id/config.json

给Huilderx 一点使用建议
希望官方能把scss、less插件纳入到核心插件里面去,直接点击安装,因为使用频率比较高,而且这两款插件大部分开发者也在用。一点小小意见,望采纳
希望官方能把scss、less插件纳入到核心插件里面去,直接点击安装,因为使用频率比较高,而且这两款插件大部分开发者也在用。一点小小意见,望采纳

midButton的设计是不是没考虑过正常的使用情况?
一般的正常用户,在看到tabbar上有按钮时,是不是会下意识的觉得这个按钮可以点击?然而实际上,这个按钮只有在app环境下才能被绑定上事件。
这种设计,是不是有点没走脑子?既然是全平台兼容的按钮,为啥只有app上能点击?做个点击功能很难吗?
一般的正常用户,在看到tabbar上有按钮时,是不是会下意识的觉得这个按钮可以点击?然而实际上,这个按钮只有在app环境下才能被绑定上事件。
这种设计,是不是有点没走脑子?既然是全平台兼容的按钮,为啥只有app上能点击?做个点击功能很难吗?

Uniapp移动端混合开发工程师(坐标合肥)
Uniapp移动端混合开发工程师
岗位职责:
- 主要负责公司APP产品、小程序、H5相关移动端开发;
- 具备前端性能优化经验;
- 根据需求认真完成相关功能的界面搭建和业务编码任务;
- 良好的沟通与表达能力,思路清晰,有强烈的责任心。
任职要求:
1、计算机相关专业大专及以上学历,1年以上开发经验;
2、熟练使用hbuilderx、uni-app,有参与使用uni-app开发移动端或小程序经验者优先。
3、精通JavaScript、HTML5、和CSS3编程语言,熟悉常见的UI(如:ElementUI、Ant Design Vue等)
4、熟悉ES5和ES6语法和常用的web前端框架,如Vue、Angular等
5、有Saas系统或者多商户商城开发经验的优先
6、规范的代码风格、追求较高的代码品味
有意者请跟帖留言。
Uniapp移动端混合开发工程师
岗位职责:
- 主要负责公司APP产品、小程序、H5相关移动端开发;
- 具备前端性能优化经验;
- 根据需求认真完成相关功能的界面搭建和业务编码任务;
- 良好的沟通与表达能力,思路清晰,有强烈的责任心。
任职要求:
1、计算机相关专业大专及以上学历,1年以上开发经验;
2、熟练使用hbuilderx、uni-app,有参与使用uni-app开发移动端或小程序经验者优先。
3、精通JavaScript、HTML5、和CSS3编程语言,熟悉常见的UI(如:ElementUI、Ant Design Vue等)
4、熟悉ES5和ES6语法和常用的web前端框架,如Vue、Angular等
5、有Saas系统或者多商户商城开发经验的优先
6、规范的代码风格、追求较高的代码品味
有意者请跟帖留言。
收起阅读 »
开通uniCloud(阿里云版)云服务空间和开通前端网页托管
1 开通uniCloud
开通uniCloud的地址为:https://unicloud.dcloud.net.cn/;
注意: 按照国家法律要求和阿里云的要求,使用uniCloud服务,需要先实名认证
3.2. 新建阿里云服务空间
3.3 开通前端网页托管
注意:前端网页托管服务初始化,需要 1-3 分钟,请耐心等待
1 开通uniCloud
开通uniCloud的地址为:https://unicloud.dcloud.net.cn/;
注意: 按照国家法律要求和阿里云的要求,使用uniCloud服务,需要先实名认证
3.2. 新建阿里云服务空间
3.3 开通前端网页托管
注意:前端网页托管服务初始化,需要 1-3 分钟,请耐心等待
收起阅读 »

获取网络流量(ios)
获取网络流量(ios):https://ext.dcloud.net.cn/plugin?id=4685
获取网络流量(ios):https://ext.dcloud.net.cn/plugin?id=4685

uniapp-图片转base64(支付宝小程序内可用)
最近遇到了一个新需求,使用uniapp开发并打包成小程序在uniapp上运行,页面内涉及到一个图片上传的功能,原先微信小程序内的图片上传对接挺简单的,类似的尝试了一下走文档,发现后端解析图片部分存在问题,经过一番讨论,后端决定让前端将图片信息转成base64再传给接口。
此时问题来了,uniapp内的图片信息转换插件均不支持在支付宝小程序内调用,如不信,可以亲身尝试一波,会提示无权限调用接口。
亲测无效的一个插件
image-tools
//官方下载后,支付宝小程序真机上测试,直接报错,报错信息为无权限调用该接口
话不多说,直接上可用的实现代码。
页面标签部分:
<view>
<canvas id="myCanvas" class="canvas-view" :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"></canvas>
</view>
逻辑部分:
export default {
data() {
return {
canvasWidth: 200, //绘制canvas的默认宽度
canvasHeight: 200, //绘制canvas的默认高度
base64: ''
};
},
methods: {
//选择上传图片
chooseUploadImg() {
const ctx = uni.createCanvasContext('myCanvas');
const that = this;
uni.chooseImage({
count: 1,
success: res => {
uni.getImageInfo({
src: res.tempFilePaths[0],
success: function(image) {
//需要动态更新canvas标签的高宽度
that.canvasWidth = image.width;
that.canvasHeight = image.height;
ctx.drawImage(res.tempFilePaths[0], 0, 0, image.width, image.height);
ctx.draw(false, () => {
ctx.toDataURL({}).then(dataURL => {
const base64Str = dataURL.replace('data:image/png;base64,', '');
// doSomething
});
});
}
});
},
fail: e => {
console.log('choose img fail');
}
});
}
}
};
</script>
样式部分:
canvas-view {
position: absolute;
top: -2000px;
opacity: 0;
}
大致实现思路为,
- 选择图片
- 获取图片信息
- canvas绘制图片~~~~
- canvas原生方法获取base64
- 其他处理
本人原文地址:https://segmentfault.com/a/1190000039793934
请多多指教。
最近遇到了一个新需求,使用uniapp开发并打包成小程序在uniapp上运行,页面内涉及到一个图片上传的功能,原先微信小程序内的图片上传对接挺简单的,类似的尝试了一下走文档,发现后端解析图片部分存在问题,经过一番讨论,后端决定让前端将图片信息转成base64再传给接口。
此时问题来了,uniapp内的图片信息转换插件均不支持在支付宝小程序内调用,如不信,可以亲身尝试一波,会提示无权限调用接口。
亲测无效的一个插件
image-tools
//官方下载后,支付宝小程序真机上测试,直接报错,报错信息为无权限调用该接口
话不多说,直接上可用的实现代码。
页面标签部分:
<view>
<canvas id="myCanvas" class="canvas-view" :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"></canvas>
</view>
逻辑部分:
export default {
data() {
return {
canvasWidth: 200, //绘制canvas的默认宽度
canvasHeight: 200, //绘制canvas的默认高度
base64: ''
};
},
methods: {
//选择上传图片
chooseUploadImg() {
const ctx = uni.createCanvasContext('myCanvas');
const that = this;
uni.chooseImage({
count: 1,
success: res => {
uni.getImageInfo({
src: res.tempFilePaths[0],
success: function(image) {
//需要动态更新canvas标签的高宽度
that.canvasWidth = image.width;
that.canvasHeight = image.height;
ctx.drawImage(res.tempFilePaths[0], 0, 0, image.width, image.height);
ctx.draw(false, () => {
ctx.toDataURL({}).then(dataURL => {
const base64Str = dataURL.replace('data:image/png;base64,', '');
// doSomething
});
});
}
});
},
fail: e => {
console.log('choose img fail');
}
});
}
}
};
</script>
样式部分:
canvas-view {
position: absolute;
top: -2000px;
opacity: 0;
}
大致实现思路为,
- 选择图片
- 获取图片信息
- canvas绘制图片~~~~
- canvas原生方法获取base64
- 其他处理
本人原文地址:https://segmentfault.com/a/1190000039793934
请多多指教。
收起阅读 »