react-native react-native-ble-manager 實現 小票打印功能

## 用到的工具:

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,

},

})

```


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容