蓝牙链接:
Android做蓝牙开发最大的也是唯一的一个坑就是你要分清楚传统蓝牙和低功耗蓝牙(Bluetooth Low Energy),他们的API不一样,也不通用。
区别他们也很容易:低功耗蓝牙顾名思义,用于功耗低的设备,比如各种智能手环、心率仪。你可以直接查阅官方文档,我认为官方文档是最好的资料,里面有很详细的例子,传统蓝牙有中文翻译,低功耗蓝牙则没有
android中蓝牙的打开、搜索主要分为以下几步。
1.在AndroidManifest.xml中添加蓝牙权限。
<!-- 管理蓝牙设备的权限 -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- 在sd卡中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
? ? tools:ignore="ProtectedPermissions"/>
<!-- 向SD卡写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CLEAR_APP_CACHE"
? ? tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
2.启动蓝牙
private?boolean?openBtDevice()?{?
//?获得蓝牙匹配器?
mBluetoothAdapter?=?BluetoothAdapter.getDefaultAdapter();?
//?蓝牙设备不被支持?
if?(mBluetoothAdapter?==?null)?{?
Log.e(TAG,?"Your?device?is?not?support?Bluetooth!");?
Toast.makeText(this,?"该设备没有蓝牙设备",?Toast.LENGTH_LONG).show();?
return?false;?
}?
//?使能蓝牙设备?
if?(!mBluetoothAdapter.isEnabled())?{?
//?隐式Intent?
Intent?enableBtIntent?=?new?Intent(?
BluetoothAdapter.ACTION_REQUEST_ENABLE);?
startActivityForResult(enableBtIntent,?REQUES_BT_ENABLE_CODE);?
}?else?{?
Toast.makeText(this,?"蓝牙打开成功!",?Toast.LENGTH_SHORT).show();?
}?
return?true;?
}?
//?当startActivityForResult启动的?画面结束的时候,该方法被回调?
@Override?
protected?void?onActivityResult(int?requestCode,?int?resultCode,?Intent?data)?{?
if?(requestCode?==?REQUES_BT_ENABLE_CODE?&&?resultCode?==?RESULT_OK)?{?
Toast.makeText(this,?"蓝牙打开成功!",?Toast.LENGTH_SHORT).show();?
}?
}
3.搜索蓝牙
已经配对过的蓝牙设备
private?void?findBtDevice()?{?
Set?pairedDevices?=?mBluetoothAdapter.getBondedDevices();?
if?(pairedDevices.size()?>?0)?{?
for?(BluetoothDevice?device?:?pairedDevices)?{?
if?(mDeviceList.contains(device))?{?
return;?
}?
mArrayAdapter.add(device.getName()?+?"\n"?+?device.getAddress());?
mDeviceList.add(device);?
}?
}?
adapter.notifyDataSetChanged();?
}
动态注册广播搜索蓝牙
IntentFilter?filter?=?new?IntentFilter(BluetoothDevice.ACTION_FOUND);?
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);?
registerReceiver(mReceiver,?filter);?
//广播用于动态的添加搜索到的蓝牙到ListView中显示?
private?final?BroadcastReceiver?mReceiver?=?new?BroadcastReceiver()?{?
@Override?
public?void?onReceive(Context?context,?Intent?intent)?{?
//?TODO?Auto-generated?method?stub?
String?action?=?intent.getAction();?
if?(BluetoothDevice.ACTION_FOUND.equals(action))?{?
//发现的蓝牙设备?
BluetoothDevice?device?=?intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//发现的蓝牙设备已存在则跳过?
if?(mDeviceList.contains(device))?{?
return;?
}?
//添加发现的蓝牙设备?
mArrayAdapter.add(device.getName()?+?"\n"?+?device.getAddress());?
mDeviceList.add(device);?
//更新到ListView?
adapter.notifyDataSetChanged();?
}?else?if?(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))?{?
//搜索结束,关闭滚动条?
setProgressBarIndeterminateVisibility(false);?
}?
}?
};
//下面是一个简单的蓝牙搜索显示蓝牙示例//
首先新建工程、接着在在AndroidManifest.xml中添加蓝牙权限。
编写布局文件
android:layout_width="match_parent"?
android:layout_height="match_parent"?
android:orientation="vertical"?>?
android:id="@+id/XianShi"?
android:layout_width="match_parent"?
android:layout_height="wrap_content"?
android:gravity="center"?
android:text="无内容"?/>?
android:layout_width="match_parent"?
android:layout_height="wrap_content"?
android:orientation="horizontal"?>?
android:id="@+id/SendText"?
android:layout_width="wrap_content"?
android:layout_height="wrap_content"?
android:layout_weight="1.0"?
android:hint="请输入"?/>?
android:layout_width="wrap_content"?
android:layout_height="wrap_content"?
android:onClick="MySend"?
android:text="发送"?/>?
android:id="@+id/FindBt"?
android:layout_width="match_parent"?
android:layout_height="wrap_content"?
android:text="搜索"?/>?
android:layout_width="match_parent"?
android:layout_height="wrap_content"?
android:gravity="center"?
android:text="蓝牙列表"?/>?
android:id="@+id/DeviceList"?
android:layout_width="match_parent"?
android:layout_height="wrap_content"?>?
/编写源代码//
public?class?MainActivity?extends?Activity?{?
private?EditText?mET;???//发送内容,本示例未用到?
private?Button?MyScan;??//搜索按钮?
private?TextView?MyMessage;??//显示内容,本示例未用到?
private?ListView?MyBtList;???//显示蓝牙列表的ListView?
private?BluetoothAdapter?mBluetoothAdapter;??//蓝牙适配器?
private?ArrayAdapter?adapter;????????//Listview使用的适配器?
private?ArrayList?mArrayAdapter?=?new?ArrayList();??//保存ListView显示蓝牙设备的内容?
private?ArrayList?mDeviceList?=?new?ArrayList();??//保存查找的蓝牙设备,避免在ListView重复显示?
private?static?final?String?TAG?=?"MyBluetooth";???//调试用?
private?static?final?int?REQUES_BT_ENABLE_CODE?=?0x1002;???//?蓝牙使能请求码?
@Override?
protected?void?onCreate(Bundle?savedInstanceState)?{?
super.onCreate(savedInstanceState);?
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);???//请求显示滚动条?
setContentView(R.layout.activity_main);?
//UI注册?
mET?=?(EditText)?findViewById(R.id.SendText);?
MyScan?=?(Button)?findViewById(R.id.FindBt);?
MyMessage?=?(TextView)?findViewById(R.id.XianShi);?
MyBtList?=?(ListView)?findViewById(R.id.DeviceList);?
//ListView添加适配器?
adapter?=?new?ArrayAdapter(this,?
android.R.layout.simple_list_item_1,?mArrayAdapter);?
MyBtList.setAdapter(adapter);?
openBtDevice();???//打开蓝牙?
//搜索蓝牙按钮点击事件?
MyScan.setOnClickListener(new?MyScanClick());?
IntentFilter?filter?=?new?IntentFilter(BluetoothDevice.ACTION_FOUND);?
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);?
//?动态注册广播接收器?
//?用来接收扫描到的设备信息?
registerReceiver(mReceiver,?filter);?
}?
//搜索蓝牙按钮点击事件?
private?class?MyScanClick?implements?OnClickListener?{?
@Override?
public?void?onClick(View?v)?{?
//?TODO?Auto-generated?method?stub?
if?(!mBluetoothAdapter.isDiscovering())?{?
findBtDevice();??//打开蓝牙?
mBluetoothAdapter.startDiscovery();??//开始搜索?
setProgressBarIndeterminateVisibility(true);??//显示滚动条?
}?
}?
}?
//广播用于动态的添加搜索到的蓝牙到ListView中显示?
private?final?BroadcastReceiver?mReceiver?=?new?BroadcastReceiver()?{?
@Override?
public?void?onReceive(Context?context,?Intent?intent)?{?
//?TODO?Auto-generated?method?stub?
String?action?=?intent.getAction();?
if?(BluetoothDevice.ACTION_FOUND.equals(action))?{?
//发现的蓝牙设备?
BluetoothDevice?device?=?intent?
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);?
//发现的蓝牙设备已存在则跳过?
if?(mDeviceList.contains(device))?{?
return;?
}?
//添加发现的蓝牙设备?
mArrayAdapter?
.add(device.getName()?+?"\n"?+?device.getAddress());?
mDeviceList.add(device);?
//更新到ListView?
adapter.notifyDataSetChanged();?
}?else?if?(BluetoothAdapter.ACTION_DISCOVERY_FINISHED?
.equals(action))?{?
//搜索结束,关闭滚动条?
setProgressBarIndeterminateVisibility(false);?
}?
}?
};?
//之前已经配对的蓝牙,添加到ListView?
private?void?findBtDevice()?{?
Set?pairedDevices?=?mBluetoothAdapter?
.getBondedDevices();?
if?(pairedDevices.size()?>?0)?{?
for?(BluetoothDevice?device?:?pairedDevices)?{?
if?(mDeviceList.contains(device))?{?
return;?
}?
mArrayAdapter?
.add(device.getName()?+?"\n"?+?device.getAddress());?
mDeviceList.add(device);?
}?
}?
adapter.notifyDataSetChanged();?
}?
//打开蓝牙?
private?boolean?openBtDevice()?{?
//?获得蓝牙匹配器?
mBluetoothAdapter?=?BluetoothAdapter.getDefaultAdapter();?
//?蓝牙设备不被支持?
if?(mBluetoothAdapter?==?null)?{?
Log.e(TAG,?"Your?device?is?not?support?Bluetooth!");?
Toast.makeText(this,?"该设备没有蓝牙设备",?Toast.LENGTH_LONG).show();?
return?false;?
}?
//?使能蓝牙设备?
if?(!mBluetoothAdapter.isEnabled())?{?
//?隐式Intent?
Intent?enableBtIntent?=?new?Intent(?
BluetoothAdapter.ACTION_REQUEST_ENABLE);?
startActivityForResult(enableBtIntent,?REQUES_BT_ENABLE_CODE);?
}?else?{?
Toast.makeText(this,?"蓝牙打开成功!",?Toast.LENGTH_SHORT).show();?
}?
return?true;?
}?
//?当startActivityForResult启动的?画面结束的时候,该方法被回调?
@Override?
protected?void?onActivityResult(int?requestCode,?int?resultCode,?Intent?data)?{?
if?(requestCode?==?REQUES_BT_ENABLE_CODE?&&?resultCode?==?RESULT_OK)?{?
Toast.makeText(this,?"蓝牙打开成功!",?Toast.LENGTH_SHORT).show();?
}?
}?
}?
蓝牙打印
链接打印机后,执行以下代码:打印文字,格式类似于外卖单:
public class PrintTextActivityextends Activity {
List>listData =new ArrayList>();
private EditTextet_input;
private CheckBoxcheckBoxAuto;
private Buttonbt_print;
private Threadautoprint_Thread;
int times =500;// Automatic print time interval
? boolean isPrint =true;
Stringmessage="";
@Override
? protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
? ? ? super.onCreate(savedInstanceState);
setContentView(R.layout.activity_print_text);
isPrint =true;
et_input = (EditText) findViewById(R.id.et_input_1);
//et_input.setText("Printing test\n");
? ? ? bt_print = (Button) findViewById(R.id.bt_print);
bt_print.setOnClickListener(new OnClickListener() {
@Override
? ? ? ? public void onClick(View v) {
message=et_input.getText().toString().trim();
try {
byte[] send=message.getBytes("GBK");
PrintService.pl.write(send);
}catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
PrintService.pl.printText("\n");
PrintService.pl.write(new byte[]{0x1b,0x61,0x01});
//PrintService.pl.write(new byte[] { 0x1d, 0x0c });
? ? ? ? ? ? PrintService.pl.write(new byte[] {0x1b,0x21,0x11 });
PrintService.pl.printText("xxx");
//修改文字模式为加粗模式
? ? ? ? ? ? PrintService.pl.write(new byte[]{0X1b,0x45,0x01});
PrintService.pl.write(new byte[]{0x1d,0x21,0x03});
PrintService.pl.printText("\n");
//修改文字加粗模式为0
? ? ? ? ? ? PrintService.pl.write(new byte[]{0x1b,0x21,0x00});
//文字居中
? ? ? ? ? ? PrintService.pl.write(new byte[]{0x1b,0x61,0x01});
PrintService.pl.printText("已支付");
PrintService.pl.printText("\n");
PrintService.pl.printText("下单时间:10—24"+"\t"+"11:15");
PrintService.pl.printText("\n");
PrintService.pl.printText("货号"+"\t"+"\t"+"\t"+"\t"+"\t"+"数量"+"\t"+"价格");
PrintService.pl.printText("-----------------------------");
PrintService.pl.printText("\n");
PrintService.pl.printText("GP-3120TU"+"\t"+"\t"+"\t"+"\t"+"X1"+"\t"+"\t"+"286");
PrintService.pl.printText("\n");
PrintService.pl.printText("GP-1124D"+"\t"+"\t"+"\t"+"\t"+"X2"+"\t"+"\t"+"560");
PrintService.pl.printText("\n");
PrintService.pl.printText("GP-1124T"+"\t"+"\t"+"\t"+"\t"+"X1"+"\t"+"\t"+"698");
PrintService.pl.printText("\n");
PrintService.pl.printText("-----------------------------");
PrintService.pl.printText("\n");
PrintService.pl.printText("实收" +"\t" +"\t" +"\t" +"\t" +"¥" +"\t" +"1603");
PrintService.pl.printText("\n");
PrintService.pl.printText("找零" +"\t" +"\t" +"\t" +"\t" +"¥" +"\t" +"2");
PrintService.pl.printText("\n");
PrintService.pl.printText("-----------------------------");
PrintService.pl.printText("\n");
PrintService.pl.write(new byte[]{0x1b,0x61,0x01});
PrintService.pl.printText("请保管好购物凭证");
PrintService.pl.printText("\n");
PrintService.pl.write(new byte[]{0x1b,0x61,0x01});
PrintService.pl.printText("多谢惠顾");
}
});
checkBoxAuto = (CheckBox) findViewById(R.id.checkBoxAuto);
// Auto Print
? ? ? autoprint_Thread =new Thread() {
public void run() {
while (isPrint) {
if (checkBoxAuto.isChecked()) {
String message =et_input.getText().toString();
PrintService.pl.printText(message);
PrintService.pl.write(new byte[] {0x1d,0x0c });
try {
Thread.sleep(times);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
? ? ? ? ? ? ? ? ? ? e.printStackTrace();
}
}
}
}
};
autoprint_Thread.start();
//? ? et_input.addTextChangedListener(textWatcher);
? }
@Override
? public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
Resources res = getResources();
String[] cmdStr = res.getStringArray(R.array.cmd);
for (int i =0; i < cmdStr.length; i++) {
String[] cmdArray = cmdStr[i].split(",");
if (cmdArray.length ==2) {
Map map =new HashMap();
map.put("title", cmdArray[0]);
map.put("description", cmdArray[1]);
menu.add(0, i, i, cmdArray[0]);
listData.add(map);
}
}
return true;
}
@Override
? public boolean onOptionsItemSelected(android.view.MenuItem item) {
Map map =listData.get(item.getItemId());
String cmd = map.get("description").toString();
byte[] bt = PrintCmdActivity.hexStringToBytes(cmd);
PrintService.pl.write(bt);
Toast toast = Toast.makeText(this,"Send Success", Toast.LENGTH_SHORT);
toast.show();
return false;
}
@Override
? protected void onStop() {
// TODO Auto-generated method stub
? ? ? isPrint =false;
super.onStop();
}
private static Bitmap resizeImage(Bitmap bitmap,int w,int h) {
Bitmap BitmapOrg = bitmap;
int width = BitmapOrg.getWidth();
int height = BitmapOrg.getHeight();
if (width > w) {
float scaleWidth = ((float) w) / width;
float scaleHeight = ((float) h) / height +24;
Matrix matrix =new Matrix();
matrix.postScale(scaleWidth, scaleWidth);
Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg,0,0, width,
height, matrix,true);
return resizedBitmap;
}else {
Bitmap resizedBitmap = Bitmap.createBitmap(w, height +24,
Config.RGB_565);
Canvas canvas =new Canvas(resizedBitmap);
Paint paint =new Paint();
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(bitmap, (w - width) /2,0, paint);
return resizedBitmap;
}
}
}