藍牙的最基本的用法,搜索和配對!
首先看下效果如下
開啓藍牙
開啓藍牙需要註冊清單文件,初始化藍牙適配器,添加廣播監聽,最後纔是正式開啓藍牙。
清單文件加權限
<!-- 藍牙權限 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
5.0以上的版本需要加入gps權限
<!-- 5.0之後藍牙需要獲取gps權限 -->
<uses-feature android:name="android.hardware.location.gps" />
6.0以上的版本需要手動申請定位權限
<!-- 6.0之後藍牙需要位置權限 記得用6.0後的權限訪問 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
注:6.0加入權限之後記得手動獲取權限!不然藍牙功能無法正常使用
初始化藍牙(BluetoothAdapter)
初始化相當簡單直接調用getDefaultAdapter
方法就可以了
//初始化藍牙
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this, "設備不存在藍牙", Toast.LENGTH_SHORT).show();
return;
}
初始化之後就可以用BluetoothAdapter對象進行對藍牙的操作
BluetoothAdapter常用方法表格如下
方法 | 說明 |
---|---|
getDefaultAdapter | 默認本地適配器,如果此硬件平臺不支持藍牙,則爲空。 |
isEnabled | 如果藍牙當前已啓用並準備好使用,則返回true。 |
getState | 獲取本地藍牙適配器的當前狀態。STATE_OFF(關閉)、STATE_TURNING_ON(正在打開)、STATE_ON(開啓)、STATE_TURNING_OFF(正在關閉) |
enable | 強制開啓藍牙 |
disable | 強制關閉藍牙 |
disable(boolean persist) | 強制關閉藍牙,是否保留設置。 |
getAddress | 獲取藍牙地址 |
getName | 獲取藍牙名字 |
factoryReset | 出廠重置藍牙 |
setName(String name) | 設置藍牙名字 |
getScanMode | 獲取藍牙的掃描模式,掃描模式確定是否可以連接或被發現。SCAN_MODE_NONE(藍牙未開啓)、SCAN_MODE_CONNECTABLE(不可見)、SCAN_MODE_CONNECTABLE_DISCOVERABLE(可見) |
setScanMode(@ScanMode int mode, int duration) | (需要使用反射)設置藍牙的掃描模式,單獨的setScanMode(int mode)改變狀態設置默認藍牙可見時間 |
getDiscoverableTimeout、setDiscoverableTimeout(int timeout) | (需要使用反射)獲取和設置默認藍牙可見時間 |
startDiscovery | 開始掃描其他藍牙 |
cancelDiscovery | 取消掃描 |
isDiscovering | 是否在掃描中 |
getBondedDevices | 獲取已綁定藍牙 |
getConnectionState | 獲取藍牙連接狀態。STATE_CONNECTED(已連接)、STATE_DISCONNECTED(未連接)、STATE_CONNECTING(連接中) |
添加廣播
初始化之後就需要監聽藍牙的廣播,不然無法獲取搜索到了藍牙設備
//綁定廣播
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);//找到設備的廣播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成的廣播
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//藍牙狀態改變的廣播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//開始掃描的廣播
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//配對狀態改變
registerReceiver(mReceiver, filter);
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Log.e("-s-", "action = " + action);
switch (action) {
//藍牙狀態改變
case BluetoothAdapter.ACTION_STATE_CHANGED:
Log.e("-s-", "藍牙狀態改變");
checkBluetooth();
break;
//開始掃描
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
Log.e("-s-", "開始掃描藍牙");
allAdapter.clear();
changeText("開始掃描藍牙");
showToast("開始掃描藍牙");
break;
//搜索完成
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
Log.e("-s-", "搜索完成");
changeText("搜索完成");
showToast("搜索完成");
break;
//找到設備
case BluetoothDevice.ACTION_FOUND:
Log.e("-s-", "找到設備");
changeText("搜索中...");
printDevice(bluetoothDevice);
allAdapter.add(bluetoothDevice);
break;
//配對狀態改變
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
Log.e("-s-", "配對狀態改變");
if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDING) {
changeText(bluetoothDevice.getName() + " 配對中");
Log.e("-s-", "配對中");
} else if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
changeText(bluetoothDevice.getName() + " 已配對成功");
Log.e("-s-", "已配對成功");
} else {
changeText(bluetoothDevice.getName() + " 已取消配對");
Log.e("-s-", "已取消配對");
}
printDevice(bluetoothDevice);
updataBonds();
break;
default:
}
}
};
以上代碼有常用的幾個藍牙相關的廣播,這邊主要講下另一個比較需要注意的APIBluetoothDevice
以下表格是常用的BluetoothDevice方法
方法 | 說明 |
---|---|
getAddress | 獲取藍牙設備的地址 |
getName | 獲取藍牙設備的名稱(可能會空) |
getType | 獲得藍牙的設備類型。DEVICE_TYPE_UNKNOWN(未知)、DEVICE_TYPE_CLASSIC(br/edr設備)、DEVICE_TYPE_LE(低能量-僅限LE)、DEVICE_TYPE_DUAL(雙模,BR/EDR/LE) |
getAlias | (需要反射調用)獲取藍牙設備的別名(可能會空) |
getAliasName | (需要反射調用)獲取藍牙的名稱,優先別名,別名爲空則返回名稱,名稱也有可能爲空 |
createBond | 啓動與遠程設備的連接(配對)過程。 |
createBond(int transport) | (需要反射調用)使用指定的傳輸啓動與遠程設備的綁定(配對)過程。TRANSPORT_AUTO(沒有偏好的GATT連接)、TRANSPORT_BREDR(優先和BR/EDR設備GATT連接)、TRANSPORT_LE(優先和LE設備GATT連接) |
cancelBondProcess | (需要反射調用)取消createBond創建的配對請求 |
removeBond | (需要反射調用)取消設備配對 |
getBondState | 獲取設備的綁定狀態。BOND_NONE(未綁定)、BOND_BONDING(綁定中)、BOND_BONDED(已綁定) |
isConnected | 返回是否有與此設備的打開連接。 |
getBluetoothClass | 獲取遠程設備的藍牙類。 |
正式開啓藍牙
有了BluetoothAdapter的初始化對象和廣播監聽藍牙之後就可以開啓藍牙了!
- 強制開啓
上面BluetoothAdapter的常用方法裏面有一個強制開啓藍牙的方法
//強制開啓藍牙
bluetoothAdapter.enable();
在低於5.0以下的手機會直接打開藍牙,以上就會以彈窗的形式提示是否允許。
- 正常打開藍牙
if (!bluetoothAdapter.isEnabled()) {
//單獨打開藍牙 可以連接 默認不可見
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, REQUEST_ENABLE);
}
首先判斷了藍牙是否可用並且沒有打開,在正常打開藍牙。這樣打開的藍牙默認是可連接但不會被其他設備發現。
- 可見打開藍牙
if (!bluetoothAdapter.isEnabled()) {
//打開藍牙並且自己藍牙可見
Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//默認是120秒
discoveryIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);//設置持續時間(最多300秒)
startActivityForResult(discoveryIntent, REQUEST_ENABLE);
}
還是一樣首先判斷了藍牙是否可用並且沒有打開,在正常打開藍牙。這樣打開的藍牙可以連接並且可以被其他設備發現。
關閉藍牙
上面BluetoothAdapter的常用方法裏面有一個強制關閉藍牙的方法,正常我們直接使用這個方法就可以了,因爲沒有其他的方法了。
if (bluetoothAdapter.isEnabled()) {
bluetoothAdapter.disable();
}
搜索藍牙
- 全部搜索藍牙
//是否可用並開啓藍牙
if (bluetoothAdapter.isEnabled()) {
//是否在掃描狀態
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
//開始掃描
bluetoothAdapter.startDiscovery();
}
調用搜索之後 結果都是在廣播中回調的
搜索廣播片段如下 添加廣播中有完整的片段
String action = intent.getAction();
//獲取獲得的設備
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
switch (action) {
//開始掃描
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
Log.e("-s-", "開始掃描藍牙");
...
break;
//搜索完成
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
Log.e("-s-", "搜索完成");
...
break;
//找到設備
case BluetoothDevice.ACTION_FOUND:
Log.e("-s-", "找到設備");
//每次會獲取到一個設備,可以加入到自己的listview中作爲展示
...
break;
}
- 已配對藍牙
直接取上面的方法getBondedDevices
就可以了。
//清空已配對listview的適配器
bondAdapter.clear();
//遍歷已配對的Set<BluetoothDevice>
for (BluetoothDevice device : bluetoothAdapter.getBondedDevices()) {
//加入已配對listview的適配器
bondAdapter.add(device);
}
配對藍牙
由於createBond
方法其實沒有隱藏,所以可以直接調用方法進行配對,然後再廣播中進行監聽實現配對成功和失敗的提示。
//正常配對
if (device.createBond()) {
Log.e("-s-", "開始配對");
...
} else {
Log.e("-s-", "配對失敗");
...
}
或者調用反射來實現配對,網上找到的資料一般都是下面這個。但是上面的正常配對其實也是可以的。
//反射配對
try {
Method method = BluetoothDevice.class.getMethod("createBond");
boolean result = (boolean) method.invoke(device);
if (result) {
Log.e("-s-", "開始配對");
...
}else {
Log.e("-s-", "配對失敗");
...
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
Log.e("-s-", "配對失敗");
...
}
取消配對藍牙
由於沒有取消方法被隱藏了,就必須用反射來實現取消了
//反射取消配對
try {
Method method = BluetoothDevice.class.getMethod("removeBond");
boolean result = (boolean) method.invoke(device);
if (result) {
Log.e("-s-", "取消成功");
....
} else {
Log.e("-s-", "取消失敗");
...
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
Log.e("-s-", "取消失敗");
...
}
全部代碼
BlueActivity.class
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.ParcelUuid;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import com.gjn.baserecycleradapterlibrary.BaseRecyclerAdapter;
import com.gjn.baserecycleradapterlibrary.RecyclerViewHolder;
import com.gjn.permissionlibrary.PermissionUtils;
import com.gjn.testproject.R;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class BlueActivity extends AppCompatActivity {
private static final int REQUEST_ENABLE = 0x1001;
private static final int REQUEST_DISABLE = 0x1002;
Button btn1, btn2, btn3, btn4, btn5, btn6;
TextView tv;
RecyclerView rv, rv2;
Switch sw;
private BluetoothAdapter bluetoothAdapter;
private BaseRecyclerAdapter<BluetoothDevice> allAdapter;
private BaseRecyclerAdapter<BluetoothDevice> bondAdapter;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Log.e("-s-", "action = " + action);
switch (action) {
//藍牙狀態改變
case BluetoothAdapter.ACTION_STATE_CHANGED:
Log.e("-s-", "藍牙狀態改變");
checkBluetooth();
break;
//開始掃描
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
Log.e("-s-", "開始掃描藍牙");
allAdapter.clear();
changeText("開始掃描藍牙");
showToast("開始掃描藍牙");
break;
//搜索完成
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
Log.e("-s-", "搜索完成");
changeText("搜索完成");
showToast("搜索完成");
break;
//找到設備
case BluetoothDevice.ACTION_FOUND:
Log.e("-s-", "找到設備");
changeText("搜索中...");
printDevice(bluetoothDevice);
allAdapter.add(bluetoothDevice);
break;
//配對狀態改變
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
Log.e("-s-", "配對狀態改變");
if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDING) {
changeText(bluetoothDevice.getName() + " 配對中");
Log.e("-s-", "配對中");
} else if (bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
changeText(bluetoothDevice.getName() + " 已配對成功");
Log.e("-s-", "已配對成功");
} else {
changeText(bluetoothDevice.getName() + " 已取消配對");
Log.e("-s-", "已取消配對");
}
printDevice(bluetoothDevice);
updataBonds();
break;
default:
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_blue);
PermissionUtils.requestPermissions(this, PermissionUtils.CODE_LOCATION, PermissionUtils.CODE_PHONE);
btn1 = findViewById(R.id.btn_1);
btn2 = findViewById(R.id.btn_2);
btn3 = findViewById(R.id.btn_3);
btn4 = findViewById(R.id.btn_4);
btn5 = findViewById(R.id.btn_5);
btn6 = findViewById(R.id.btn_6);
tv = findViewById(R.id.tv_state);
sw = findViewById(R.id.sw_state);
rv = findViewById(R.id.rv_ly);
rv2 = findViewById(R.id.rv_ypd);
//初始化藍牙
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this, "設備不存在藍牙", Toast.LENGTH_SHORT).show();
return;
}
//綁定廣播
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);//找到設備的廣播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成的廣播
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//藍牙狀態改變的廣播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//開始掃描的廣播
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//配對狀態改變
registerReceiver(mReceiver, filter);
//初始化RecyclerView和適配器
rv.setLayoutManager(new LinearLayoutManager(this));
rv2.setLayoutManager(new LinearLayoutManager(this));
allAdapter = new BaseRecyclerAdapter<BluetoothDevice>(this, R.layout.item_blue, null) {
@Override
public void bindData(RecyclerViewHolder holder, BluetoothDevice device, int position) {
holder.setTextViewText(R.id.tv_name, device.getName());
holder.setTextViewText(R.id.tv_address, device.getAddress());
if (BluetoothDevice.BOND_BONDED == device.getBondState()) {
holder.setTextViewText(R.id.tv_state, "已配對");
} else {
holder.setTextViewText(R.id.tv_state, "未配對");
}
}
};
rv.setAdapter(allAdapter);
bondAdapter = new BaseRecyclerAdapter<BluetoothDevice>(this, R.layout.item_blue, null) {
@Override
public void bindData(RecyclerViewHolder holder, BluetoothDevice device, int position) {
holder.setTextViewText(R.id.tv_name, device.getName());
holder.setTextViewText(R.id.tv_address, device.getAddress());
if (BluetoothDevice.BOND_BONDED == device.getBondState()) {
holder.setTextViewText(R.id.tv_state, "已配對");
} else {
holder.setTextViewText(R.id.tv_state, "未配對");
}
}
};
rv2.setAdapter(bondAdapter);
checkBluetooth();
initData();
}
private void initData() {
allAdapter.setOnItemClickListener(new BaseRecyclerAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int pos) {
bond(allAdapter.getItem(pos));
}
});
bondAdapter.setOnItemClickListener(new BaseRecyclerAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int pos) {
unBond(bondAdapter.getItem(pos));
}
});
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!bluetoothAdapter.isEnabled()) {
//單獨打開藍牙
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, REQUEST_ENABLE);
}
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bluetoothAdapter.enable();
}
});
btn5.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Method setScanMode = BluetoothAdapter.class.getMethod("setScanMode", int.class);
boolean result = (boolean) setScanMode.invoke(bluetoothAdapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
Log.e("-s-", "result = " + result);
Method getDiscoverableTimeout = BluetoothAdapter.class.getMethod("getDiscoverableTimeout");
int time = (int) getDiscoverableTimeout.invoke(bluetoothAdapter);
Log.e("-s-", "time = " + time);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
});
btn6.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//打開藍牙並且自己藍牙可見
Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//默認是120秒
discoveryIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);//設置持續時間(最多300秒)
startActivityForResult(discoveryIntent, REQUEST_ENABLE);
}
});
btn3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (bluetoothAdapter.isEnabled()) {
bluetoothAdapter.disable();
}
}
});
btn4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (bluetoothAdapter.isEnabled()) {
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
bluetoothAdapter.startDiscovery();
}
}
});
}
private void unBond(BluetoothDevice device) {
if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
//反射取消配對
try {
Method method = BluetoothDevice.class.getMethod("removeBond");
boolean result = (boolean) method.invoke(device);
if (result) {
Log.e("-s-", "取消成功");
showToast("取消成功");
} else {
Log.e("-s-", "取消失敗");
showToast("取消失敗");
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
private void bond(BluetoothDevice device) {
if (device.getBondState() == BluetoothDevice.BOND_NONE) {
// //反射配對
// try {
// Method method = BluetoothDevice.class.getMethod("createBond");
// boolean result = (boolean) method.invoke(device);
// if (result) {
// Log.e("-s-", "配對成功");
// showToast("配對成功");
// }else {
// Log.e("-s-", "配對失敗");
// showToast("配對失敗");
// }
// } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
// e.printStackTrace();
// }
//正常配對
if (device.createBond()) {
Log.e("-s-", "開始配對");
tv.setText(device.getName() + " 開始配對");
showToast("開始配對");
} else {
Log.e("-s-", "配對失敗");
showToast(device.getName() + " 配對失敗");
}
}
}
private void changeText(String str) {
tv.setText(str);
}
private void showToast(String s) {
Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
}
private void checkBluetooth() {
switch (bluetoothAdapter.getScanMode()) {
case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
Log.e("-s-", "藍牙可連接");
tv.setText("藍牙可連接");
break;
case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
Log.e("-s-", "藍牙可連接可發現");
tv.setText("藍牙可連接可發現");
break;
case BluetoothAdapter.SCAN_MODE_NONE:
default:
Log.e("-s-", "藍牙不可連接不可見");
tv.setText("藍牙不可連接不可見");
}
if (bluetoothAdapter.isEnabled()) {
sw.setChecked(true);
updataBonds();
} else {
sw.setChecked(false);
allAdapter.clear();
bondAdapter.clear();
}
}
private void updataBonds() {
bondAdapter.clear();
for (BluetoothDevice device : bluetoothAdapter.getBondedDevices()) {
bondAdapter.add(device);
}
}
private void printDevice(BluetoothDevice device) {
Log.e("-s-", "Name = " + device.getName());
Log.e("-s-", "Address = " + device.getAddress());
Log.e("-s-", "BondState = " + device.getBondState());
Log.e("-s-", "Type = " + device.getType());
if (device.getUuids() != null) {
for (ParcelUuid uuid : device.getUuids()) {
Log.e("-s-", "uuid = " + uuid);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
}
activity_blue.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
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="com.gjn.testproject.blue.BlueActivity">
<Switch
android:id="@+id/sw_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:enabled="false"
android:text="藍牙狀態"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="默認打開藍牙"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sw_state" />
<Button
android:id="@+id/btn_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="強制打開藍牙"
app:layout_constraintStart_toEndOf="@+id/btn_1"
app:layout_constraintTop_toBottomOf="@+id/sw_state" />
<Button
android:id="@+id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="關閉藍牙"
app:layout_constraintStart_toEndOf="@+id/btn_2"
app:layout_constraintTop_toBottomOf="@+id/sw_state" />
<Button
android:id="@+id/btn_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="搜索藍牙"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_1" />
<Button
android:id="@+id/btn_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="設置藍牙可見"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_1" />
<Button
android:id="@+id/btn_6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="可見打開藍牙"
app:layout_constraintStart_toEndOf="@+id/btn_4"
app:layout_constraintTop_toBottomOf="@+id/btn_3" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_ypd"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.032"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView11" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_ly"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView12" />
<TextView
android:id="@+id/tv_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="無操作"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/textView11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="已配對設備"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_4" />
<TextView
android:id="@+id/textView12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="全部設備"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rv_ypd" />
</android.support.constraint.ConstraintLayout>
資料
Android BLE 藍牙開發入門
Android藍牙開發(一)之打開藍牙和設備搜索
Android藍牙開發(二)之藍牙配對和藍牙連接