最近在研究Android的藍(lán)牙打印機(jī)程序,中間遇到了很多坑。請在這里分享我的經(jīng)驗。
先來看打印過程:
1、申請必要的權(quán)限
2、確定本機(jī)有藍(lán)牙硬件,并且打開藍(lán)牙適配器
3、開通廣播接收功能,用于發(fā)現(xiàn)藍(lán)牙設(shè)備回傳的周圍藍(lán)牙設(shè)備
4、發(fā)送藍(lán)牙發(fā)現(xiàn)信號廣播,周邊設(shè)備收到這個信號后,會回傳自己的mac地址和設(shè)備名
5、通過廣播收到周邊藍(lán)牙設(shè)備mac,通過mac地址,連接到指定的藍(lán)牙打印機(jī),獲取socket。
6、通過socket發(fā)送GB2312編碼的字符串,打印完成。
熱敏打印機(jī)一般都自帶字庫,所以直接發(fā)送文字給打印機(jī)就可以打印出想要的東西,如果要打印其它字體、圖片、二維碼和條形碼,只能通過ESC指令,把這些換算成坐標(biāo),通過寫點的方式打印。
ESC打印控制指令,可以對文字大小、對齊進(jìn)行各種控制,大家可以網(wǎng)上搜索具體指令。
部分源代碼來源于網(wǎng)上整理。
請使用手機(jī)真機(jī)測試,并且打開需要的各種權(quán)限,特別是打開手機(jī)上的位置獲取權(quán)限,因為這個我在手機(jī)上沒有打開,一直沒有收到設(shè)備廣播數(shù)據(jù),折騰了很久。
下面看源代碼
AndroidMani
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=";
xmlns:tools=";
package="com.exam;>
<uses-permission android:name="android.; />
<uses-permission android:name="android.; />
<uses-permission android:name="android.; />
<!-- 藍(lán)牙-->
<uses-permission android:name="android.;/>
<uses-permission android:name="android.;/>
<uses-permission android:name="android.; />
<uses-permission android:name="android.;/>
<!-- 僅在支持BLE(即藍(lán)牙4.0)的設(shè)備上運行-->
<uses-permission android:name="android.; android:required="true"/>
<!-- 如果Android 6.0藍(lán)牙搜索不到設(shè)備,需要補(bǔ)充下面兩個權(quán)限-->
<uses-permission android:name="android.;/>
<uses-permission android:name="android.;/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style;>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.in; />
<category android:name="android.in; />
</intent-filter>
</activity>
</application>
</manifest>
MainAc
注意那個UUID,不可以隨便修改,不然無法連接上打印機(jī),我這里省略了顯示藍(lán)牙設(shè)備列表的程序,找到打印就直接使用了。
package com.exam;
import androidx.anno;
import androidx.a;
import android.anno;
import android.blue;
import android.blue;
import android.blue;
import android.blue;
import android.con;
import android.con;
import android.con;
import android.conFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.u;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import java.io.OutputStream;
import java.u;
public class MainActivity extends AppCompatActivity {
private Button btn_bt_open;
private Button btn_bt_start;
private TextView txtinfo;
private BluetoothAdapter mBluetooth;
private int mOpenCode = 0x01;
private BluetoothDevice deviceprint;
//通過廣播,接收周邊藍(lán)牙設(shè)備信息
private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {
@SuppressLint("MissingPermission")
@Override
public void onReceive(Context context, Intent intent) {
String action = in();
Log.i("myapp", "action:" + action);
//獲得已經(jīng)搜索到的藍(lán)牙設(shè)備
if )) {//發(fā)現(xiàn)新的藍(lán)牙設(shè)備
BluetoothDevice device = in);
Log.i("myapp", "Find:" + device.getAddress());
Log.i("myapp", "Find:" + device.getName());
if ().equals("99:32:88:A6:19:FE")) {
//找到打印機(jī)直接使用
deviceprint = mBlue("99:32:88:A6:19:FE");
mBlue();
}
}
}
};
@Override
protected void onStart() {
();
//需要過濾多個動作,則調(diào)用IntentFilter對象的addAction添加新動作
IntentFilter discoveryFilter = new IntentFilter();
Log.i("myapp", "Reg discoverReceiver");
di);
//注冊藍(lán)牙設(shè)備搜索的廣播接收器
Intent intent = registerReceiver(discoveryReceiver, discoveryFilter);
}
@Override
protected void onStop() {
();
//注銷藍(lán)牙設(shè)備搜索的廣播接收器
unregisterReceiver(discoveryReceiver);
}
@SuppressLint("MissingPermission")
private void beginDiscovery() {
//如果當(dāng)前不是正在搜索,則開始新的搜索任務(wù)
if () != true) {
Log.i("myapp", "Start find BlueTooth");
mBlue();//開始掃描周圍的藍(lán)牙設(shè)備
}
}
@SuppressLint("MissingPermission")
private void startBluetooth() {
//彈出是否允許掃描藍(lán)牙設(shè)備的選擇對話框
Intent intent = new Inten);
startActivityForResult(intent, mOpenCode);
}
BluetoothSocket socket;
@SuppressLint("MissingPermission")
private void printtxt() {
if (deviceprint == null) return;
if ()) mBlue();//關(guān)閉掃描
UUID uuid= UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//不可以修改,這個值對應(yīng)打印機(jī)
try {
socket = device(uuid);
} catch (IOException e) {
e.printStackTrace();
}
new Thread() { //藍(lán)牙連接必須新開一個線程
@Override
public void run() {
if (socket == null) return;
try {
if () == false();
String otxt = "OK\r\n打印漢字測試\r\nHeHe\r\n";
OutputStream outs = ();
//InputStream ins=();
ou(0x1B);
ou(0x40);
ou(); //ESC初始化打印機(jī)
ou(0x1B);
ou(0x61);
ou(0x0); //0居左 1居中 2 居右
ou(); //ESC初始化打印機(jī)
ou("gb2312")); //這里必須與打印機(jī)內(nèi)部編碼一樣,不然打印漢字是亂碼
ou();
("myapp","input:"+S())
ou();
Log.i("myapp", "print finish");
();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 初始化藍(lán)牙適配器
*/
private void initBluetooth() {
//Android從4.3開始增加支持BLE技術(shù)(即藍(lán)牙4.0以上版本)
if >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
//從系統(tǒng)服務(wù)中獲取藍(lán)牙管理器
BluetoothManager bm = (BluetoothManager) getSystemService);
mBluetooth = bm.getAdapter();
Log.i("myapp", "從系統(tǒng)服務(wù)中獲取藍(lán)牙管理器");
} else {
//獲取系統(tǒng)默認(rèn)的藍(lán)牙適配器
mBluetooth = Blue();
Log.i("myapp", "獲取系統(tǒng)默認(rèn)的藍(lán)牙適配器");
}
if (mBluetooth == null) {
("本機(jī)沒有藍(lán)牙");
Log.i("findresult", "沒有找到藍(lán)牙");
} else {
("本機(jī)有藍(lán)牙設(shè)備");
Log.i("findresult", "本機(jī)有藍(lán)牙");
startBluetooth();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
(savedInstanceState);
setContentView);
btn_bt_open = (Button) findViewById);
btn_bt_start = (Button) findViewById);
txtinfo = (TextView) findViewById);
b(new View.OnClickListener() {
@Override
public void onClick(View view) {
initBluetooth();
}
});
b(new View.OnClickListener() {
@Override
public void onClick(View view) {
printtxt();
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
(requestCode, resultCode, data);
if (requestCode == mOpenCode) {//來自允許藍(lán)牙掃描的對話框
if (resultCode == 120) {
("允許本地藍(lán)牙被附近的其他藍(lán)牙設(shè)備發(fā)現(xiàn)");
//延遲50毫秒后啟動藍(lán)牙設(shè)備的刷新任務(wù)
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Log.i("myApp", "開始查找藍(lán)牙...");
beginDiscovery();
}
}, 50);
} else {
("不允許藍(lán)牙被附近的其他藍(lán)牙設(shè)備發(fā)現(xiàn)");
}
}
}
}
ac
<?xml version="1.0" encoding="utf-8"?>
<androidx.con xmlns:android=";
xmlns:app=";
xmlns:tools=";
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp">
<Button
android:id="@+id/btn_bt_open"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="獲取藍(lán)牙" />
<Button
android:id="@+id/btn_bt_print"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="藍(lán)牙打印" />
<TextView
android:id="@+id/textinfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
</androidx.con>
1.《藍(lán)牙熱敏打印機(jī)安卓源代碼分析》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點,與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《藍(lán)牙熱敏打印機(jī)安卓源代碼分析》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進(jìn)行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。
3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/why/3054818.html