Android作為一個面向手機和平闆的作業系統,主要擅長娛樂和通信方面的應用,由于接口方面的限制,對于其它外部裝置的支援不是很強,而且多數外設生産廠商也不支援Android系統。
所幸的是,幾乎所有智能手機都帶有藍牙功能,隻要遵循特定的通信協定,我們可以通過藍牙功能,調用所有支援藍牙的外部裝置。
列印機是最常見的外部裝置,而其中的發票列印機,廣泛應用于超市收銀、票據、回執列印,是商務應用不可或缺的組成部分。下面就以群索QS5803藍牙熱敏發票列印機為例,說明C++ Builder XE7如何調用它進行列印。
一、與列印機進行配對
與任何藍牙裝置進行通訊之前,必須與其進行配對。打開群索QS5803列印機電源,在Android系統中點“設定->藍牙”,可以搜尋到該裝置的名稱QSPrinter,選擇,輸入配對密碼,預設為“0000”,具體可參看說明書。
二、擷取系統中已經配對的藍牙裝置
1. 打開C++ Builder XE7,建立一個Android工程,添加頭檔案以支援藍牙功能
#include <System.Bluetooth.hpp>
2. 通過藍牙管理器對象,擷取本機已配對的藍牙裝置
放置一個組合框ComboEdit1和一個按鈕Button1,用于填充藍牙裝置名稱
[cpp] view plain copy
- void __fastcall TMainForm::Button1Click(TObject *Sender)
- {
- TBluetoothManager *FBluetoothManager = TBluetoothManager::Current; //得到本機藍牙管理器
- TBluetoothAdapter *FAdapter = FBluetoothManager->CurrentAdapter; //得到本機藍牙裝置
- if(FBluetoothManager->ConnectionState == TBluetoothConnectionState::Connected) //如果有并且打開了藍牙裝置
- {
- Memo1->Lines->Add(L"得到本機藍牙裝置: '" + FBluetoothManager->CurrentAdapter->AdapterName + L"'");
- ComboEdit1->Clear();
- TBluetoothDeviceList *FPairedDevices = FBluetoothManager->GetPairedDevices(); //得到已配對裝置清單
- if(FPairedDevices->Count > 0)
- {
- for(int i = 0; i < FPairedDevices->Count; i++)
- {
- ComboEdit1->Items->Add(FPairedDevices->Items[i]->DeviceName);
- }
- if(ComboEdit1->Count > 0)
- ComboEdit1->ItemIndex = 0;
- }
- else
- {
- Memo1->Lines->Add(L"無配對裝置");
- }
- }
- else //無藍牙裝置或者未打開
- {
- Memo1->Lines->Add(L"本機沒有或未打開藍牙裝置");
- }
- }
三、擷取裝置中提供的服務
每個藍牙裝置都提供有一個或若幹個服務,用不同的UUID字元串表示。需要擷取該服務,才能與藍牙裝置通訊。
放置第二個組合框ComboEdit2和一個按鈕Button2,用于填充該裝置的服務名稱
[cpp] view plain copy
- void __fastcall TMainForm::Button2Click(TObject *Sender)
- {
- ComboEdit2->Clear();
- if(ComboEdit1->ItemIndex > -1)
- {
- TBluetoothDevice * LDevice = FPairedDevices->Items[ComboEdit1->ItemIndex];
- TBluetoothServiceList * LServices = LDevice->GetServices(); //擷取該已配對裝置提供的服務
- for(int i=0; i<LServices->Count; i++)
- {
- ComboEdit2->Items->Add(GUIDToString(LServices->Items[i].UUID));
- }
- if(ComboEdit2->Count > 0)
- ComboEdit2->ItemIndex = 0;
- }
- else
- {
- ShowMessage(L"請在已配對清單中選擇一個裝置");
- }
- }
四、連接配接列印機
[cpp] view plain copy
- UnicodeString strServiceGUID = ComboEdit2->Items->Strings[ComboEdit2->ItemIndex]; //服務GUID
- TBluetoothDevice * LDevice = FPairedDevices->Items[ComboEdit1->ItemIndex];
- Memo1->Lines->Add(L"準備連接配接服務:" + strServiceGUID);
- Memo1->GoToTextEnd();
- FSocket = LDevice->CreateClientSocket(StringToGUID(strServiceGUID), false); //建立與藍牙裝置的Socket通訊
- if(FSocket != NULL)
- {
- try
- {
- FSocket->Connect(); //連接配接
- BluetoothReadTH = new TBluetoothReadTH(false, FSocket); //建立讀資料線程
- Memo1->Lines->Add(L"連接配接Socket成功!");
- Memo1->GoToTextEnd();
- }
- catch(...)
- {
- delete FSocket;
- FSocket = NULL;
- Memo1->Lines->Add(L"連接配接Socket失敗!");
- Memo1->GoToTextEnd();
- }
- }
- else
- {
- ShowMessage(L"發送逾時(15秒)");
- }
五、發送資料并列印
根據該列印機的通訊協定,發送要列印的内容和控制指令
[cpp] view plain copy
- //發送列印内容
- TBytes ToSend = TEncoding::ANSI->GetBytes(AnsiString(Edit1->Text));
- FSocket->SendData(ToSend);
- Memo1->Lines->Add(L"發送資料:" + Edit1->Text);
- Memo1->GoToTextEnd();
- //列印并走紙一行指令
- TBytes bt;
- bt.set_length(1);
- bt[0]=0x0D;
- FSocket->SendData(bt);
六、關于列印圖像
需要将圖檔轉換成yuv數組,其中隻取y部分組成新的數組,其中數組的内容轉換成0,1,大于0的部分全是1,小于零的部分全是0,将數組進行打包,通過左移操作,每八個轉換成一個新的byte位元組組成新的數組,列印内容每行576個像素(80mm列印機,如果是58mm列印機則為384像素),其中通過左移操作,每八個轉成一個位元組實際上每行也就成為48個byte,其中在列印每行的時候需要加入頭數組,頭數組為4個位元組,加入頭數組
bytehead[0] = (byte) 0x1f;
bytehead[1] = (byte) 0x10;
bytehead[2] = (byte) (mWidth / 8); //其中mWidth為寬度576
bytehead[3] = (byte) 0x00; //将新生成的數組通過藍牙傳遞給列印機。
七、總結
列印操作是一個比較耗時的過程,上面代碼隻是簡單示例,在實際應用中,應該将讀寫藍牙資料放線上程中進行。具體内容詳見示例程式:
http://download.csdn.net/detail/realbay/8689849
列印機網址:
http://detail.1688.com/offer/36926154653.html?spm=a2615.2177701.0.0.UcjyXR
示例程式效果如下:
轉載:http://blog.csdn.net/realbay/article/details/45666701