Android 蓝牙打印机中的文本格式
实际上,我必须实现一个模块,该模块连接到BT终端打印机并在其中打印。我有一个简单但功能性的例子,它与打印机一起工作。问题是这些文本是纯文本打印的,我必须给它加上格式、粗体、更改字体大小等。。。我该怎么做??。我不知道怎么。。。我使用这个类:Android 蓝牙打印机中的文本格式,android,text,printing,bluetooth,format,Android,Text,Printing,Bluetooth,Format,实际上,我必须实现一个模块,该模块连接到BT终端打印机并在其中打印。我有一个简单但功能性的例子,它与打印机一起工作。问题是这些文本是纯文本打印的,我必须给它加上格式、粗体、更改字体大小等。。。我该怎么做??。我不知道怎么。。。我使用这个类: /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); *
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.edec.aptr;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
/**
* This class does all the work for setting up and managing Bluetooth
* connections with other devices. It has a thread that listens for incoming
* connections, a thread for connecting with a device, and a thread for
* performing data transmissions when connected.
*/
public class BluetoothService {
// Debugging
private static final String TAG = "BluetoothService";
private static final boolean D = true;
// Name for the SDP record when creating server socket
private static final String NAME = "BTPrinter";
// Unique UUID for this application
private static final UUID MY_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB"); // change by
// chongqing
// jinou
// Member fields
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private AcceptThread mAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
// Constants that indicate the current connection state
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_LISTEN = 1; // now listening for incoming
// connections
public static final int STATE_CONNECTING = 2; // now initiating an outgoing
// connection
public static final int STATE_CONNECTED = 3; // now connected to a remote
// device
/**
* Constructor. Prepares a new BTPrinter session.
*
* @param context
* The UI Activity Context
* @param handler
* A Handler to send messages back to the UI Activity
*/
public BluetoothService(Context context, Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
}
/**
* Set the current state of the connection
*
* @param state
* An integer defining the current connection state
*/
private synchronized void setState(int state) {
if (D)
Log.d(TAG, "setState() " + mState + " -> " + state);
mState = state;
// Give the new state to the Handler so the UI Activity can update
mHandler.obtainMessage(amarre.MESSAGE_STATE_CHANGE, state, -1)
.sendToTarget();
}
/**
* Return the current connection state.
*/
public synchronized int getState() {
return mState;
}
/**
* Start the service. Specifically start AcceptThread to begin a session in
* listening (server) mode. Called by the Activity onResume()
*/
public synchronized void start() {
if (D)
Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Start the thread to listen on a BluetoothServerSocket
if (mAcceptThread == null) {
mAcceptThread = new AcceptThread();
mAcceptThread.start();
}
setState(STATE_LISTEN);
}
/**
* Start the ConnectThread to initiate a connection to a remote device.
*
* @param device
* The BluetoothDevice to connect
*/
public synchronized void connect(BluetoothDevice device) {
if (D)
Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Start the thread to connect with the given device
mConnectThread = new ConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}
/**
* Start the ConnectedThread to begin managing a Bluetooth connection
*
* @param socket
* The BluetoothSocket on which the connection was made
* @param device
* The BluetoothDevice that has been connected
*/
public synchronized void connected(BluetoothSocket socket,
BluetoothDevice device) {
if (D)
Log.d(TAG, "connected");
// Cancel the thread that completed the connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Cancel the accept thread because we only want to connect to one
// device
if (mAcceptThread != null) {
mAcceptThread.cancel();
mAcceptThread = null;
}
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = mHandler.obtainMessage(amarre.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(amarre.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
/**
* Stop all threads
*/
public synchronized void stop() {
if (D)
Log.d(TAG, "stop");
setState(STATE_NONE);
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
if (mAcceptThread != null) {
mAcceptThread.cancel();
mAcceptThread = null;
}
}
/**
* Write to the ConnectedThread in an unsynchronized manner
*
* @param out
* The bytes to write
* @see ConnectedThread#write(byte[])
*/
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED)
return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
/**
* Indicate that the connection attempt failed and notify the UI Activity.
*/
private void connectionFailed() {
setState(STATE_LISTEN);
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(amarre.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(
amarre.TOAST,
"No se puede conectar al dispostivo, verifique que éste se encuentra encendido y cercano a la tablet");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
* Indicate that the connection was lost and notify the UI Activity.
*/
private void connectionLost() {
// setState(STATE_LISTEN);
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(amarre.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(amarre.TOAST,
"La conexión con el dispositivo se ha perdido");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
* This thread runs while listening for incoming connections. It behaves
* like a server-side client. It runs until a connection is accepted (or
* until cancelled).
*/
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
// Create a new listening server socket
try {
tmp = mAdapter
.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) {
Log.e(TAG, "listen() failed", e);
}
mmServerSocket = tmp;
}
public void run() {
if (D)
Log.d(TAG, "BEGIN mAcceptThread" + this);
setName("AcceptThread");
BluetoothSocket socket = null;
// Listen to the server socket if we're not connected
while (mState != STATE_CONNECTED) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "accept() failed", e);
break;
}
// If a connection was accepted
if (socket != null) {
synchronized (BluetoothService.this) {
switch (mState) {
case STATE_LISTEN:
case STATE_CONNECTING:
// Situation normal. Start the connected thread.
connected(socket, socket.getRemoteDevice());
break;
case STATE_NONE:
case STATE_CONNECTED:
// Either not ready or already connected. Terminate
// new socket.
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
}
if (D)
Log.i(TAG, "END mAcceptThread");
}
public void cancel() {
if (D)
Log.d(TAG, "cancel " + this);
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of server failed", e);
}
}
}
/**
* This thread runs while attempting to make an outgoing connection with a
* device. It runs straight through; the connection either succeeds or
* fails.
*/
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
mmDevice = device;
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(TAG, "create() failed", e);
}
mmSocket = tmp;
}
public void run() {
Log.i(TAG, "BEGIN mConnectThread");
setName("ConnectThread");
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
} catch (IOException e) {
connectionFailed();
// Close the socket
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(TAG,
"unable to close() socket during connection failure",
e2);
}
// Start the service over to restart listening mode
BluetoothService.this.start();
return;
}
// Reset the ConnectThread because we're done
synchronized (BluetoothService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
/**
* This thread runs during a connection with a remote device. It handles all
* incoming and outgoing transmissions.
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "create ConnectedThread");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
int bytes;
// Keep listening to the InputStream while connected
while (true) {
try {
byte[] buffer = new byte[256];
// Read from the InputStream
bytes = mmInStream.read(buffer);
if (bytes > 0) {
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(amarre.MESSAGE_READ, bytes, -1,
buffer).sendToTarget();
} else {
Log.e(TAG, "disconnected");
connectionLost();
// add by chongqing jinou
if (mState != STATE_NONE) {
Log.e(TAG, "disconnected");
// Start the service over to restart listening mode
BluetoothService.this.start();
}
break;
}
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
// add by chongqing jinou
if (mState != STATE_NONE) {
// Start the service over to restart listening mode
BluetoothService.this.start();
}
break;
}
}
}
/**
* Write to the connected OutStream.
*
* @param buffer
* The bytes to write
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
mHandler.obtainMessage(amarre.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
我从另一个类发送数据,因此:
byte[] send;
try {
send = message.getBytes("GB2312");
} catch (UnsupportedEncodingException e) {
send = message.getBytes();
}
mService.write(send);
消息是一个字符串变量。。那么,如何格式化文本???,或者至少更改字体大小…对此有两种看法: 您只是试图通过传递文本来打印。您正在将选项留给打印机,以选择以它想要的方式打印 检查打印机是否支持基本打印配置文件[BPP]-基于作业的传输。我成功地在蓝牙打印机上以html格式打印了它,包括图像和文本 另外,检查您提供的UUID。对于对象推送配置文件和基于BPP作业的传输配置文件,它们是不同的UUID。我建议您将UUID用于BPP[基于工作的调动] 并尝试传递带有格式化文本的xhtml文件 谢谢
现在我知道怎么做了。我不得不应用逆向工程,从市场上反编译一个.apk,在Linux上使用dex2jar,然后用java反编译打开jar。。。在编写此命令时,请尝试以下操作:
out.write(str.getBytes(),0,str.getBytes().length)代码>
您正在向该方法发送字节[]数组。在发送实际字节[]数组之前,可以通过发送另一个字节[]数组来修改格式
字节[]数组的默认格式如下:
byte[]arrayOfByte1={27,33,0}代码>
所以你可以试试这个:
byte[] format = { 27, 33, 0 };
out.write(format);
out.write(str.getBytes(),0,str.getBytes().length);
这些行将打印默认格式的文本,但如果您尝试以下代码
byte[] format = { 27, 33, 0 };
format[2] = ((byte)(0x8 | arrayOfByte1[2]));
out.write(format);
out.write(str.getBytes(),0,str.getBytes().length);
它将以粗体打印文本。。。您可以尝试以下其他格式数组:
// Bold
format[2] = ((byte)(0x8 | arrayOfByte1[2]));
// Height
format[2] = ((byte)(0x10 | arrayOfByte1[2]));
// Width
format[2] = ((byte) (0x20 | arrayOfByte1[2]));
// Underline
format[2] = ((byte)(0x80 | arrayOfByte1[2]));
// Small
format[2] = ((byte)(0x1 | arrayOfByte1[2]));
您还可以将其组合起来,然后如果您喜欢小文本和粗体文本,请取消对这些数组分配的注释,例如:
byte[] format = { 27, 33, 0 };
// Bold
format[2] = ((byte)(0x8 | arrayOfByte1[2]));
// Height
format[2] = ((byte)(0x10 | arrayOfByte1[2]));
// Width
format[2] = ((byte) (0x20 | arrayOfByte1[2]));
// Underline
// format[2] = ((byte)(0x80 | arrayOfByte1[2]));
// Small
// format[2] = ((byte)(0x1 | arrayOfByte1[2]));
out.write(format);
out.write(str.getBytes(),0,str.getBytes().length);
最后一段代码打印的文本大小最大。我知道这是一个旧线程,但它对我帮助很大,因此我决定分享我的代码,以简化格式的使用
示例用法:
final String message = "Example message\n";
// Default format:
writeWithFormat(message.getBytes(), new Formatter().get(), Formatter.leftAlign());
// Bold format center:
writeWithFormat(message.getBytes(), new Formatter().bold().get(), Formatter.centerAlign());
// Bold underlined format with right alignment:
writeWithFormat(message.getBytes(), new Formatter().bold().underlined().get(), Formatter.rightAlign());
具有生成器模式的格式化程序类:
/**
* Class for formatting
*/
public static class Formatter {
/** The format that is being build on */
private byte[] mFormat;
public Formatter() {
// Default:
mFormat = new byte[]{27, 33, 0};
}
/**
* Method to get the Build result
*
* @return the format
*/
public byte[] get() {
return mFormat;
}
public Formatter bold() {
// Apply bold:
mFormat[2] = ((byte) (0x8 | mFormat[2]));
return this;
}
public Formatter small() {
mFormat[2] = ((byte) (0x1 | mFormat[2]));
return this;
}
public Formatter height() {
mFormat[2] = ((byte) (0x10 | mFormat[2]));
return this;
}
public Formatter width() {
mFormat[2] = ((byte) (0x20 | mFormat[2]));
return this;
}
public Formatter underlined() {
mFormat[2] = ((byte) (0x80 | mFormat[2]));
return this;
}
public static byte[] rightAlign(){
return new byte[]{0x1B, 'a', 0x02};
}
public static byte[] leftAlign(){
return new byte[]{0x1B, 'a', 0x00};
}
public static byte[] centerAlign(){
return new byte[]{0x1B, 'a', 0x01};
}
}
使用格式的write方法如下所示:
/**
* Method to write with a given format
*
* @param buffer the array of bytes to actually write
* @param pFormat The format byte array
* @param pAlignment The alignment byte array
* @return true on successful write, false otherwise
*/
public boolean writeWithFormat(byte[] buffer, final byte[] pFormat, final byte[] pAlignment) {
try {
// Notify printer it should be printed with given alignment:
mOutputStream.write(pAlignment);
// Notify printer it should be printed in the given format:
mOutputStream.write(pFormat);
// Write the actual data:
mOutputStream.write(buffer, 0, buffer.length);
// Share the sent message back to the UI Activity
App.getInstance().getHandler().obtainMessage(MESSAGE_WRITE, buffer.length, -1, buffer).sendToTarget();
return true;
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
return false;
}
}
你能提供完整的代码吗?因为我想在我的应用程序中开发打印机功能。如果你能给我发邮件,我会给你发送一个示例项目,该项目可以使用ESC/POS热敏打印机打印…你好,莱昂纳多。请把项目也寄给我。到aarbiyech@gmail.comWhere你得到变量ammare了吗?你能给我同样的代码通过蓝牙打印吗?我需要为我的申请做同样的事情。ThanksHow是否删除粗体设置?例如,如果使用粗体格式打印一行,如何在不重新发送新字符串的情况下取消绑定下一行。我希望它是一个直接的命令。不管我得到了什么,只要写格式[2]=((字节)(0x0 | arrayOfByte1[2])
U被迫重新发送bytearray,如果将粗体设置为打印机,则应再次发送init数组:`byte[]format={27,33,0}`有打印直线的方法吗?设定文字的重心?只是想说莱昂纳多你很棒@Koen它正在工作,但有时校准不起作用。我错过什么了吗?。就像我在文本中心设置了对齐,但它向左对齐。有什么想法吗?@Sumit Kumar你想在一行上打印“左文本”“居中文本”“右文本”之类的内容吗?(如1行中的3列)如何使文本大于默认值?@UsmanRana Raha writeWithFormat(message.getBytes(),new Formatter().height().get(),Formatter.leftAlign());不是所有的打印机都支持ttf,但有没有在文本上设置字体类型ttf?