januslo / react-native-bluetooth-escpos-printer

React-Native plugin for the bluetooth ESC/POS & TSC printers.
MIT License
361 stars 420 forks source link

cannot print #61

Open ddevico opened 5 years ago

ddevico commented 5 years ago

Hello, I try for a week to run your componant but I can not ... the application connects the printer well but when I press print, nothing happens and no errors are displayed ... Can you help me ? Davy

FazilMuhammed commented 5 years ago

worked properly in Android.but in iOS cannot print. Bluetooth enable and pairing devices working properly. Anyone help me.

firdaussoberi commented 5 years ago

What's the issue @FazilMuhammed? I can print in iOS but that was with RN 0.5x . Haven't tested iOS with RN >0.60 yet. Android is fine

Also, maybe different printers give different response. Mine is jingpu 58mm thermal printer

FazilMuhammed commented 5 years ago

RN 0.58 Bluetooth device - Mini Thermal Printer

Printer and device is connected successfully but on printing function not calling from iOS App.

when i click print button this function is not executing.

note - options is my printing contents

BluetoothTscPrinter.printLabel(options) .then(()=>{ console.log('Success') }, (err)=>{ console.log('error') })

firdaussoberi commented 5 years ago

Oh you are printing with tsc. Mine worked with esc but haven't tried tsc yet. Does it not work with esc?

FazilMuhammed commented 5 years ago

tried both methods tcs and escos but still issue exist in ios, printtext function is not called.

FazilMuhammed commented 5 years ago

@firdaussoberi can you share your escos used code to me please.

firdaussoberi commented 5 years ago

@FazilMuhammed sure, mine is rather long code (redacted here so maybe some error, let me know). have you tried following the examples? you need the connection first, then the printing command can be just one-liner.

import React, {Component} from 'react';
import {Alert, ActivityIndicator,Platform, ScrollView, Linking, StyleSheet, Text, View,Image,NativeModules,DeviceEventEmitter,NativeEventEmitter,Switch} from 'react-native';
import {BluetoothManager,BluetoothEscposPrinter,BluetoothTscPrinter} from 'react-native-bluetooth-escpos-printer';
export default class PrinterScreen extends Component {
    _listeners = [];

    constructor() {
        super();
        this.state = {
            devices: null,
            pairedDs: ds.cloneWithRows([]),
            foundDs: ds.cloneWithRows([]),
            bleOpend: false,
            loading: true,
            debugMsg: '',
            boundAddress: '',
            debugMsg: '',
       deviceAddress: '',
           bluetoothState:'PoweredOff',  //initialize powered off at first before it checks
        }
    }

componentDidMount() {
        //alert(BluetoothManager)
        BluetoothManager.isBluetoothEnabled().then((enabled)=> {
            this.setState({
                bleOpend: Boolean(enabled),
                loading: false
            })
        }, (err)=> {
            err
        });

        if (Platform.OS === 'ios') {
            let bluetoothManagerEmitter = new NativeEventEmitter(BluetoothManager);
            this._listeners.push(bluetoothManagerEmitter.addListener(BluetoothManager.EVENT_DEVICE_ALREADY_PAIRED,
                (rsp)=> {
                    this._deviceAlreadPaired(rsp)
                }));
            this._listeners.push(bluetoothManagerEmitter.addListener(BluetoothManager.EVENT_DEVICE_FOUND, (rsp)=> {
                this._deviceFoundEvent(rsp)
            }));
            this._listeners.push(bluetoothManagerEmitter.addListener(BluetoothManager.EVENT_CONNECTION_LOST, ()=> {
                this.setState({
                    name: '',
                    boundAddress: ''
                });
            }));
        } else if (Platform.OS === 'android') {
            this._listeners.push(DeviceEventEmitter.addListener(
                BluetoothManager.EVENT_DEVICE_ALREADY_PAIRED, (rsp)=> {
                    this._deviceAlreadPaired(rsp)
                }));
            this._listeners.push(DeviceEventEmitter.addListener(
                BluetoothManager.EVENT_DEVICE_FOUND, (rsp)=> {
                    this._deviceFoundEvent(rsp)
                }));
            this._listeners.push(DeviceEventEmitter.addListener(
                BluetoothManager.EVENT_CONNECTION_LOST, ()=> {
                    this.setState({
                        name: '',
                        boundAddress: ''
                    });
                }
            ))
        }

  this.printSomething();
}

printSomething = async () =>{
//with normal text, mine is 58mm mini thermal printer and has 32char limitation
await  BluetoothEscposPrinter.printText("------------------------------\r\n",{});
await  BluetoothEscposPrinter.printText("This is another text",{});
await  BluetoothEscposPrinter.printText("------------------------------\r\n",{});
//with columns, split to 4 columns of 8 char each, need to specify alignment for each column and text for each column
await BluetoothEscposPrinter.printColumn([8,8,8,8],[BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT],
        ["column1","column2","column3","column4"],{});        
await BluetoothEscposPrinter.printColumn([8,8,8,8],[BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT],
        ["1","PRODUCTA","2","$2.00"],{});        
await BluetoothEscposPrinter.printColumn([8,8,8,8],[BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT],
        ["2","PRODUCTB","3","$1.00"],{});        
}

    componentWillUnmount() {

    //usually to destroy states or variables or components, reset the passed variables so that printer can start afresh again
        for (let ls in this._listeners) {
            this._listeners[ls].remove();
        }

    }

    _deviceAlreadPaired(rsp) {
        var ds = null;
        if (typeof(rsp.devices) == 'object') {
            ds = rsp.devices;
        } else {
            try {
                ds = JSON.parse(rsp.devices);
            } catch (e) {
            }
        }
        this.paired = ds || []
        this.setState({
            pairedDs: this.state.pairedDs.cloneWithRows(this.paired)
        });
    }

    _deviceFoundEvent(rsp) {//alert(JSON.stringify(rsp))
        var r = null;
        try {
            if (typeof(rsp.device) == "object") {
                r = rsp.device;
            } else {
                r = JSON.parse(rsp.device);
            }
        } catch (e) {//alert(e.message);
            //ignore
        }
        //alert('f')
        if (r) {
            if (!this.found || !this.found.push){
                this.found = []
            };
            this.found.push(r);
            this.setState({
                foundDs: this.state.foundDs.cloneWithRows(this.found)
            });
        }
    }

render() {
       return (
            <View>
                <Text>Testing...</Text>
       </View>
       );
  }
}

So in the examples, they show how to connect to printer and save the bluetooth printer address in componentdidmount, after screen render is called. Then you need to create the printing command based on async/await (I used escpos here), then call that function in componentdidmount.

The screen did nothing actually, you can put instead the switch for bluetooth on/off in android (in iOS as i know there is no native method to on bluetooth from API yet so you need to use some reactnative bluetooth listener package) and you can put also the searched device addresses together with the already paired devices addresses.

For note: I used react-native-bluetooth-state-manager to listen to bluetooth either on/off/rejected permission. To handle the appstate change (in this case, the bluetooth on/off state in iOS, android is fine-> you can open from switch) you need something like AppState https://facebook.github.io/react-native/docs/appstate.

Try the above code first. If you want to add that part to the above code, in my constructor I initialize like this:

    constructor() {
        super();
        this.state = {
                        //others here like before
            appState: AppState.currentState,  //checks whether app is 'active','background' or             
        }
    }

Then to track the changes in my componentdidmount, modify/add this:

import BluetoothStateManager from 'react-native-bluetooth-state-manager';

    componentDidMount() {
    this.didFocusListener = this.props.navigation.addListener(
    'didFocus',
    () => {
    console.log('did focus'); 
    //alert('did focus'); 
    this.bluetoothStatus();
    },
    );
    AppState.addEventListener('change', this._handleAppStateChange);
}

    componentWillUnmount() {

    AppState.removeEventListener('change', this._handleAppStateChange);
    //usually to destroy states or variables or components, reset the passed variables so that printer can start afresh again

    this.didFocusListener.remove();
    //this.willFocusListener.remove();

        for (let ls in this._listeners) {
            this._listeners[ls].remove();
        }

    }

    bluetoothStatus = async () => {
        let promise = BluetoothStateManager.getState().then(bluetoothState => {
            // do something...
            //alert("Bluetooth State is: " + bluetoothState);
            this.setState({bluetoothState:bluetoothState,});
            if(bluetoothState=="PoweredOn"){
                this.setState({bleOpend: true});                
            }else{
                this.setState({bleOpend: false});                               
            }         
        });
        let result = await promise;
    };

     _handleAppStateChange = (nextAppState) => {
        /*if (
          this.state.appState.match(/inactive|background/) &&
          nextAppState === 'active'
        ) {
          console.log('App has come to the foreground!');
        }*/
        this.setState({appState: nextAppState},()=>{
            this.bluetoothStatus();
        });
      };
FazilMuhammed commented 5 years ago

@firdaussoberi Thank you so much.Let something need to know.

how you connect the bluetooth devices. before pair.

initially we get the list.

here is my code to connect .

code

           BluetoothManager.connect(9DA2BF7F-1C4F-6B54-4297-C758C945B7E2)
                .then((s) => {
                         this.setState({
                                 loading:false,
                                 boundAddress:row.address,
                                 name:row.name || "UNKNOWN"
                             }, async () => {

                           await  BluetoothEscposPrinter.printText("Hello World\n\r",{
                               encoding:'GBK',
                               codepage:0,
                               widthtimes:3,
                               heigthtimes:3,
                               fonttype:1
                          });
                       } )
                           },(e)=>{
                                this.setState({
                                     loading:false
                                   })
                            alert(e);
                     })
firdaussoberi commented 5 years ago

@firdaussoberi Thank you so much.Let something need to know.

how you connect the bluetooth devices. before pair.

initially we get the list.

here is my code to connect .

code

           BluetoothManager.connect(9DA2BF7F-1C4F-6B54-4297-C758C945B7E2)
                .then((s) => {
                         this.setState({
                                 loading:false,
                                 boundAddress:row.address,
                                 name:row.name || "UNKNOWN"
                             }, async () => {

                           await  BluetoothEscposPrinter.printText("Hello World\n\r",{
                               encoding:'GBK',
                               codepage:0,
                               widthtimes:3,
                               heigthtimes:3,
                               fonttype:1
                          });
                       } )
                           },(e)=>{
                                this.setState({
                                     loading:false
                                   })
                            alert(e);
                     })

I see. I think this way you restrict to only one uuid. I think the examples show how to search for devices and connect address. The address/uuid can change.

That's why the example has this kind of layout. switch, then two listview (deprecated) columns of new address and connected address. This one code is rather long 😆 . I need more time to show instruction.

screenshot: https://drive.google.com/file/d/12Ne_skQREZ2t3WHxDRbPghkaM4fHxhg8/view

Mine was from the library's older code. He splitted the scan logic and printing logic. I think this is what you want for the scanning part: https://github.com/januslo/react-native-bluetooth-escpos-printer/blob/master/examples/home.js You can see most of my codes are the same, just I combine the scan part and printing part

For iOS, even if you click the on/off switch it'll do nothing (I read ios you can't on/off bluetooth from api yet) so you need the bluetooth state tracker, if powered off, you manually turn it on from device setting, if on you good to go

firdaussoberi commented 5 years ago

Oh another, if you can alert/debug/console.log every important line (before connect, after connect, when printing, inside printing call) then it's easier to know where's the problem.

FazilMuhammed commented 5 years ago

@firdaussoberi I used alert to check. here is my code

code

             printSomething = async () =>  {

                    Alert.alert("Print")

                    await  BluetoothEscposPrinter.printText("------------------------------\r\n",{});
                    await  BluetoothEscposPrinter.printText("This is another text",{});
                    await  BluetoothEscposPrinter.printText("------------------------------\r\n",{});
                    await BluetoothEscposPrinter.printColumn([8,8,8,8],   [BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrint er.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT],
         ["column1","column2","column3","column4"],{});        
                   await BluetoothEscposPrinter.printColumn([8,8,8,8],[BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT],
        ["1","PRODUCTA","2","$2.00"],{});        
                  await BluetoothEscposPrinter.printColumn([8,8,8,8],[BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT],
        ["2","PRODUCTB","3","$1.00"],{});        
}

getting alert properly. but problem is when i change this alert to between await BluetoothEscposPrinter function Alert is not getting here is my code

code

         printSomething = async () => {
                await  BluetoothEscposPrinter.printText("------------------------------\r\n",{});
                await  BluetoothEscposPrinter.printText("This is another text",{});
                await  BluetoothEscposPrinter.printText("------------------------------\r\n",{});
                Alert.alert("Print")

                await BluetoothEscposPrinter.printColumn([8,8,8,8],[BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT],
        ["column1","column2","column3","column4"],{});        
                await BluetoothEscposPrinter.printColumn([8,8,8,8],[BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT],
        ["1","PRODUCTA","2","$2.00"],{});        
                await BluetoothEscposPrinter.printColumn([8,8,8,8],[BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT,BluetoothEscposPrinter.ALIGN.RIGHT],
        ["2","PRODUCTB","3","$1.00"],{});        
      }

here is my updated BluetoothManager.connect()

code

    BluetoothManager.connect(row.address)
                    .then((response)=>{
                        console.log(response)
                        this.setState({
                            loading:false,
                            boundAddress:row.address,
                            name:row.name || "UNKNOWN"
                        })
                    },(e)=>{
                        this.setState({
                            loading:false
                        })
                        alert(e);
                    })

when i console the response result in iOS it's undefined but in android it's success. may I know this undefined response leads any effect.

firdaussoberi commented 5 years ago

@FazilMuhammed undefined immediately after BluetoothManager.connect means either it can't connect to the address or something is wrong with the connection. I think your problem is more to connection in iOS (if android shows success). So that's why the print does nothing on iOS. Try to fix the connection. I think I left the BluetoothManager.connect in my sample (it's a rather long code). Let me get back and include that part.

FazilMuhammed commented 5 years ago

I think may be the printer issue its shows only support Android

Screenshot 2019-08-29 at 10 52 43 AM

when I tried similar app. Use same android printer then it's getting print from iOS App. here I share the app below.

https://apps.apple.com/us/app/express-thermal-print/id1449743356

firdaussoberi commented 5 years ago

Maybe. Check the device specs. My printer shows support both android and ios

keerthanaMol commented 5 years ago

@firdaussoberi can you please help to print data center.

here is my code.

Code

        printData = async () =>  {
                await  BluetoothEscposPrinter.printText("------------------------------\r\n",{});
                await  BluetoothEscposPrinter.printText("Hello Welcom",{});
                await  BluetoothEscposPrinter.printText("------------------------------\r\n",{});
      }
firdaussoberi commented 5 years ago

@keerthanaMol i don't understand your issue, can u describe it? so did u successfully printed or you're having connection problem?

keerthanaMol commented 5 years ago

i'm working in android.printing data is successful. i have doubt in align issue. i dont i print in center can you help me...

On Fri 30 Aug, 2019 7:37 pm Firdaus Soberi, notifications@github.com wrote:

@keerthanaMol https://github.com/keerthanaMol i don't understand your issue, can u describe it? so did u successfully printed or you're having connection problem?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/januslo/react-native-bluetooth-escpos-printer/issues/61?email_source=notifications&email_token=ANBN67KB5A4QQPF7OB7GSB3QHESSPA5CNFSM4IHMF5Z2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5RYGBQ#issuecomment-526615302, or mute the thread https://github.com/notifications/unsubscribe-auth/ANBN67PIYVWCRUHROXP7JJDQHESSPANCNFSM4IHMF5ZQ .

firdaussoberi commented 5 years ago

i see. in that case just use the printcolumn function, [32] as length of column (for 58mm mini printer) and aligncenter. i mean like this:

await BluetoothEscposPrinter.printColumn([32],[BluetoothEscposPrinter.ALIGN.CENTER],
        ["any 32 char text here"],{});        

for other like 80mm printer, u need to calculate max character and put that instead of 32

keerthanaMol commented 5 years ago

how to change the fontweight for print page?

dvorakvaclav commented 3 years ago

Hi, I temporary fixed the problem with printing on iOS by changing service to E7810A71-73AE-499D-8C15-FAA9AEF0C3F2 and charactiscs to BEF8D6C9-9C21-4C9E-B632-BD58C1009F9F in ios/RNBluetoothManager.m:

- (void) initSupportServices
{
    if(!supportServices){
        CBUUID *issc = [CBUUID UUIDWithString: @"E7810A71-73AE-499D-8C15-FAA9AEF0C3F2"];
        supportServices = [NSArray arrayWithObject:issc];/*ISSC*/
        writeableCharactiscs = @{issc:@"BEF8D6C9-9C21-4C9E-B632-BD58C1009F9F"};
    }
}
derb21 commented 2 years ago

Anyone fix the connect() results in undefined on IOS issue?

thechaudharysab commented 2 years ago

@FazilMuhammed https://github.com/januslo/react-native-bluetooth-escpos-printer/issues/182 Can you have a look at this issue?