I can print a receipt (byte[] printer format) via a thermal printer, like this :
// Print a receipt
OutputStream outputStream = mPrinterSocket.getOutputStream();
for (byte[] packet : content)
outputStream.write(packet);
outputStream.flush();
But I can not manage to save a receipt (byte[] printer format) into a file (pdf or image).
I tried :
// Save a receipt
try (OutputStream outputStream = new FileOutputStream(filePath)) {
for (byte[] packet : content) {
outputStream.write(packet);
outputStream.flush();
}
} catch (Exception exception) {
exception.printStackTrace();
}
But it returned a corrupted file, containing:
䀛琛ᬐšℝ䴑ਊℝ䴀੍੍ㄊ⼵㔰ㄯ‹ㄱ㈺‱†††††慔汢䔛ਁ′潂獩潳獮†††††††††††ᬊE‱潃慣†††††††††††⸲〲ᬊE‱慆瑮††††††††††⸲〲ⴊⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭⴭਭ䔛吁呏䱁†††††††††䔠剕㐠㐮ਰਊ䔛䴀牥楣⃠楢湥⁴ਡਊਊᴊV
Is the process to "print a byte[] to file" different from "save a byte[] to file"? For example, I use the character {0x1b, 0x45, 0x01} to put a text in bold, is this a problem? I would like to avoid reformatting everything or using an external library.
I'd wrap the FileOutputStream into a BufferedOutputStream, instead of using a plain FOS. When reading from or writing to a file it is always a good practice to use a buffer.
Also, you don't need to flush() after each packet, just outside of the loop - as in your first example. This also improves performance.
You can use the itext library for android to create PDF file and save it. For more details Read Here
Related
I getting issue, printing through bluetooth on thermal printer from pdf file become text view.
Print Pdf file via Bluetooth Printer Android I was tried these example but didn't what I expected.
this is my current code
code file source:
String checkout = "checkout";
String fpath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) +"/"+ checkout + ".pdf";
code to printing
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum);
System.out.println("read " + readNum + " bytes,");
}
} catch (IOException ex) {
System.out.println("ERROR!");
}
byte[] bytesPDF = bos.toByteArray();
byte[] printformat = { 27, 33, 0 }; //try adding this print format
mService.write(printformat);
mService.write(bytesPDF);
I hope able to print pdf file by thermal bluetooth printer. Please help me. Thankyou.
The issue is very clear. As we can see that the printed receipt has formatting syntaxes with it. Which is used to format text and images in a PDF file. So, the printer through which you are trying to print doesn't support printing a PDF file. So, if possible you should provide the file in a compatible format such as a text file.
To know more about formatting text in a Bluetooth printer, you can have a look at this post here. Let me know whether this solves your problem or not.
The way how Thermal printer works is
Open socket connection to printer
Send the encoded data that the printer understands
Close the connection
So, the question here boils down to what's the format of the data to be sent so that the printer is able to understand it and print accordingly. It depends on the manufacturer of the Printer. The encodings are either well documented, packed into an SDK/driver for use or are open source standard encoding for ESC/POS generic printers.
At the end, what you need to do to print a PDF file is -
Convert PDF file to Bitmap[] of pages.
Encode the pages one by one by the command for printing bitmap as provided by the manufacturer.
Pass this encoded string data to the printer.
For Example, do look at the generic ESC/POS implementation in the following GitHub Repo
https://github.com/DantSu/ESCPOS-ThermalPrinter-Android
PrinterTextParserImg.bitmapToHexadecimalString()
I wrote an android application that part of it is to handle upload and download documents. Currently I am using the Microsoft Azure server to save the files on.
The way I am currently doing it is by turning the files to a string and saving it that way on the Azure server:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileInputStream fis;
try {
fis = new FileInputStream(new File(Uridata.getPath()));
byte[] buf = new byte[1024];
int n;
while (-1 != (n = fis.read(buf)))
baos.write(buf, 0, n);
} catch (Exception e) {
e.printStackTrace();
}
byte[] bbytes = baos.toByteArray();
item.setStringFile(Base64.encodeToString(bbytes, Base64.URL_SAFE));
item.setName(Uridata.getLastPathSegment());
where item is my class that saves the string representation and the name of the file and is being loaded to the Azure, Uridata is an Uri instance of the file chosen.
I have one main problem with this solution and it is the limit on the file size.
I am searching for a good server to use instead of the Azure (maybe a RESET one) and if there is a better way to save files of all kinds (pdf, word...).
I will also want in the future to use the same data in a web interface
Does anybody have any suggestions on how to do it?
Thanks in advance!
To start, you don't have to transform the file into a string, you can just save it as a file. You have the possibility of losing data by continuing to do that. See: How do I save a stream to a file in C#?
If you're looking for another service to save files, then you should look into Azure Blob Storage. It will allow you to upload as much data as you want to a storage service for arbitrary files. See for example:
https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-blobs/
I´m working on a project related with image recognition using MATLAB and I'm currently using an Android app to help with some pre-processing steps. I thought it was going to be easy to work with matrices instead of bitmaps. I finally managed to finish my algorithm and to import it to Eclipse. The problem is that I realize that I don't know how to convert a Bitmap image into something that MATLAB can read in for the purposes of my algorithm.
Do you have any ideas on how I can do this?
If I'm interpreting your question correctly, you have an image stored in the Bitmap class and you want to save this to file locally on your Android device. You then want to load this image into MATLAB for your image recognition algorithm.
Given the fact that your image is in memory via Android, you can use the method compress: http://developer.android.com/reference/android/graphics/Bitmap.html#compress(android.graphics.Bitmap.CompressFormat, int, java.io.OutputStream
You'd then use this and save the image to file, and then you can load it into MATLAB, using imread for example.
Here's some sample code you could write for your Android app. Assuming your Bitmap instance is stored in a variable called bmp, do:
FileOutputStream out = null; // For writing to the device
String filename = "out.png"; // Output file name
// Full path to save
// This accesses the pictures directory of your device and saves the file there
String output = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), filename);
try {
out = new FileOutputStream(filename); // Open up a new file stream
// Save the Bitmap instance to file
// First param - type of image
// Second param - Compression factor
// Third param - The full path to the file
// Note: PNG is lossless, so the compression factor (100) is ignored
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
}
// Catch any exceptions that happen
catch (Exception e) {
e.printStackTrace();
}
// Execute this code even if exception happens
finally {
try {
// Close the file if it was open to write
if (out != null)
out.close();
}
// Catch any exceptions with the closing here
catch (IOException e) {
e.printStackTrace();
}
}
The above code will save the image to your default Pictures directory on your device. Once you pull out that image, you can read the image into MATLAB by using imread:
im = imread('out.png');
im would thus be the raw RGB pixels of the image that you can now use for your image recognition algorithm.
My requirement is to print a file from an android device without using any cloud based service.
I have been able to achieve it using "Raw" print protocol i.e by simply sending the file to printer's IP address at Port 9100. Here is the code snippet for that:
client = new Socket(ip,port); //Port is 9100
byte[] mybytearray = new byte[(int) file.length()]; //create a byte array to file
fileInputStream = new FileInputStream(file);
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedInputStream.read(mybytearray, 0, mybytearray.length); //read the file
outputStream = client.getOutputStream();
outputStream.write(mybytearray, 0, mybytearray.length); //write file to the output stream byte by byte
outputStream.flush();
bufferedInputStream.close();
outputStream.close();
The problem with "Raw" printing protocol is that there is no way to get the status back from the printer.
So, I recently read about IPP and LDR using which we can get the status back from printer.
I have tried to find a way to implement them using android but had no success. I have already went through this answer but had no success in finding my solution.
It will be really helpful if someone can guide me on how to implement IPP or LDR in android.
Thanks in advance!
General usage of IPP:
Once a print job has been submitted the printer returns a job-id
Use the Get-Job-Attributes-Operation in order to get the current job-state
Wait until the attribute job-state equals to 9 (means 'completed')
There are other final job-states you should check for: aborted or canceled
For prototyping you could use the ipptool (native for desktop usage):
# ipptool -t -d job=482 ipp://192.168.2.113/ipp job.ipp
{
OPERATION Get-Job-Attributes
GROUP operation-attributes-tag
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
ATTR uri printer-uri $uri
ATTR integer job-id $job
}
Update 5/2020
I have published a kotlin implementation of the ipp protocol.
https://github.com/gmuth/ipp-client-kotlin
Once submitted you can wait for the print job to terminate: job.waitForTermination()
My android program crashes on this line when the file size is very large. Is there any way I can prevent the program from crashing ?
byte[] myByteArray = new byte[(int)mFile.length()];
Additional details :-
I am trying to send a file to server.
error log-
E/dalvikvm-heap(29811): Out of memory on a 136309996-byte allocation.
You should use a stream when reading the file. Since you've mentioned sending to a server, you should stream that file to the server.
As others have mentioned, you should consider your data size (1GB seems excessive). I haven't tested this, but the basic approach in code would look something like:
// open a stream to the file
FileInputStream fileInputStream = new FileInputStream(filePath);
// open a stream to the server
HttpURLConnection connection = new URL(url).openConnection();
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
byte[] buffer = new byte[BUFFER_SIZE]; // pick some buffer size
int bytesRead = 0;
// continually read from the file into the buffer and immediately write that to output stream
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
outputStream.write(buffer);
}
Hope that is clear enough for you to fit to your needs.
Yep. Don't try to read the whole file into memory at once...
If you really need the whole file in memory you might have more luck with allocating dynamic memory for each line and storing the lines in a list. (you might be able to get a bunch of smaller chunks of memory but not one big piece)
Without knowing the context we can't tell, but normally you would parse the file into data structs rather than just storing the whole file in memory.
In JDK 7 you can use Files.readAllBytes(Path).
Example:
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path;
Path path = Paths.get("path/to/file");
byte[] myByteArray = Files.readAllBytes(path);
Don't try reading the complete file into memory. Instead open a stream and process the file line by line (is it's a text file) or in parts. How that has to be done depends on the problem you are trying to solve.
EDIT: You say you want to upload a file, so please check this question. You don't need to have the complete file in memory.