本系列笔记概述
- 蓝牙传输优势:功耗低,传输距离还可以;
- 蓝牙聊天室案例
- Android中蓝牙设备的使用
- 蓝牙权限(本文的讲解内容之一)
- 蓝牙功能开启(本文的讲解内容之一)
- 搜索蓝牙设备(本文的讲解内容之一)
- 与外设搭建RFCOMM通道(射频通道)
- 蓝牙设备双向数据传输
蓝牙聊天室案例框架
蓝牙权限
- 执行蓝牙通信需要权限BLUETOOTH,
例如:请求连接、接收连接和传输数据等; - 如果需要启动设备 或 操作蓝牙设置,则需声明BLUETOOTH_ADMIN权限
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
设置蓝牙——获取BlueAdapter
- 使用蓝牙需用到BlueAdapter。表示设备自身的蓝牙适配器;
- 通过静态方法
BlueAdapter.getDefaultAdapter()
获得BlueAdapter; - 整个系统只有一个蓝牙适配器,application可使用此BlueAdapter对象与之交互;
- 如果
getDefaultAdapter()
返回null,则表示该设备不支持蓝牙,
例如:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null){
//Device does not support Bluetooth
}
启用蓝牙
- 调用
isEnable()
以检查当前是否已启用蓝牙;
如果此方法返回false
,则表示蓝牙处于停用状态; - 要请求启用蓝牙,将通过ACTION_REQUEST_ENABLE向系统设置
发出启用蓝牙的请求(无需停止应用),
例如:
...
private static final int REQUEST_ENABLE_BT = 10;//其是需要自己定义的局部常量。
...
if(mBluetoothAdapter.isEnabled()){
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
demo(查看本机是否支持蓝牙,蓝牙是否开启,没开启则请求):
- 新建一个项目,添加好如上述两个权限,编写MainActivity.java:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "BluetoothChat";
private static final int REQUEST_ENABLE_BT = 10;//其是需要自己定义的局部常量。
private BluetoothAdapter mBluetoothAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null){
//Device does not support Bluetooth
Log.e(TAG, "Device does not support Bluetooth");
}else {
Toast.makeText(this,"设备支持蓝牙!",Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onStart() {
super.onStart();
if(!mBluetoothAdapter.isEnabled()){
//向系统请求开启蓝牙
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);//结果返回回调到onActivityResult()
}else {
//已经开启了蓝牙
Toast.makeText(this,"蓝牙已经开启",Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_ENABLE_BT){
Toast.makeText(this,"蓝牙已经开启",Toast.LENGTH_SHORT).show();
}
}
}
查找设备——查找配对过的设备
- getBondedDevices():返回已配对设备的一组BluetoothDevice
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
//If threre are paired devices
if (pairedDevices.size() > 0) {
//Loop through paired devices
for(BluetoothDevice device : pairedDevices){
//Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
查找设备——发现设备
- 发现设备:
startDiscovery()
该进程为异步进程,
该方法会立即返回一个布尔值,指示是否已成功启动发现操作
; - 发现进程通常包含约
12秒钟
的查询扫描
- 广播接收:
//广播接收
private BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();//获取action
Log.d(TAG, "ACTION:" + action);
if(action.equals(BluetoothDevice.ACTION_FOUND)){
//如果扫描时发现蓝牙设备,取到发现的设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
}else if(action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)){
//如果扫描完毕
}
}
};
- 广播过滤、注册、注销:
...
//为广播接收器注册过滤器
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBluetoothReceiver,filter);
...
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mBluetoothReceiver);
}
demo(查找已配对蓝牙,log打印出来):
续上,修改activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/bt_paired_device"
android:text="已配对设备"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/bt_scan"
android:text="扫描附近蓝牙设备"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
接着修改MainActivity.java:
实例化、绑定:
...
//scan paired
private Button mScanButton;
private Button mPairedDeviceButton;
...
//scan paired
mPairedDeviceButton = (Button)findViewById(R.id.bt_paired_device);
mScanButton = (Button)findViewById(R.id.bt_scan);
...
添加onClick:
mPairedDeviceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//paired 配对的
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
//If threre are paired devices
// if (pairedDevices.size() > 0) {
//Loop through paired devices
for(BluetoothDevice device : pairedDevices){
//You add the name and address to an array adapter to show in a ListView at this
Log.d(TAG, "Device name " + device.getName());//打印匹配过的蓝牙设备的name
Log.d(TAG, "Device addr " + device.getAddress());
}
// }
}
});
mScanButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mBluetoothAdapter.isDiscovering()){//如果正在扫描,令之停止扫描,重新开始扫描
mBluetoothAdapter.cancelDiscovery();
}
mBluetoothAdapter.startDiscovery();//异步函数
}
});
运行之后点击“已配对设备”按钮,显示已配对蓝牙设备的信息:
此时java:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "BluetoothChat";
private static final int REQUEST_ENABLE_BT = 10;//其是需要自己定义的局部常量。
private BluetoothAdapter mBluetoothAdapter;
//scan paired
private Button mScanButton;
private Button mPairedDeviceButton;
//广播接收
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//scan paired
mPairedDeviceButton = (Button)findViewById(R.id.bt_paired_device);
mScanButton = (Button)findViewById(R.id.bt_scan);
mPairedDeviceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//paired 配对的
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
//If threre are paired devices
// if (pairedDevices.size() > 0) {
//Loop through paired devices
for(BluetoothDevice device : pairedDevices){
//Add the name and address to an array adapter to show in a ListView
Log.d(TAG, "Device name " + device.getName());//打印匹配过的蓝牙设备的name
Log.d(TAG, "Device addr " + device.getAddress());
}
// }
}
});
mScanButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mBluetoothAdapter.isDiscovering()){//如果正在扫描,令之停止扫描,重新开始扫描
mBluetoothAdapter.cancelDiscovery();
}
mBluetoothAdapter.startDiscovery();//异步函数
}
});
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null){
//Device does not support Bluetooth
Log.e(TAG, "Device does not support Bluetooth");
}else {
Toast.makeText(this,"设备支持蓝牙!",Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onStart() {
...
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
...
}
}
}
demo(续上,监测扫描发现设备时
、扫描完毕时
两个状态,做对应处理):
- 点击“扫描附近蓝牙设备”按钮时,开始一轮新的扫描:
mScanButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mBluetoothAdapter.isDiscovering()){//如果正在扫描,令之停止扫描,重新开始扫描
mBluetoothAdapter.cancelDiscovery();
}
mBluetoothAdapter.startDiscovery();//异步函数
}
});
- 注册广播接收器,
监测扫描发现设备时
、扫描完毕时
两个状态,
然后做对应处理:
//广播接收
private BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();//获取action
Log.d(TAG, "ACTION:" + action);
if(action.equals(BluetoothDevice.ACTION_FOUND)){
//如果扫描时发现蓝牙设备,取到发现的设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "new Device name " + device.getName());//打印匹配过的蓝牙设备的name
Log.d(TAG, "new Device addr " + device.getAddress());
}else if(action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)){
//如果扫描完毕
Toast.makeText(MainActivity.this,"Discovery done!",Toast.LENGTH_SHORT).show();
Log.d(TAG, "Discovery done!");
}
}
};
- 在onCreate()末尾注册intent过滤器:
//为广播接收器注册过滤器
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBluetoothReceiver,filter);
- 在onDestroy()中注销:
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mBluetoothReceiver);
}
- 运行效果如图,没有发现新设备,在扫描完毕后打印出对应的Log:
- 此时java:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "BluetoothChat";
private static final int REQUEST_ENABLE_BT = 10;//其是需要自己定义的局部常量。
private BluetoothAdapter mBluetoothAdapter;
//scan paired
private Button mScanButton;
private Button mPairedDeviceButton;
//广播接收
private BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();//获取action
Log.d(TAG, "ACTION:" + action);
if(action.equals(BluetoothDevice.ACTION_FOUND)){
//如果扫描时发现蓝牙设备,取到发现的设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "new Device name " + device.getName());//打印匹配过的蓝牙设备的name
Log.d(TAG, "new Device addr " + device.getAddress());
}else if(action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)){
//如果扫描完毕
Toast.makeText(MainActivity.this,"Discovery done!",Toast.LENGTH_SHORT).show();
Log.d(TAG, "Discovery done!");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//scan paired
mPairedDeviceButton = (Button)findViewById(R.id.bt_paired_device);
mScanButton = (Button)findViewById(R.id.bt_scan);
mPairedDeviceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//paired 配对的
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
//If threre are paired devices
// if (pairedDevices.size() > 0) {
//Loop through paired devices
for(BluetoothDevice device : pairedDevices){
//Add the name and address to an array adapter to show in a ListView
Log.d(TAG, "Device name " + device.getName());//打印匹配过的蓝牙设备的name
Log.d(TAG, "Device addr " + device.getAddress());
}
// }
}
});
mScanButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mBluetoothAdapter.isDiscovering()){//如果正在扫描,令之停止扫描,重新开始扫描
mBluetoothAdapter.cancelDiscovery();
}
mBluetoothAdapter.startDiscovery();//异步函数
}
});
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null){
//Device does not support Bluetooth
Log.e(TAG, "Device does not support Bluetooth");
}else {
Toast.makeText(this,"设备支持蓝牙!",Toast.LENGTH_SHORT).show();
}
//为广播接收器注册过滤器
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBluetoothReceiver,filter);
}
@Override
protected void onStart() {
super.onStart();
if(!mBluetoothAdapter.isEnabled()){
//向系统请求开启蓝牙
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);//结果返回回调到onActivityResult()
}else {
//已经开启了蓝牙
Toast.makeText(this,"蓝牙已经开启",Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_ENABLE_BT){
Toast.makeText(this,"蓝牙已经开启",Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mBluetoothReceiver);
}
}