/** 装载要打印的数据 */
private void initPrintData() {
AlertUtil.showLoadingMessage(this);
OrderDetails details = adapter.getData();
StringBuffer sb = new StringBuffer();
// 排版标题
sb.append(BluetoothPrintFormatUtil.printTitle("xx网\n"))
.append(BluetoothPrintFormatUtil.printTitle("www.baidu.com\n")).append("\n\n" + line + "\n");
// 排版订单信息
LinkedHashMap MsgMap = new LinkedHashMap();
sb.append("订单编号:" + details.getOrderId() + bar);
ArrayList arr = details.getStateloglist();
if (arr.size() != 0) {
sb.append("下单时间:" + startTime + bar);
}
sb.append("打印时间:" + DateUtils.getYearAndDay2(0) + bar);
sb.append(line + bar);
for (int i = 0; i < details.getStoreList().size(); i++) {
for (int j = 0; j < details.getStoreList().get(i).getPlist().size(); j++) {
String type = details.getStoreList().get(i).getPlist().get(j).getType();
if(type==null||"".equals(type)){
type="kg";
}
double weight = details.getStoreList().get(i).getPlist().get(j).getWeight();
sb.append(details.getStoreList().get(i).getPlist().get(j).getProductName() + bar);
MsgMap.put(details.getStoreList().get(i).getPlist().get(j).getCount()+"份"+" 重约" + CommonUtil.getDouble(weight) + type,
"¥" + details.getStoreList().get(i).getPlist().get(j).getPrice() + bar);
sb.append(BluetoothPrintFormatUtil.printMiddleMsg(MsgMap));
MsgMap.clear();
}
}
sb.append(line + bar);
MsgMap.put("运费", "+¥" + details.getShipPrice() + bar);
if(details.getOneYuan()>0){
MsgMap.put("一元购", "-¥" + details.getOneYuan() + bar);
}
if(details.getFirstDiscount()>0){
MsgMap.put("首单减免", "-¥" + details.getFirstDiscount() + bar);
}
if(details.getOverDiscount()>0){
MsgMap.put("满减优惠", "-¥" + details.getOverDiscount() + bar);
}
if(details.getBonusPay()>0){
MsgMap.put("红包抵扣", "-¥" + details.getBonusPay() + bar);
}
if(details.getHalfPrice()>0){
MsgMap.put("第二件半价", "-¥" + details.getHalfPrice() + bar);
}
MsgMap.put("订单总价", "¥" + details.getSOAmout() + bar);
sb.append(BluetoothPrintFormatUtil.printMiddleMsg(MsgMap));
MsgMap.clear();
sb.append(line + bar);
StringBuffer sb2 = new StringBuffer();
MsgMap.put("实付金额", "¥" + details.getCashPay() + bar);
sb2.append(BluetoothPrintFormatUtil.printMiddleMsg(MsgMap));
MsgMap.clear();
sb2.append(line + bar);
sb2.append("客户姓名:" + details.getReceiveName() + bar);
sb2.append("电话号码:" + details.getCellPhone() + bar);
sb2.append("配送时间:" + details.getDeliveryTime() + bar);
sb2.append("收货地址:" + details.getReceiveAddress() + bar);
sb2.append("订单备注:" + details.getMemo() + bar + bar + bar + bar + bar);
sb2.append(BluetoothPrintFormatUtil.printMiddleMsg(MsgMap));
MsgMap.clear();
AlertUtil.dismiss(this);
/**进入蓝牙列表页面*/
Intent intent = new Intent(OrderDetailsActivity.this, BluetoothSelectActivity.class);
intent.putExtra("data", sb.toString());
intent.putExtra("data2", sb2.toString());
intent.putExtra("orderid", details.getOrderId());
startActivity(intent);
}
然后是排版的类,我用的58mm的热敏蓝牙打印机
只用了2个方法,
/**
* 打印纸一行最大的字节
*/
private static final int LINE_BYTE_SIZE = 32;
private static StringBuffer sb = new StringBuffer();
/**
* 排版居中标题
* @param title
* @return
*/
public static String printTitle(String title){
sb.delete(0, sb.length());
for(int i=0;i<(LINE_BYTE_SIZE - getBytesLength(title))/2;i++){
sb.append(" ");
}
sb.append(title);
return sb.toString();
}
/**
* 排版左右靠边的内容
*
* 例:姓名 李白
* 病区 5A病区
* 住院号 11111
*
* @param msg
* @return
*/
public static String printMiddleMsg(LinkedHashMap middleMsgMap){
sb.delete(0, sb.length());
String separated = " ";
//将一张纸的宽度除去边缘的距离之后一分为二
int leftLength = (LINE_BYTE_SIZE-getBytesLength(separated))/2;
for(Entry middleEntry : middleMsgMap.entrySet()){
//第一部分先写数据,剩余的填充空格,空格的数量为左半部分长度减去数据长度
sb.append(middleEntry.getKey());
for(int i=0;i<(leftLength-getBytesLength(middleEntry.getKey()));i++){
sb.append(" ");
}
//第二部分先填充空格,再写数据,空格的数量为左半部分长度减去数据长度
int size=leftLength-getBytesLength(middleEntry.getValue());
for (int i = 0; i < size; i++) {
sb.append(" ");
}
sb.append(middleEntry.getValue());
}
return sb.toString();
}
这个排版类是在csdn上下载的,准确的说,点都不好用,还是我自己去改的,不过思路很好,类里面还提供了别的方法,但是没有测试过,所以不给出,附链接:http://blog.csdn.net/qq331710168/article/details/9170135
打开蓝牙并让自己的手机能在120秒内被搜索到
//打开蓝牙
Intent enableBtIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(enableBtIntent, 1);
操作蓝牙的类
public class BluetoothService {
private Context context = null;
private BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private ArrayList unbondDevices = null; // 用于存放未配对蓝牙设备
private ListView unbondDevicesListView = null;
private String data = "",data2="";
ProgressDialog progressDialog = null;
/**
* 添加未绑定蓝牙设备到ListView
*/
private void addUnbondDevicesToListView() {
ArrayList> data = new ArrayList>();
int count = this.unbondDevices.size();
System.out.println("未绑定设备数量:" + count);
for (int i = 0; i < count; i++) {
HashMap map = new HashMap();
map.put("deviceName", this.unbondDevices.get(i).getName());
data.add(map);// 把item项的数据加到data中
}
String[] from = { "deviceName" };
int[] to = { R.id.undevice_name };
SimpleAdapter simpleAdapter = new SimpleAdapter(this.context, data, R.layout.unbonddevice_item, from, to);
// 把适配器装载到listView中
this.unbondDevicesListView.setAdapter(simpleAdapter);
// 为每个item绑定监听,用于设备间的配对
this.unbondDevicesListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView> arg0, View arg1, int arg2, long arg3) {
try {
AlertUtil.showLoadingMessage(context);
BluetoothDevice device = unbondDevices.get(arg2);
PrintDataService printDataService = new PrintDataService(context, device.getAddress(),BluetoothService.this.data,BluetoothService.this.data2);
if(printDataService.connect()){
printDataService.send();
}
} catch (Exception e) {
AlertUtil.showErrorMessage(context, "配对失败!");
}
}
});
}
public BluetoothService(Context context, ListView unbondDevicesListView, String data,String data2) {
this.context = context;
this.unbondDevicesListView = unbondDevicesListView;
this.unbondDevices = new ArrayList();
this.data = data;
this.data2 = data2;
this.initIntentFilter();
}
private void initIntentFilter() {
// 设置广播信息过滤
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
// 注册广播接收器,接收并处理搜索结果
context.registerReceiver(receiver, intentFilter);
}
/**
* 打开蓝牙
*/
public void openBluetooth(Activity activity) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
activity.startActivityForResult(enableBtIntent, 1);
}
/**
* 关闭蓝牙
*/
public void closeBluetooth() {
this.bluetoothAdapter.disable();
}
/**
* 判断蓝牙是否打开
*
* @return boolean
*/
public boolean isOpen() {
return this.bluetoothAdapter.isEnabled();
}
/**
* 搜索蓝牙设备
*/
public void searchDevices() {
this.unbondDevices.clear();
// 寻找蓝牙设备,android会将查找到的设备以广播形式发出去
this.bluetoothAdapter.startDiscovery();
}
/**
* 取消搜索蓝牙设备
*/
public void cancelDevices() {
this.unbondDevices.clear();
if(progressDialog!=null){
progressDialog.dismiss();
}
// 取消寻找蓝牙设备
this.bluetoothAdapter.cancelDiscovery();
}
/**
* 添加未绑定蓝牙设备到list集合
*
* @param device
*/
public void addUnbondDevices(BluetoothDevice device) {
System.out.println("未绑定设备名称:" + device.getName());
if (!this.unbondDevices.contains(device)) {
this.unbondDevices.add(device);
}
}
/**
* 添加已绑定蓝牙设备到list集合
*
* @param device
*/
public void addbondDevices() {
Set devices = this.bluetoothAdapter.getBondedDevices();
for (BluetoothDevice device : devices) {
if (!this.unbondDevices.contains(device)) {
this.unbondDevices.add(device);
}
}
addUnbondDevicesToListView();
}
/**
* 蓝牙广播接收器
*/
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
addUnbondDevices(device);
} else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
progressDialog = ProgressDialog.show(context, "请稍等...", "搜索蓝牙设备中...", true);
progressDialog.setOnKeyListener(onKeyListener);
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
System.out.println("设备搜索完毕");
if(progressDialog!=null){
progressDialog.dismiss();
}
addUnbondDevicesToListView();
}
}
};
private OnKeyListener onKeyListener = new OnKeyListener() {
//监听返回键
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
cancelDevices();
}
return false;
}
};
}
bluetoothService.searchDevices();方法会发起一个长达2分钟的广播搜索,很耗时,不建议使用,直接用手机自带的蓝牙配对之后再执行bluetoothService.addbondDevices();要快无数倍,不建议使用
try { AlertUtil.showLoadingMessage(context); BluetoothDevice device = unbondDevices.get(arg2); PrintDataService printDataService = new PrintDataService(context, device.getAddress(),BluetoothService.this.data,BluetoothService.this.data2); if(printDataService.connect()){ printDataService.send(); } } catch (Exception e) { AlertUtil.showErrorMessage(context, "配对失败!"); }
if (device.getBondState() == BluetoothDevice.BOND_NONE) {
Method creMethod = BluetoothDevice.class.getMethod("createBond");
Log.e("TAG", "开始配对");
creMethod.invoke(device);
}
public class PrintDataService {
private Context context = null;
private String deviceAddress = null;
private BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private BluetoothDevice device = null;
private static BluetoothSocket bluetoothSocket = null;
private static OutputStream outputStream = null;
private String sendData = "" ,sendData2 = "";
private Bitmap bitmap;
// private static final UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static UUID uuid=null;
final String[] items = { "复位打印机", "标准ASCII字体", "压缩ASCII字体", "字体不放大", "宽高加倍", "取消加粗模式", "选择加粗模式", "取消倒置打印", "选择倒置打印",
"取消黑白反显", "选择黑白反显", "取消顺时针旋转90°", "选择顺时针旋转90°" };
final byte[][] byteCommands = { { 0x1b, 0x40 }, // 复位打印机
{ 0x1b, 0x4d, 0x00 }, // 标准ASCII字体
{ 0x1b, 0x4d, 0x01 }, // 压缩ASCII字体
{ 0x1d, 0x21, 0x00 }, // 字体不放大
{ 0x1d, 0x21, 0x11 }, // 宽高加倍
{ 0x1b, 0x45, 0x00 }, // 取消加粗模式
{ 0x1b, 0x45, 0x01 }, // 选择加粗模式
{ 0x1b, 0x7b, 0x00 }, // 取消倒置打印
{ 0x1b, 0x7b, 0x01 }, // 选择倒置打印
{ 0x1d, 0x42, 0x00 }, // 取消黑白反显
{ 0x1d, 0x42, 0x01 }, // 选择黑白反显
{ 0x1b, 0x56, 0x00 }, // 取消顺时针旋转90°
{ 0x1b, 0x56, 0x01 },// 选择顺时针旋转90°
{ 0x1b, 0x21, 13 },// 字体放大
};
Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
if(msg.what==1000){
send();
}
};
};
public PrintDataService(Context context, String deviceAddress,String sendData,String sendData2) {
super();
this.context = context;
this.deviceAddress = deviceAddress;
this.sendData=sendData;
this.sendData2=sendData2;
this.device = this.bluetoothAdapter.getRemoteDevice(this.deviceAddress);
ParcelUuid[] uuids= this.device.getUuids();
uuid = UUID.fromString(uuids[0].toString());
}
/**
* 获取设备名称
*
* @return String
*/
public String getDeviceName() {
return this.device.getName();
}
/**
* 连接蓝牙设备
*/
public boolean connect() {
if (bluetoothSocket==null||!bluetoothSocket.isConnected()) {
try {
if (device.getBondState() == BluetoothDevice.BOND_NONE) {
Method creMethod = BluetoothDevice.class.getMethod("createBond");
Log.e("TAG", "开始配对");
creMethod.invoke(device);
}
int sdk = Integer.parseInt(Build.VERSION.SDK);
if (sdk >= 10) {
bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
} else {
bluetoothSocket = device.createRfcommSocketToServiceRecord(uuid);
}
bluetoothSocket.connect();
outputStream = bluetoothSocket.getOutputStream();
if (this.bluetoothAdapter.isDiscovering()) {
System.out.println("关闭适配器!");
this.bluetoothAdapter.cancelDiscovery();
}
} catch (Exception e) {
AlertUtil.showErrorMessage(context, "连接失败!");
return false;
}
AlertUtil.showSuccessMessage(context, this.device.getName() + "连接成功!");
return true;
} else {
return true;
}
}
/**
* 断开蓝牙设备连接
*/
public static void disconnect() {
System.out.println("断开蓝牙设备连接");
try {
bluetoothSocket.close();
outputStream.close();
bluetoothSocket=null;
outputStream=null;
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 选择指令
*/
public void selectCommand() {
new AlertDialog.Builder(context).setTitle("请选择指令").setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
outputStream.write(byteCommands[which]);
} catch (IOException e) {
Toast.makeText(context, "设置指令失败!", Toast.LENGTH_SHORT).show();
}
}
}).create().show();
}
/**
* 发送数据
*/
public void send() {
if (outputStream != null) {
System.out.println("开始打印!!");
try {
for (int i = 0; i < 2; i++) {
byte[] data = sendData.getBytes("gbk");
outputStream.write(byteCommands[0]);
outputStream.write(data, 0, data.length);
outputStream.flush();
byte[] data2 = sendData2.getBytes("gbk");
outputStream.write(byteCommands[13]);
outputStream.write(data2, 0, data2.length);
outputStream.flush();
}
AlertUtil.showSuccessMessage(context, "数据打印完成",new OnClickListener() {
@Override
public void onClick(View v) {
//数据打印完成后关闭蓝牙选择页面
Intent intent=new Intent();
intent.setAction(GlobalConstant.BROADCAST_BLUETOOTH_FINISH);
context.sendBroadcast(intent);
}
});
} catch (IOException e) {
AlertUtil.showErrorMessage(context, "数据发送失败!");
}finally{
disconnect();
}
} else {
AlertUtil.showErrorMessage(context, "设备未连接,请重新连接!");
}
}
}
BluetoothSocket在连接完之后,下次连接之前一定要好好清理掉,不然下次是无法连接的,原demo只有2个页面,一个选择蓝牙连接,一个输入数据打印,退出的时候可能是调用了这个方法的,但是我没注意到!!!我每次都是开机之后第一次可以连,第二次就不行了!!!找了2天才梦到是不是因为这个原因,气得要死,,,不过主要原因还是因为自己对BluetoothSocket完全不熟悉导致的,写个文纪念一下
/**
* 断开蓝牙设备连接
*/
public static void disconnect() {
System.out.println("断开蓝牙设备连接");
try {
bluetoothSocket.close();
outputStream.close();
bluetoothSocket=null;
outputStream=null;
} catch (IOException e) {
e.printStackTrace();
}
}