How to print ZQ511 from TC15 React Native app

? ?brahim Ethem Bildirici 10 months 2 weeks ago
247 0 0

Hello,
Is it possible to use ZQ511 printer with React Native? 

https://developer.zebra.com/blog/develop-react-native-printing-app-android-ios-link-os-sdk 

I did all the steps in this link but the app cannot find the printer.

Does anyone have experience with this or can help? What should I do?

Thanks.

 

Print.js

import React, { Component } from 'react';
import { ActivityIndicator, Platform } from 'react-native';
import { StyleSheet, Button, TouchableOpacity, Text, View, Alert } from 'react-native';
import ZSDKModule from './ZSDKModule.js';


class App extends Component {
   
  state = { printers: [] }; // Starting with an empty list for the listview

  isDiscovering = false; // Hide or reveal the spinner
  buttonTitle = 'Click to Discover Bluetooth Printers';

  printTestLabel = (printer) => {
    alert(`A test label is printed on ${printer.name}`);

    if (Platform.OS === 'ios') {
      ZSDKModule.zsdkWriteBluetooth(printer.name, ''); // Use friendlyName on iOS

    } else {
      var mac_sn = printer.name.split(', '); // e.g. ["AC:3F:A4:BE:90:93","XXZEJ173500341"]
      console.log(mac_sn);
      var macAddress = mac_sn[0];
      var friendlyName = mac_sn[1];
      ZSDKModule.zsdkWriteBluetooth(macAddress, ''); // Use MAC address on Android
    }
  }

  discoverPrinters = () => {
    console.log("1");
    // First, clear the listview
    var printersArray = [];
    
    this.setState({printers: printersArray});
    this.isDiscovering = true;
    this.buttonTitle = 'Scanning for Zebra Printers ...';
    console.log("2");
    ZSDKModule.zsdkPrinterDiscoveryBluetooth(
      
       // The callback to be called by the native module after Bluetooth discovery finishes.
       (error, discoveredPrinters) => {
        console.log("3");
        this.isDiscovering = false; // Disable the spinner
        this.buttonTitle = 'Click to Discover Bluetooth Printers';
        console.log('discoveredPrinters: '+discoveredPrinters);
        if (error) {
          console.error(`Error found! ${error}`);
        }

        console.log(`Discovered printers are: ${discoveredPrinters}`);

        // Parse the JSON string
        var printersJson = JSON.parse(discoveredPrinters);

        var printersArray = []; // Discovered printer array for listview

        // Traverse the JSON object of printers to compose an array for the listview
        if (Platform.OS === 'ios') {
          // Cannot get printer's MAC address on iOS. Only the friendlyName
          for (var i = 0; i < printersJson.length; i++) {
            printersArray.push({id: i, name: `${printersJson[i].friendlyName}`});
          }
        } else {
          // We have both MAC address and the friendlyName on Android
          for (var i = 0; i < printersJson.length; i++) {
            printersArray.push({id: i, name: `${printersJson[i].address}` + `, ` + `${printersJson[i].friendlyName}`});
          }
        }

        console.log(printersArray);

        // Update the listview
        this.setState({printers: printersArray});

      }
    );
  }

  render() {
    return (
      <View style={{marginTop: 50}}>
        <Text style={styles.headline}>ZSDK RCT Native Module DevDemo</Text>

        <Button
          title={this.buttonTitle}
          color='#841584'
          disabled={this.isDiscovering}
          onPress={this.discoverPrinters}
        />

        {
          this.state.printers.map((printer, index) => (
            <TouchableOpacity
              key = {printer.id}
              style = {styles.container}
              onPress = {() => this.printTestLabel(printer)}>
              <Text style = {styles.text}>
                {printer.name}
              </Text>
            </TouchableOpacity>
          ))
        }

        <View style={{marginTop: 150}}>
          {this.isDiscovering && <ActivityIndicator size='large' color='#0000ff' />}
        </View>
      </View>
    )
  }
}

export default App

const styles = StyleSheet.create({
  container: {
    marginTop: 3,
    padding: 10,
    backgroundColor: '#d9f9b1',
    alignItems: 'center',
    justifyContent: 'center',
  },

  text: {
      color: '#4f603c'
  },

  headline: {
    textAlign: 'center',
    fontWeight: 'bold',
    fontSize: 17,
    marginTop: 0,
  },

});

ZSDKModule.js

import { NativeModules } from 'react-native';
const { ZSDKModule } = NativeModules;
export default ZSDKModule;

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="com.symbol.datawedge.api.ACTION" />
<uses-permission android:name="com.symbol.datawedge.api.RESULT_ACTION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>



    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
        android:launchMode="singleTask"
        android:windowSoftInputMode="adjustResize"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
    </application>
</manifest>

MainApplication.java

package com.sistapmobileapp;

import android.app.Application;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.soloader.SoLoader;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost =
      new DefaultReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
          return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          // Packages that cannot be autolinked yet can be added manually here, for example:
          // packages.add(new MyReactNativePackage());
          packages.add(new ZSDKModulePackage());
          return packages;
        }

        @Override
        protected String getJSMainModuleName() {
          return "index";
        }

        @Override
        protected boolean isNewArchEnabled() {
          return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
        }

        @Override
        protected Boolean isHermesEnabled() {
          return BuildConfig.IS_HERMES_ENABLED;
        }
      };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
    if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
      // If you opted-in for the New Architecture, we load the native entry point for this app.
      DefaultNewArchitectureEntryPoint.load();
    }
    ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
  }
}

ZSDKModulePackage.java

package com.sistapmobileapp;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ZSDKModulePackage implements ReactPackage {

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Override
    public List<NativeModule> createNativeModules(
            ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();

        modules.add(new ZSDKModule(reactContext));

        return modules;
    }

}

ZSDKModule.java

package com.sistapmobileapp;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.zebra.sdk.comm.BluetoothConnection;
import com.zebra.sdk.comm.Connection;
import com.zebra.sdk.comm.ConnectionException;
import com.zebra.sdk.printer.PrinterLanguage;
import com.zebra.sdk.printer.ZebraPrinter;
import com.zebra.sdk.printer.ZebraPrinterFactory;
import com.zebra.sdk.printer.ZebraPrinterLanguageUnknownException;
import com.facebook.react.bridge.Callback;
import com.zebra.sdk.printer.discovery.BluetoothDiscoverer;
import com.zebra.sdk.printer.discovery.DiscoveredPrinter;
import com.zebra.sdk.printer.discovery.DiscoveredPrinterBluetooth;
import com.zebra.sdk.printer.discovery.DiscoveryHandler;

import java.io.Console;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

import android.util.Log;

import org.json.JSONArray;
import org.json.JSONObject;


public class ZSDKModule extends ReactContextBaseJavaModule {

    ZSDKModule(ReactApplicationContext context) {
        super(context);
    }

    
    @Override
    public String getName() {
        return "ZSDKModule";
    }

    @ReactMethod
    public void zsdkWriteBluetooth(String macAddress, String zpl) {
        Log.d("ZSDKModule", "Going to write via Bluetooth with MAC address: " + macAddress
                + " and zpl: " + zpl);

        Connection printerConnection = null;
        ZebraPrinter printer = null;

        printerConnection = new BluetoothConnection(macAddress);

        try {
            printerConnection.open();

            if (printerConnection.isConnected()) {
                printer = ZebraPrinterFactory.getInstance(printerConnection);
                PrinterLanguage printerLanguage = printer.getPrinterControlLanguage();
                byte[] testLabel = getTestLabel(printerLanguage);
                printerConnection.write(testLabel);
            }
        } catch (ConnectionException e) {
            // Do something
        } catch (ZebraPrinterLanguageUnknownException e) {
            // Do something
        } finally {
            try {
                if (printerConnection != null) {
                    printerConnection.close();
                }
            } catch (ConnectionException ex) {
                // Do something
            }
        }
    }

    
    private byte[] getTestLabel(PrinterLanguage printerLanguage) {
        byte[] testLabel = null;
        if (printerLanguage == PrinterLanguage.ZPL) {
            testLabel = "^XA^FO17,16^GB379,371,8^FS^FT65,255^A0N,135,134^FDTEST^FS^XZ".getBytes();
        } else if (printerLanguage == PrinterLanguage.CPCL || printerLanguage == PrinterLanguage.LINE_PRINT) {
            String cpclConfigLabel = "! 0 200 200 406 1\r\n" + "ON-FEED IGNORE\r\n" + "BOX 20 20 380 380 8\r\n" + "T 0 6 137 177 TEST\r\n" + "PRINT\r\n";
            testLabel = cpclConfigLabel.getBytes();
        }
        return testLabel;
    }

    @ReactMethod
    public void zsdkPrinterDiscoveryBluetooth(Callback callback) {
        try {
            BluetoothDiscoverer.findPrinters(getReactApplicationContext(), new DiscoveryResult(callback));
            
        
        } catch (ConnectionException e) {
            // Do something
        } finally {
            // Do something
        }
    }

    // Implementation to DiscoveryHandler
    public class DiscoveryResult implements DiscoveryHandler {

        protected Callback callback = null;
        protected ArrayList<Map<String, String>> foundPrinterList;

        public DiscoveryResult(Callback callback) {
            super();
            this.callback = callback;
            foundPrinterList = new ArrayList<Map<String, String>>();
        }

        @Override
        public void foundPrinter(final DiscoveredPrinter printer) {
            DiscoveredPrinter dp = printer;
            Map<String, String> foundPrinter = new HashMap<>();
            foundPrinter.put("address", printer.address);
            foundPrinter.put("friendlyName", ((DiscoveredPrinterBluetooth) printer).friendlyName);
            foundPrinterList.add(foundPrinter);
        }

        @Override
        public void discoveryFinished() {

            // Convert the foundPrinterList into JSON string
            List<JSONObject> jsonObj = new ArrayList<JSONObject>();

            for(Map<String, String> data : foundPrinterList) {
                jsonObj.add(new JSONObject(data));
            }

            JSONArray foundPrinterJson = new JSONArray(jsonObj);

            Log.d("ZSDKModule", "Found printers are: " + foundPrinterJson.toString());

            // Invoke the callback in React Native
            callback.invoke(null, foundPrinterJson.toString());
        }

        @Override
        public void discoveryError(String message) {
            // To do
        }
    }
}
CONTACT
Can’t find what you’re looking for?