## 用到的工具:
react-native
react-native-ble-manager
iconv-lite
buffer
## 安裝?
npm install?react-native-ble-manager
npm install?buffer
npm install?iconv-lite
新建 Ecs.js 文件,貼代碼
```
const _ = require('lodash');
const Util = require('./util');
const Buffer = require('buffer').Buffer;
var iconv = require('iconv-lite');
const Common = {
INIT:"1B 40",//初始化
? ? ALIGN_LEFT:"1B 61 00",//左對齊
? ? ALIGN_RIGHT:"1B 61 02",//居右對齊
? ? ALIGN_CENTER:"1B 61 01",//居中對齊
? ? UNDER_LINE:"1C 2D 01",//下劃線
? ? PRINT_AND_NEW_LINE:"0A",//打印并換行
? ? FONT_SMALL:"1B 4D 01",//小號字體9x17
? ? FONT_NORMAL:"1B 4D 00",//正常12x24
? ? FONT_BOLD:"1B 45 01",//粗體
? ? FONT_HEIGHT_TIMES:'1B 21 10',
FONT_WIDTH_TIMES:'1B 21 20',
FONT_HEIGHT_WIDTH_TIMES:'1B 21 30',
SOUND:"1B 42 02 02" // 蜂鳴 2次/100ms
};
const Config = {
wordNumber:48 // 可打印的字數,對應80mm紙張
};
let printArray = [];
function writeTextToDevice(text){
let re =iconv.encode(text,'gbk')
console.log("writeTextToDevice",Array.from(re));
// return an array of bytes
? ? printArray =printArray.concat(Array.from(re));
return re;
}
function writeHexToDevice(hexString) {
let str = hexString.toLowerCase().replace(" ","");
let pos =0;
let len =str.length;
if (len %2 !=0) {
return null;
}
len /=2;
let hexA =new Array();
for (let i =0;i
let s =str.substr(pos,2);
let v =parseInt(s,16);
hexA.push(v);
pos +=2;
}
console.log("writeHexToDevice",hexA);
printArray =printArray.concat(hexA);
return hexA;
}
function setConfig(config) {
Object.assign(Config, config);
}
function leftRight(left, right, wordNumber =Config.wordNumber) {
return left +Util.getSpace(wordNumber -Util.getWordsLength(left) -Util.getWordsLength(right)) + right;
}
function keyValue(name, value, wordNumber =Config.wordNumber) {
const nameLen =Util.getWordsLength(name);
let vArr = [],temp ='';
_.each(value, (v, i) => {
const tvLen =Util.getWordsLength(temp + v);
const diff =tvLen - (wordNumber -nameLen);
if (diff <=0) {
temp += v;
if (i === value.length -1) {
vArr.push(temp);
}
}else {
if (Util.isChinese(v) &&diff ===1) {
temp +=' ';
}
vArr.push(temp);
temp = v;
}
});
return _.map(vArr, (v, i) => {
if (i ===0) {
return name + v;
}else {
return Util.getSpace(name.length) + v;
}
}).join('');
}
const ESC = {
Common,
Util: {
leftRight,
keyValue,
},
setConfig,
init(){
writeHexToDevice(Common.INIT);
},
printAndNewLine(){
writeHexToDevice(Common.PRINT_AND_NEW_LINE);
},
alignLeft(){
writeHexToDevice(Common.ALIGN_LEFT);
},
alignCenter(){
writeHexToDevice(Common.ALIGN_CENTER);
},
alignRight(){
writeHexToDevice(Common.ALIGN_RIGHT);
},
underline(){
writeHexToDevice(Common.UNDER_LINE);
},
fontSmall(){
writeHexToDevice(Common.FONT_SMALL);
},
fontNormal(){
writeHexToDevice(Common.FONT_NORMAL);
},
fontBold(){
writeHexToDevice(Common.FONT_BOLD);
},
fontHeightTimes(){
writeHexToDevice(Common.FONT_HEIGHT_TIMES);
},
fontHeightTimes(){
writeHexToDevice(Common.FONT_WIDTH_TIMES);
},
fontHeightTimes(){
writeHexToDevice(Common.FONT_HEIGHT_WIDTH_TIMES);
},
text(str){
writeTextToDevice(str)
},
sound(){
writeHexToDevice(Common.SOUND);
},
getByte(){
return printArray;
},
resetByte(){
printArray = [];
}
};
module.exports =ESC;
```
新建util.js 貼代碼
```
const _ = require('lodash');
function isChinese(word) {
const charCode = word.charCodeAt(0);
return !(charCode >=0 &&charCode <=128)
}
function getWordLength(word) {
return isChinese(word) ?2 :1;
}
function getWordsLength(words) {
return _.reduce(words, (m, v) => m +getWordLength(v),0);
}
function getSpace(len) {
return _.times(len, () =>' ').join('');
}
module.exports = {
isChinese,
getWordsLength,
getWordLength,
getSpace
};
```
新建?BleModule.js 貼代碼
```
/**
* Created by guang on 2016/11/21.
*/
import {
Platform,
NativeModules,
NativeEventEmitter
}from 'react-native';
import BleManagerfrom 'react-native-ble-manager';
const BleManagerModule =NativeModules.BleManager;
//通過NativeAppEventEmitter.addListener添加監聽的方法官方已不建議使用
const bleManagerEmitter =new NativeEventEmitter(BleManagerModule);
export default class BleModule{
constructor(){
this.isConnecting =false;//藍牙是否連接
? ? ? ? this.bluetoothState ='off';//藍牙打開狀態
? ? ? ? this.initUUID();
}
/**
? ? * 添加監聽器
? ? * 所有監聽事件如下
? ? * BleManagerStopScan:掃描結束監聽
? ? * BleManagerDiscoverPeripheral:掃描到一個新設備
? ? * BleManagerDidUpdateState:藍牙狀態改變
? ? * BleManagerDidUpdateValueForCharacteristic:接收到新數據
? ? * BleManagerConnectPeripheral:藍牙設備已連接
? ? * BleManagerDisconnectPeripheral:藍牙設備已斷開連接
? ? * */
? ? addListener(str,fun){
return bleManagerEmitter.addListener(str,fun);
}
/**
? ? * 初始化藍牙模塊
? ? * Init the module.
* */
? ? start(){
BleManager.start({showAlert:false})
.then( ()=>{
this.checkState();
console.log('Init the module success.');
}).catch(error=>{
console.log('Init the module fail.');
});
}
/**
? ? * 強制檢查藍牙狀態
? ? * Force the module to check the state of BLE and trigger a BleManagerDidUpdateState event.
* */
? ? checkState(){
BleManager.checkState();
}
/**
? ? * 掃描可用設備,5秒后結束
? ? * Scan for availables peripherals.
* */
? ? scan() {
return new Promise( (resolve, reject) =>{
BleManager.scan([],5,true)
.then( () => {
console.log('Scan started');
resolve();
}).catch( (err)=>{
console.log('Scan started fail');
reject(err);
});
});
}
/**
? ? * 停止掃描
? ? * Stop the scanning.
* */
? ? stopScan() {
BleManager.stopScan()
.then(() => {
console.log('Scan stopped');
}).catch((err)=>{
console.log('Scan stopped fail',err);
});
}
/**
? ? * 返回掃描到的藍牙設備
? ? * Return the discovered peripherals after a scan.
* */
? ? getDiscoveredPeripherals() {
return new Promise( (resolve, reject) =>{
BleManager.getDiscoveredPeripherals([])
.then((peripheralsArray) => {
console.log('Discovered peripherals: ', peripheralsArray);
resolve(peripheralsArray);
})
.catch(error=>{
});
});
}
/**
* Converts UUID to full 128bit.
*
? ? * @param {UUID} uuid 16bit, 32bit or 128bit UUID.
? ? * @returns {UUID} 128bit UUID.
*/
? ? fullUUID(uuid) {
if (uuid.length ===4){
return '0000' + uuid.toUpperCase() +'-0000-1000-8000-00805F9B34FB'
? ? ? ? }
if (uuid.length ===8) {
return uuid.toUpperCase() +'-0000-1000-8000-00805F9B34FB'
? ? ? ? }
return uuid.toUpperCase()
}
initUUID(){
this.readServiceUUID = [];
this.readCharacteristicUUID = [];
this.writeWithResponseServiceUUID = [];
this.writeWithResponseCharacteristicUUID = [];
this.writeWithoutResponseServiceUUID = [];
this.writeWithoutResponseCharacteristicUUID = [];
this.nofityServiceUUID = [];
this.nofityCharacteristicUUID = [];
}
//獲取Notify、Read、Write、WriteWithoutResponse的serviceUUID和characteristicUUID
? ? getUUID(peripheralInfo){
this.readServiceUUID = [];
this.readCharacteristicUUID = [];
this.writeWithResponseServiceUUID = [];
this.writeWithResponseCharacteristicUUID = [];
this.writeWithoutResponseServiceUUID = [];
this.writeWithoutResponseCharacteristicUUID = [];
this.nofityServiceUUID = [];
this.nofityCharacteristicUUID = [];
for(let item of peripheralInfo.characteristics){
item.service =this.fullUUID(item.service);
item.characteristic =this.fullUUID(item.characteristic);
if(Platform.OS =='android'){
if(item.properties.Notify =='Notify'){
this.nofityServiceUUID.push(item.service);
this.nofityCharacteristicUUID.push(item.characteristic);
}
if(item.properties.Read =='Read'){
this.readServiceUUID.push(item.service);
this.readCharacteristicUUID.push(item.characteristic);
}
if(item.properties.Write =='Write'){
this.writeWithResponseServiceUUID.push(item.service);
this.writeWithResponseCharacteristicUUID.push(item.characteristic);
}
if(item.properties.WriteWithoutResponse =='WriteWithoutResponse'){
this.writeWithoutResponseServiceUUID.push(item.service);
this.writeWithoutResponseCharacteristicUUID.push(item.characteristic);
}
}else{//ios
? ? ? ? ? ? ? ? for(let property of item.properties){
if(property =='Notify'){
this.nofityServiceUUID.push(item.service);
this.nofityCharacteristicUUID.push(item.characteristic);
}
if(property =='Read'){
this.readServiceUUID.push(item.service);
this.readCharacteristicUUID.push(item.characteristic);
}
if(property =='Write'){
this.writeWithResponseServiceUUID.push(item.service);
this.writeWithResponseCharacteristicUUID.push(item.characteristic);
}
if(property =='WriteWithoutResponse'){
this.writeWithoutResponseServiceUUID.push(item.service);
this.writeWithoutResponseCharacteristicUUID.push(item.characteristic);
}
}
}
}
console.log('readServiceUUID',this.readServiceUUID);
console.log('readCharacteristicUUID',this.readCharacteristicUUID);
console.log('writeWithResponseServiceUUID',this.writeWithResponseServiceUUID);
console.log('writeWithResponseCharacteristicUUID',this.writeWithResponseCharacteristicUUID);
console.log('writeWithoutResponseServiceUUID',this.writeWithoutResponseServiceUUID);
console.log('writeWithoutResponseCharacteristicUUID',this.writeWithoutResponseCharacteristicUUID);
console.log('nofityServiceUUID',this.nofityServiceUUID);
console.log('nofityCharacteristicUUID',this.nofityCharacteristicUUID);
}
/**
? ? * 連接藍牙
? ? * Attempts to connect to a peripheral.
* */
? ? connect(id) {
this.isConnecting =true;//當前藍牙正在連接中
? ? ? ? return new Promise( (resolve, reject) =>{
BleManager.connect(id)
.then(() => {
console.log('Connected success.');
return BleManager.retrieveServices(id);
})
.then((peripheralInfo)=>{
console.log('Connected peripheralInfo: ', peripheralInfo);
this.peripheralId = peripheralInfo.id;
this.getUUID(peripheralInfo);
this.isConnecting =false;//當前藍牙連接結束
? ? ? ? ? ? ? ? ? ? resolve(peripheralInfo);
})
.catch(error=>{
console.log('Connected error:',error);
this.isConnecting =false;//當前藍牙連接結束
? ? ? ? ? ? ? ? ? ? reject(error);
});
});
}
/**
? ? * 斷開藍牙連接
? ? * Disconnect from a peripheral.
* */
? ? disconnect() {
BleManager.disconnect(this.peripheralId)
.then( () => {
console.log('Disconnected');
})
.catch( (error) => {
console.log('Disconnected error:',error);
});
}
/**
? ? * 打開通知
? ? * Start the notification on the specified characteristic.
* */
? ? startNotification(index =0) {
return new Promise( (resolve, reject) =>{
BleManager.startNotification(this.peripheralId,this.nofityServiceUUID[index],this.nofityCharacteristicUUID[index])
.then(() => {
console.log('Notification started');
resolve();
})
.catch((error) => {
console.log('Notification error:',error);
reject(error);
});
});
}
/**
? ? * 關閉通知
? ? * Stop the notification on the specified characteristic.
* */
? ? stopNotification(index =0) {
BleManager.stopNotification(this.peripheralId,this.nofityServiceUUID[index],this.nofityCharacteristicUUID[index])
.then(() => {
console.log('stopNotification success!');
resolve();
})
.catch((error) => {
console.log('stopNotification error:',error);
reject(error);
});
}
/**
? ? * 寫數據到藍牙
? ? * 參數:(peripheralId, serviceUUID, characteristicUUID, data, maxByteSize)
* Write with response to the specified characteristic, you need to call retrieveServices method before.
* */
? ? write(data,index =0) {
// data = this.addProtocol(data);? //在數據的頭尾加入協議格式,如0A => FEFD010AFCFB,不同的藍牙協議應作相應的更改
? ? ? ? return new Promise( (resolve, reject) =>{
BleManager.write(this.peripheralId,this.writeWithResponseServiceUUID[index],this.writeWithResponseCharacteristicUUID[index], data)
.then(() => {
console.log('Write success: ',data.toString());
resolve();
})
.catch((error) => {
console.log('Write? failed: ',data);
reject(error);
});
});
}
/**
? ? * 寫數據到藍牙,沒有響應
? ? * 參數:(peripheralId, serviceUUID, characteristicUUID, data, maxByteSize)
* Write without response to the specified characteristic, you need to call retrieveServices method before.
* */
? ? writeWithoutResponse(data,index =0){
return new Promise( (resolve, reject) =>{
BleManager.writeWithoutResponse(this.peripheralId,this.writeWithoutResponseServiceUUID[index],this.writeWithoutResponseCharacteristicUUID[index], data)
.then(() => {
console.log('Write success: ',data);
resolve();
})
.catch((error) => {
console.log('Write? failed: ',data);
reject(error);
});
});
}
/**
? ? * 讀取數據
? ? * Read the current value of the specified characteristic, you need to call retrieveServices method before
* */
? ? read(index =0){
return new Promise( (resolve, reject) =>{
BleManager.read(this.peripheralId,this.readServiceUUID[index],this.readCharacteristicUUID[index])
.then((data) => {
console.log('Read: ',data);
resolve(data);
})
.catch((error) => {
console.log(error);
reject(error);
});
});
}
/**
? ? * 返回已連接的藍牙設備
? ? * Return the connected peripherals.
* */
? ? getConnectedPeripherals() {
BleManager.getConnectedPeripherals([])
.then((peripheralsArray) => {
console.log('Connected peripherals: ', peripheralsArray);
}).catch(error=>{
})
}
/**
? ? * 判斷指定設備是否已連接
? ? * Check whether a specific peripheral is connected and return true or false
*/
? ? isPeripheralConnected(){
return new Promise( (resolve, reject) =>{
BleManager.isPeripheralConnected(this.peripheralId, [])
.then((isConnected) => {
resolve(isConnected);
if (isConnected) {
console.log('Peripheral is connected!');
}else {
console.log('Peripheral is NOT connected!');
}
}).catch(error=>{
reject(error);
})
});
}
/**
? ? * 藍牙接收的信號強度
? ? * Read the current value of the RSSI
* */
? ? readRSSI(id) {
return new Promise( (resolve, reject) =>{
BleManager.readRSSI(id)
.then((rssi) => {
console.log(id,'RSSI: ',rssi);
resolve(rssi)
})
.catch((error) => {
console.log(error);
reject(error)
});
});
}
/**
? ? * 打開藍牙(Android only)
* Create the request to the user to activate the bluetooth
* */
? ? enableBluetooth() {
BleManager.enableBluetooth()
.then(() => {
console.log('The bluetooh is already enabled or the user confirm');
})
.catch((error) => {
console.log('The user refuse to enable bluetooth');
});
}
/**
* Android only
? ? * 開啟一個綁定遠程設備的進程
? ? * Start the bonding (pairing) process with the remote device
* */
? ? createBond(){
BleManager.createBond(this.peripheralId)
.then(() => {
console.log('createBond success or there is already an existing one');
})
.catch(() => {
console.log('fail to bond');
})
}
/**
* Android only
? ? * 獲取已綁定的設備
? ? * Return the bonded peripherals
* */
? ? getBondedPeripherals(){
BleManager.getBondedPeripherals([])
.then((bondedPeripheralsArray) => {
// Each peripheral in returned array will have id and name properties
? ? ? ? ? ? ? ? console.log('Bonded peripherals: ' + bondedPeripheralsArray);
});
}
/**
? ? * 在已綁定的緩存列表中移除設備
? ? * Removes a disconnected peripheral from the cached list.
* It is useful if the device is turned off,
* because it will be re-discovered upon turning on again
* */
? ? removePeripheral(){
return new Promise( (resolve, reject) =>{
BleManager.removePeripheral(this.peripheralId)
.then(()=>{
resolve();
})
.catch(error=>{
reject(error);
})
});
}
/**
? ? * 添加藍牙協議格式,包頭、數據長度、包尾,不同的藍牙協議應作相應的更改
? ? * 0A => FEFD010AFCFB
* */
? ? addProtocol(data){
return 'FEFD' +this.getHexByteLength(data) + data +'FCFB';
}
/**
? ? * 計算十六進制數據長度,每兩位為1個長度,返回十六進制長度
? ? * */
? ? getHexByteLength(str){
let length =parseInt(str.length /2);
let hexLength =this.addZero(length.toString(16));
return hexLength;
}
/**
? ? * 在字符串前面添加 0, 默認補充為2位
? ? * */
? ? addZero(str, bit=2){
for(let i = str.length;i < bit;i++){
str ='0' + str;
}
return str;
}
/**
? ? * ios系統從藍牙廣播信息中獲取藍牙MAC地址
? ? * */
? ? getMacAddressFromIOS(data){
let macAddressInAdvertising = data.advertising.kCBAdvDataManufacturerMacAddress;
//為undefined代表此藍牙廣播信息里不包括Mac地址
? ? ? ? if(!macAddressInAdvertising){
return;
}
macAddressInAdvertising =macAddressInAdvertising.replace("<","").replace(">","").replace(" ","");
if(macAddressInAdvertising !=undefined &&macAddressInAdvertising !=null &&macAddressInAdvertising !='') {
macAddressInAdvertising =this.swapEndianWithColon(macAddressInAdvertising);
}
return macAddressInAdvertising;
}
/**
? ? * ios從廣播中獲取的mac地址進行大小端格式互換,并加上冒號:
? ? * @param string? ? ? ? 010000CAEA80
? ? * @returns string? ? ? 80:EA:CA:00:00:01
* */
? ? swapEndianWithColon(str){
let format ='';
let len = str.length;
for(let j =2;j <=len;j =j +2){
format += str.substring(len-j,len-(j-2));
if(j !=len) {
format +=":";
}
}
return format.toUpperCase();
}
}
```
新建?BlueToothPrinterPage.js 貼代碼
```
import React, { Component }from 'react'
import _from 'lodash';
import {
StyleSheet,
Text,
TouchableOpacity,
View,
FlatList,
Platform,
TextInput,
Dimensions,
Alert,
}from 'react-native'
import BleModulefrom './BleModule';
import ESCfrom "../../../components/ecs/Ecs";
//確保全局只有一個BleManager實例,BleModule類保存著藍牙的連接信息
global.BluetoothManager =new BleModule();
export default class BlueToothPrinterPageextends Component {
constructor(props) {
super(props);
this.state={
data: [],
scaning:false,
isConnected:false,
text:'',
writeData:'',
receiveData:'',
readData:'',
isMonitoring:false
? ? ? ? }
this.bluetoothReceiveData = [];//藍牙接收的數據緩存
? ? ? ? this.deviceMap =new Map();
}
componentDidMount(){
BluetoothManager.start();//藍牙初始化
? ? ? ? this.updateStateListener =BluetoothManager.addListener('BleManagerDidUpdateState',this.handleUpdateState);
this.stopScanListener =BluetoothManager.addListener('BleManagerStopScan',this.handleStopScan);
this.discoverPeripheralListener =BluetoothManager.addListener('BleManagerDiscoverPeripheral',this.handleDiscoverPeripheral);
this.connectPeripheralListener =BluetoothManager.addListener('BleManagerConnectPeripheral',this.handleConnectPeripheral);
this.disconnectPeripheralListener =BluetoothManager.addListener('BleManagerDisconnectPeripheral',this.handleDisconnectPeripheral);
this.updateValueListener =BluetoothManager.addListener('BleManagerDidUpdateValueForCharacteristic',this.handleUpdateValue);
}
componentWillUnmount(){
this.updateStateListener.remove();
this.stopScanListener.remove();
this.discoverPeripheralListener.remove();
this.connectPeripheralListener.remove();
this.disconnectPeripheralListener.remove();
this.updateValueListener.remove();
if(this.state.isConnected){
BluetoothManager.disconnect();//退出時斷開藍牙連接
? ? ? ? }
}
//藍牙狀態改變
? ? handleUpdateState=(args)=>{
console.log('BleManagerDidUpdateStatea:', args);
BluetoothManager.bluetoothState = args.state;
if(args.state =='on'){//藍牙打開時自動搜索
? ? ? ? ? ? this.scan();
}
}
//掃描結束監聽
? ? handleStopScan=()=>{
console.log('BleManagerStopScan:','Scanning is stopped');
this.setState({scaning:false});
}
//搜索到一個新設備監聽
? ? handleDiscoverPeripheral=(data)=>{
// console.log('BleManagerDiscoverPeripheral:', data);
? ? ? ? console.log(data.id,data.name);
let id;//藍牙連接id
? ? ? ? let macAddress;//藍牙Mac地址
? ? ? ? if(Platform.OS =='android'){
macAddress = data.id;
id =macAddress;
}else{
//ios連接時不需要用到Mac地址,但跨平臺識別同一設備時需要Mac地址
? ? ? ? ? ? //如果廣播攜帶有Mac地址,ios可通過廣播0x18獲取藍牙Mac地址,
? ? ? ? ? ? macAddress =BluetoothManager.getMacAddressFromIOS(data);
id = data.id;
}
this.deviceMap.set(data.id,data);//使用Map類型保存搜索到的藍牙設備,確保列表不顯示重復的設備
? ? ? ? this.setState({data:[...this.deviceMap.values()]});
}
//藍牙設備已連接
? ? handleConnectPeripheral=(args)=>{
console.log('BleManagerConnectPeripheral:', args);
}
//藍牙設備已斷開連接
? ? handleDisconnectPeripheral=(args)=>{
console.log('BleManagerDisconnectPeripheral:', args);
let newData = [...this.deviceMap.values()]
BluetoothManager.initUUID();//斷開連接后清空UUID
? ? ? ? this.setState({
data:newData,
isConnected:false,
writeData:'',
readData:'',
receiveData:'',
text:'',
});
}
//接收到新數據
? ? handleUpdateValue=(data)=>{
//ios接收到的是小寫的16進制,android接收的是大寫的16進制,統一轉化為大寫16進制
? ? ? ? let value = data.value.toUpperCase();
this.bluetoothReceiveData.push(value);
console.log('BluetoothUpdateValue',value);
this.setState({receiveData:this.bluetoothReceiveData.join('')})
}
connect(item){
//當前藍牙正在連接時不能打開另一個連接進程
? ? ? ? if(BluetoothManager.isConnecting){
console.log('當前藍牙正在連接時不能打開另一個連接進程');
return;
}
if(this.state.scaning){//當前正在掃描中,連接時關閉掃描
? ? ? ? ? ? BluetoothManager.stopScan();
this.setState({scaning:false});
}
let newData = [...this.deviceMap.values()]
newData[item.index].isConnecting =true;
this.setState({data:newData});
BluetoothManager.connect(item.item.id)
.then(peripheralInfo=>{
let newData = [...this.state.data];
newData[item.index].isConnecting =false;
//連接成功,列表只顯示已連接的設備
? ? ? ? ? ? ? ? this.setState({
data:[item.item],
isConnected:true
? ? ? ? ? ? ? ? });
})
.catch(err=>{
let newData = [...this.state.data];
newData[item.index].isConnecting =false;
this.setState({data:newData});
this.alert('連接失敗');
})
}
disconnect(){
this.setState({
data:[...this.deviceMap.values()],
isConnected:false
? ? ? ? });
BluetoothManager.disconnect();
}
scan(){
if(this.state.scaning){//當前正在掃描中
? ? ? ? ? ? BluetoothManager.stopScan();
this.setState({scaning:false});
}
if(BluetoothManager.bluetoothState =='on'){
BluetoothManager.scan()
.then(()=>{
this.setState({scaning:true });
}).catch(err=>{
})
}else{
BluetoothManager.checkState();
if(Platform.OS =='ios'){
this.alert('請開啟手機藍牙');
}else{
Alert.alert('提示','請開啟手機藍牙',[
{
text:'取消',
onPress:()=>{ }
},
{
text:'打開',
onPress:()=>{BluetoothManager.enableBluetooth() }
}
]);
}
}
}
alert(text){
Alert.alert('提示',text,[{text:'確定',onPress:()=>{ } }]);
}
/*write=(index)=>{
if(this.state.text.length == 0){
? ? ? ? ? ? this.alert('請輸入消息');
return;
}
BluetoothManager.write(this.state.text,index)
.then(()=>{
this.bluetoothReceiveData = [];
this.setState({
writeData:this.state.text,
text:'',
})
})
.catch(err=>{
? ? ? ? ? ? ? ? this.alert('發送失敗');
})
}*/
? ? write=(index)=>{
BluetoothManager.write(this.print(),index)
.then(()=>{
this.bluetoothReceiveData = [];
this.setState({
writeData:this.state.text,
text:'',
})
})
.catch(err=>{
this.alert('發送失敗');
})
}
print(){
ESC.resetByte();
// 一定要配置好
? ? ? ? const Config = {
wordNumber:48
? ? ? ? };
ESC.setConfig(Config);
ESC.init();
ESC.alignCenter();
ESC.fontBold();
ESC.printAndNewLine();
ESC.text('正定新區許翠蔬菜店');
ESC.printAndNewLine();
ESC.text('采購訂貨單');
ESC.printAndNewLine();
ESC.printAndNewLine();
ESC.init();
ESC.text('下單時間:2016-09-06 19:30:23');
ESC.printAndNewLine();
ESC.text('單據編號:T2345-CGD-2017-01-14-00005');
ESC.printAndNewLine();
ESC.text('采購單位:小農女供應鏈優先公司');
ESC.printAndNewLine();
ESC.text('采購經辦:采購員A');
ESC.printAndNewLine();
ESC.text('電? ? 話:15201083760');
ESC.printAndNewLine();
ESC.printAndNewLine();
ESC.text('商品明細:共2種商品');
ESC.printAndNewLine();
// 商品開始
? ? ? ? ESC.text(
ESC.Util.leftRight('大利(42斤/件)','',20)
+ ESC.Util.leftRight('84元/件','',11)
+ ESC.Util.leftRight('x1件','總價:84元',17)
);
ESC.printAndNewLine();
ESC.text(' (3斤,1斤/斤,要新鮮的)+(5袋,5斤/袋,不要睡分太多的)');
ESC.printAndNewLine();
ESC.text(_.times(Config.wordNumber, () =>'-').join(''));
ESC.printAndNewLine();
// 商品結束
? ? ? ? // 商品開始
? ? ? ? ESC.text(
ESC.Util.leftRight('大利(42斤/件)','',20)
+ ESC.Util.leftRight('84元/件','',11)
+ ESC.Util.leftRight('x1件','總價:84元',17)
);
ESC.printAndNewLine();
ESC.text(' (3斤,1斤/斤,要新鮮的)+(5袋,5斤/袋,不要睡分太多的)');
ESC.printAndNewLine();
ESC.text(_.times(Config.wordNumber, () =>'-').join(''));
ESC.printAndNewLine();
// 商品結束
? ? ? ? ESC.text(_.times(Config.wordNumber, () =>'-').join(''));
ESC.printAndNewLine();
ESC.alignRight();
ESC.text('合計:168元');
ESC.printAndNewLine();
ESC.printAndNewLine();
ESC.printAndNewLine();
ESC.init();
ESC.text(ESC.Util.leftRight('采購經辦:','',24) +'供應商:');
ESC.printAndNewLine();
ESC.printAndNewLine();
ESC.printAndNewLine();
ESC.printAndNewLine();
ESC.printAndNewLine();
ESC.printAndNewLine();
ESC.printAndNewLine();
ESC.sound();
ESC.init();
console.log("傳輸字節",ESC.getByte());
return ESC.getByte();
}
writeWithoutResponse=(index)=>{
if(this.state.text.length ==0){
this.alert('請輸入消息');
return;
}
BluetoothManager.writeWithoutResponse(this.state.text,index)
.then(()=>{
this.bluetoothReceiveData = [];
this.setState({
writeData:this.state.text,
text:'',
})
})
.catch(err=>{
this.alert('發送失敗');
})
}
read=(index)=>{
BluetoothManager.read(index)
.then(data=>{
this.setState({readData:data});
})
.catch(err=>{
this.alert('讀取失敗');
})
}
notify=(index)=>{
BluetoothManager.startNotification(index)
.then(()=>{
this.setState({isMonitoring:true});
this.alert('開啟成功');
})
.catch(err=>{
this.setState({isMonitoring:false});
this.alert('開啟失敗');
})
}
renderItem=(item)=>{
let data = item.item;
return(
? ? ? ? ? ? ? ? activeOpacity={0.7}? ? ? ? ? ? ? ? disabled={this.state.isConnected?true:false}? ? ? ? ? ? ? ? onPress={()=>{this.connect(item)}}? ? ? ? ? ? ? ? style={styles.item}>
{data.name?data.name:''}
{data.isConnecting?'連接中...':''}
{data.id}
);
}
renderHeader=()=>{
return(
? ? ? ? ? ? ? ? ? ? activeOpacity={0.7}? ? ? ? ? ? ? ? ? ? style={[styles.buttonView,{marginHorizontal:10,height:40,alignItems:'center'}]}? ? ? ? ? ? ? ? ? ? onPress={this.state.isConnected?this.disconnect.bind(this):this.scan.bind(this)}>
{this.state.scaning?'正在搜索中':this.state.isConnected?'斷開藍牙':'搜索藍牙'}
{this.state.isConnected?'當前連接的設備':'可用設備'}
)
}
renderFooter=()=>{
return(
{this.state.isConnected?
{this.renderWriteView('寫數據(write):','發送',BluetoothManager.writeWithResponseCharacteristicUUID,this.write,this.state.writeData)}
{this.renderWriteView('寫數據(writeWithoutResponse):','發送',BluetoothManager.writeWithoutResponseCharacteristicUUID,this.writeWithoutResponse,this.state.writeData)}
{this.renderReceiveView('讀取的數據:','讀取',BluetoothManager.readCharacteristicUUID,this.read,this.state.readData)}
{this.renderReceiveView('通知監聽接收的數據:'+`${this.state.isMonitoring?'監聽已開啟':'監聽未開啟'}`,'開啟通知',BluetoothManager.nofityCharacteristicUUID,this.notify,this.state.receiveData)}
:
}
)
}
renderReceiveView=(label,buttonText,characteristics,onPress,state)=>{
if(characteristics.length ==0){
return;
}
return(
{label}
{state}
{characteristics.map((item,index)=>{
return(
? ? ? ? ? ? ? ? ? ? ? ? ? ? activeOpacity={0.7}? ? ? ? ? ? ? ? ? ? ? ? ? ? style={styles.buttonView}? ? ? ? ? ? ? ? ? ? ? ? ? ? onPress={()=>{onPress(index)}}? ? ? ? ? ? ? ? ? ? ? ? ? ? key={index}>
{buttonText} ({item})
)
})}
)
}
renderWriteView=(label,buttonText,characteristics,onPress,state)=>{
if(characteristics.length ==0){
return;
}
return(
{label}
{this.state.writeData}
{characteristics.map((item,index)=>{
return(
? ? ? ? ? ? ? ? ? ? ? ? ? ? key={index}? ? ? ? ? ? ? ? ? ? ? ? ? ? activeOpacity={0.7}? ? ? ? ? ? ? ? ? ? ? ? ? ? style={styles.buttonView}? ? ? ? ? ? ? ? ? ? ? ? ? ? onPress={()=>{onPress(index)}}>
{buttonText} ({item})
)
})}
? ? ? ? ? ? ? ? ? ? style={[styles.textInput]}? ? ? ? ? ? ? ? ? ? value={this.state.text}? ? ? ? ? ? ? ? ? ? placeholder='請輸入消息'
? ? ? ? ? ? ? ? ? ? onChangeText={(text)=>{
this.setState({text:text});
}}? ? ? ? ? ? ? ? />
)
}
render () {
return (
? ? ? ? ? ? ? ? ? ? renderItem={this.renderItem}? ? ? ? ? ? ? ? ? ? ListHeaderComponent={this.renderHeader}? ? ? ? ? ? ? ? ? ? ListFooterComponent={this.renderFooter}? ? ? ? ? ? ? ? ? ? keyExtractor={item=>item.id}? ? ? ? ? ? ? ? ? ? data={this.state.data}? ? ? ? ? ? ? ? ? ? extraData={[this.state.isConnected,this.state.text,this.state.receiveData,this.state.readData,this.state.writeData,this.state.isMonitoring,this.state.scaning]}? ? ? ? ? ? ? ? ? ? keyboardShouldPersistTaps='handled'
? ? ? ? ? ? ? ? />
)
}
}
const styles =StyleSheet.create({
container: {
flex:1,
backgroundColor:'white',
marginTop:Platform.OS =='ios'?20:0,
},
item:{
flexDirection:'column',
borderColor:'rgb(235,235,235)',
borderStyle:'solid',
borderBottomWidth:StyleSheet.hairlineWidth,
paddingLeft:10,
paddingVertical:8,
},
buttonView:{
height:30,
backgroundColor:'rgb(33, 150, 243)',
paddingHorizontal:10,
borderRadius:5,
justifyContent:"center",
alignItems:'center',
alignItems:'flex-start',
marginTop:10
? ? },
buttonText:{
color:"white",
fontSize:12,
},
content:{
marginTop:5,
marginBottom:15,
},
textInput:{
paddingLeft:5,
paddingRight:5,
backgroundColor:'white',
height:50,
fontSize:16,
flex:1,
},
})
```