I am trying to print a turn number from my android kiosk/tablet. User just presses on an image button and the turn should be printed.
The kiosk connects to a USB Epson TM-T20 printer.
I downloaded the sample EPOS2_Printer app that epson provides, and I built it's APK, it works fine on the kiosk, so I am trying to use its code and integrate it into what I am trying to do. The problem is I am unable to get the printer to be discovered and selected without user interaction.
The sample EPSON provides has a DiscoveryActivity, where the app searches for connected devices, you select the one you want from search results and that takes you back to main activity with the target field pre-filled.
I am trying to stay in the same activity, and onClick, do the discovery and get target (only 1 printer) and print to it.
Reading this: Epson printer connect fails status ERR_CONN the comment below says to use Discover.start to get the target, but how can you integrate that with Printer.connect?
I can share code, just wanted to be as short as possible here.
Any help is appreciated!
Share your code, please
Did you try something like this?
printer = new Print(getApplicationContext());
try {
// Open
printer.openPrinter(
connectionType,
openDeviceName,
Print.FALSE,
Print.PARAM_DEFAULT,
Print.PARAM_DEFAULT);
}
catch (EposException e) {
result.setEposException(e);
return;
}
try {
// Print data if printer is printable
printer.getStatus(printerStatus, batteryStatus);
result.setPrinterStatus(printerStatus[0]);
result.setBatteryStatus(batteryStatus[0]);
if (isPrintable(result)) {
printerStatus[0] = 0;
batteryStatus[0] = 0;
printer.beginTransaction();
isBeginTransaction = true;
printer.sendData(builder, sendTimeout, printerStatus, batteryStatus);
result.setPrinterStatus(printerStatus[0]);
result.setBatteryStatus(batteryStatus[0]);
}
}
catch (EposException e) {
result.setEposException(e);
}
finally {
if (isBeginTransaction) {
try {
printer.endTransaction();
}
catch (EposException e) {
// Do nothing
}
}
}
try {
printer.closePrinter();
}
Related
'DataWedge' services automatically place scan data in an 'inFocus' field like an EditText, However I would like this functionality turned off so I can place the data where I want
I have already tried searching the internet and trawling through the settings. Awaiting response from customer service
here is some code I tried for Datalogic which did not work
var keywedge = KeyboardWedge(mBarcodeManager)
//keywedge.enable = BooleanProperty(0)
keywedge.enable.set(false)
Note. I have solved the Datalogic SDK, I only need help with Honeywell (I missed a step) here is the solution ;)
var keywedge = KeyboardWedge(mBarcodeManager)
keywedge.enable.set(false)
try{
keywedge.store(mBarcodeManager,false)
}catch (e: Exception){
Log.e(TAG, "Cannot disable Wedge", e)
}
I have resolved this one some time ago sorry for the lack of update
Honeywell
//Simply claim the scanner
try{
barcodeReader?.claim()
} catch (e: ScannerUnavailableException){
e.printStackTrace()
}
Datalogic
var keywedge = KeyboardWedge(mBarcodeManager)
keywedge.enable.set(false)
try{
keywedge.store(mBarcodeManager,false)
}catch (e: Exception){
Log.e(TAG, "Cannot disable Wedge", e)
}
Zebra
//Add the Data & Status Listeners then enable
scanner?.addDataListener(this)
scanner?.addStatusListener(this)
scanner?.enable()
Is there a way to see Android logs that were logged before connecting to the Android Studio?
I have an app that tracks GPS location. The issue is that it terminates after some time and I get the Android system message that says "Application Terminated"
I want to see what went wrong and where. When I connect Android studio later, it shows logs that happened from time it is connected.
I want the logs from past.
There are couple of things you can try to resolve:
1) I generally write logs when I have such cases to test.
public static void writeToFile(String msg) {
Log.d("MyApp", msg);
try {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
FileOutputStream dio = null;
File file = new File(Environment.getExternalStorageDirectory(), "MyApp_File_Logs.txt");
if (file != null) {
try {
dio = new FileOutputStream(file, true);
dio.write((msg+"\n").getBytes());
dio.close();
dio = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
Log.e("MyApp", "Exception in writeToFile(): " + e.getMessage());
}
}
So instead of Log.d , Use this Utility method. You can add time in the message to be more precise.
Done forget to give write external storage permission to you app
2) Once you see crash , go to command prompt
and use the below commands:
adb shell
logcat -b crash
You might see something in this, if you connect within a minute or so
3) Increase the "Logger Buffer Size " in your developer options , but in this case you will see delay in getting logs when you connect your device to adb and open logcat.
you can add a log module into your app,let log module output your app's log into local file,like logger
I am following the Zebra Android Link_OS SDK sample code for printing a test label on a ZQ510 over Bluetooth, but it won't print in ZPL format.
Here is the code I'm running to print the label:
private void sendZplOverBluetooth(final String theBtMacAddress) {
new Thread(new Runnable() {
public void run() {
try {
// Instantiate connection for given Bluetooth® MAC Address.
Connection thePrinterConn = new BluetoothConnection(theBtMacAddress);
// Initialize
Looper.prepare();
// Open the connection - physical connection is established here.
thePrinterConn.open();
// This example prints "This is a ZPL test." near the top of the label.
String zplData = "^XA^FO20,20^A0N,25,25^FDThis is a ZPL test.^FS^XZ";
// Send the data to printer as a byte array.
thePrinterConn.write(zplData.getBytes());
// Make sure the data got to the printer before closing the connection
Thread.sleep(500);
// Close the connection to release resources.
thePrinterConn.close();
Looper.myLooper().quit();
} catch (Exception e) {
// Handle communications error here.
e.printStackTrace();
}
}
}).start();
}
And here is the result of the print. (I ran it twice, that's why there are two test prints).
Then I read about how it might be in a different mode because for some reason Zebra can't detect their own proprietary language. So I tried to get the settings and see through the Android app. Again using the given Link-OS SDK example code:
private static void displaySettings(Connection c) throws ConnectionException, ZebraPrinterLanguageUnknownException, SettingsException, ZebraIllegalArgumentException {
ZebraPrinter genericPrinter = ZebraPrinterFactory.getInstance(c);
ZebraPrinterLinkOs linkOsPrinter = ZebraPrinterFactory.createLinkOsPrinter(genericPrinter);
if (linkOsPrinter != null) {
System.out.println("Available Settings for myDevice");
Set<String> availableSettings = linkOsPrinter.getAvailableSettings();
for (String setting : availableSettings) {
System.out.println(setting + ": Range = (" + linkOsPrinter.getSettingRange(setting) + ")");
}
System.out.println("\nCurrent Setting Values for myDevice");
Map<String, String> allSettingValues = linkOsPrinter.getAllSettingValues();
for (String settingName : allSettingValues.keySet()) {
System.out.println(settingName + ":" + allSettingValues.get(settingName));
}
String darknessSettingId = "print.tone";
String newDarknessValue = "10.0";
if (availableSettings.contains(darknessSettingId) &&
linkOsPrinter.isSettingValid(darknessSettingId, newDarknessValue) &&
linkOsPrinter.isSettingReadOnly(darknessSettingId) == false) {
linkOsPrinter.setSetting(darknessSettingId, newDarknessValue);
}
System.out.println("\nNew " + darknessSettingId + " Value = " + linkOsPrinter.getSettingValue(darknessSettingId));
}
}
This time, I get a SettingsException with the description of Operation cannot be performed on raw channel with a printer set to line print mode
How am I able to print ZPL text using a Mac and developing Android correctly? I read about using some Zebra Utility app for changing the mode, but it's only available for Windows, and their Android app doesn't work.
Regardless, if someone was to use the app with a printer in the incorrect mode, they would have to go through all this unnecessary setup that wouldn't be intuitive for just anybody.
Thanks for the help and appreciate any feedback.
You can programmatically set the print mode to ZPL, it's currently in line-mode.
To do so:
BluetoothConnection printerIns= new BluetoothConnection(theBtMacAddress);
ZebraPrinter zPrinterIns = ZebraPrinterFactory.getInstance(printerIns);
//Set printer to ZPL mode
zPrinterIns.sendCommand("! U1 setvar \"device.languages\" \"zpl\"\r\n");
//Feed and calibrate to the media
zPrinterIns.sendCommand("~jc^xa^jus^xz");
In your example code, You are establishing a Bluetooth connection and attempting to send raw data, make use of the ZebraPrinterand BluetoothConnection classes provided by Zebra instead from the com.zebra.sdk.printer namespace.
I corrected your code, it should work now.
new Thread(new Runnable() {
public void run() {
try {
// Instantiate connection for given Bluetooth® MAC Address.
BluetoothConnection thePrinterConn = new BluetoothConnection(theBtMacAddress);
// Initialize
Looper.prepare();
// Open the connection - physical connection is established here.
ZebraPrinter zPrinterIns = ZebraPrinterFactory.getInstance(thePrinterConn);
zPrinterIns.sendCommand("! U1 setvar \"device.languages\" \"zpl\"\r\n");
zPrinterIns.sendCommand("~jc^xa^jus^xz");
Thread.sleep(500);
// Send the data to printer as a byte array.
zPrinterIns.sendCommand("^XA^FO20,20^A0N,25,25^FDThis is a ZPL test.^FS^XZ");
// Make sure the data got to the printer before closing the connection
Thread.sleep(500);
// Close the connection to release resources.
thePrinterConn.close();
Looper.myLooper().quit();
} catch (Exception e) {
// Handle communications error here.
e.printStackTrace();
}
}
}).start();
If you don't want to perform this step programmatically like in the Dayan answer and you have acces to a Windows machine (or emulating one), install the Zebra Setup Utilities. Then following the instructions here https://km.zebra.com/kb/index?page=content&id=SO7296 to switch the print mode to ZPL with the command
! U1 setvar "device.languages" "zpl"
I am developing a restaurant app which print receipts after customer purchases foods. I have added a config screen in app which the manager uses to configure printers. A manager can print a test page to test whether he has entered right ip and port. Here is my code which prints test page:
private class PrintTask extends AsyncTask<Printer, Boolean, String> {
#Override
protected String doInBackground(Printer... params) {
try {
publishProgress(true);
Socket sock = new Socket(params[0].getIp(), Integer.parseInt(params[0].getPort()));
PrintWriter oStream = new PrintWriter(sock.getOutputStream());
oStream.printf("--------------------------------\r\n");
oStream.printf("*** TEST PRINT ***\r\n");
oStream.printf("You have configured your \n\r");
oStream.printf(params[0].getName());
oStream.printf("\r\nprinter successfully\n\r");
oStream.printf("| Thanks |\r\n");
oStream.printf("--------------------------------\r\n");
oStream.close();
sock.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
publishProgress(false);
return "";
}
#Override
protected void onProgressUpdate(Boolean... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
if(!values[0]) {
waitView.setVisibility(View.GONE);
}
else {
waitView.setVisibility(View.VISIBLE);
}
}
}
The problem is if I print on a network printer (a stand alone printer without attaching to any PC) it prints text properly. Here I am using the ip and default port 9100. But when I print to a shared printer attached to a PC, it fails to print. Any idea, where I am doing wrong...???
From what your describe it looks like that standalone printer is running some kind of "text printing service" on your given port. So looks like everything you send to this port will be printed as text.
Whereas when you have "Shared" printer on your Windows machine, it's implemented using Windows Printer service or smth like that. It's not just simple socket/port anymore where you can write ASCII text.
So I have TCP server in Windows that is programmed in C++ and a client in JAVA, Android 4.0.4.
In Android, I connect like this:
public boolean sendConnectRequest()
{
while (isSocketConnected == false)
{
try {
if(comSocket == null)
comSocket = new Socket("192.168.0.1",1531);
isSocketConnected = comSocket.isConnected();
if (isSocketConnected) {
out = comSocket.getOutputStream();
in = comSocket.getInputStream();
}
else
comSocket.close();
}
catch (IOException ex)
{
Log.e("TCP Error", ex.getLocalizedMessage());
}
}
return true;
}
I typically have no problems with this code on the first connection to the server.
When i disconnect from the server, I call this:
public void closeConnection() {
if (comSocket != null)
{
try {
comSocket.close();
isSocketConnected = false;
if (out != null)
out.close();
if (in != null)
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
So here is the problem... I hit the home button on the smartphone, which places the program in pause. I start the program again and it calls the resume function in activity, which in turn starts the process toward reconnection. The connection is attempted and i get no errors. However, my Windows server records no connection. In Windows, I know that I am still blocked at:
SOCKET connectionSocket = accept(tcpNetworkData->socket, (struct sockaddr*)&from, &fromlen);
I believe this is normal. When I am in debug mode on the Android side, I notice that it returns immediately from the line: comSocket = new Socket("192.168.0.1",1531); This should indicate to me that a connection is made.
If you follow me so far... I should also say that if I shut the server down, the client resets by closing the connection and opening a new one. This time the comSocket = new Socket("192.168.0.1",1531) does not block as it should and the execution keeps going. This is obviously wrong. I think it is a resource release problem but why? With Winsock you can solve this problem with this line of code:
int so_reuseaddr = TRUE;
setsockopt(networkData->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&so_reuseaddr,sizeof(so_reuseaddr));
Can you do something similar with Android or do you have to? Thank you for your help!
According to the javadoc the connection is established once you call the constructor.
Socket(InetAddress address, int port)
Creates a stream socket and connects it to the specified port number at the specified IP address.
When you press the home button, your app goes in background but it does not get killed immediately, so your comSocket might be not null when you get back to your application. In that case you are not calling the constructor again, thus you are not reconnecting to the server. What you should do is
if(comSocket == null){
comSocket = new Socket("192.168.0.1",1531);
}else{
comSocket.connect(new InetSocketAddress("192.168.0.1",1531));
}
(and please please place the curly brackets :-) )
Something to keep in mind is that the isConnected() method isn't very reliable for detecting when the remote side has closed the connection, (here is an example).
You have to figure this out by reading or writing on the associated Input/Output Streams.
Try using PrintWriter.checkError(), which will return true as soon as the client can no longer connect to the server.