本人水平有限,文章中如果出現什麼不正確或者模糊的地方,還請各位小夥伴留下評論,多多指教 : )
正式開始前的話
之前2篇關於藍牙的文章是很久之前寫的博文,算是CSDN的開篇之作,裏面存在許多的不足,而且後面也沒能堅持下來,有一些小夥伴私信我要這部分的代碼,剛好最近手上的一個項目也是和藍牙有關,所以今天特意特意把這個項目又下下來,一方面總結最近一段時間關於藍牙的開發,另一方也算把前兩篇的坑給填上~~
至於這個項目當中涉及到的其他內容,例如數據庫的使用,界面的編寫等都不再在這個系列的博客做詳細介紹(當時寫的太菜了……沒啥好介紹的(:з」∠)有興趣的小夥伴屆時可以看看源碼~),本系列的博客將會把重點放在藍牙的處理上。這裏附上之前寫的兩篇文章地址,有興趣的小夥伴可以去看一看~~
android 藍牙鎖應用實例開發(一) 簡介
android 藍牙鎖應用開發實例(二)客戶端基本頁面
藍牙開發梳理
整體思路
我一直認爲,無論做什麼樣的開發,一定要思路先行,在瞭解大致的工作流程後,才便於我們後面對各種瑣碎細節的研究。不僅能加深理解,還能養成良好的思維模式。接下來就帶大家簡單梳理一下藍牙開發的流程。
(1)獲取藍牙開發的權限
(2)掃描附近的藍牙設備,並將這些設備加入到devices列表
(3)選擇要配對的設備,將次設備加入到已配對設備列表
(4)進行數據通信或其他操作
(5)接觸配對狀態
若干年之後,你可能具體的代碼細節忘記 ,但是上面的步驟應該是做過一次開發就不會忘記了。
在第2步和第3部中涉及了2個列表,一個是【設備列表】,一個是【匹配設備列表】。
設備列表——是指附近的可見藍牙設備,但是還沒匹配
匹配設備列表——是指已經完成匹配的列表
大家要理解這2種列表的區別。因爲列表的區別,也代表了設備狀態。
即【未匹配狀態】、【匹配狀態】、【配對狀態】
未匹配,就是指從來沒有匹配過的設備。
匹配狀態,就是指設備間已經相互完成了身份驗證,處於待配對(待建立Socket)狀態。
不知大家還記不記得,以前藍牙配對的時候,手機會彈出一個對話框,提示輸入pin碼,其實也就是提前約定的一個配對碼,到後來,手機與與手機之間的連接就不需要配對碼了(實際上是程序內部完成了配對的過程)。
當然,手機與一些藍牙硬件(例如單片機+藍牙模塊的組合)配對時,還是需要輸入pin碼(不過也能通過程序自動完成驗證)
那麼什麼配對狀態呢?
配對的過程,其實就是Socket通信的一個過程,兩個藍牙設備僅僅匹配是還不能夠傳遞數據的,只有當二者建立了Socket通道之後,才能進行數據的傳遞。
好了,基本是思路差不多介紹完了,爲了加深大家對藍牙的理解,我這裏再把上面的內容,通過圖的形式再總結一下。同時我也會把藍牙相關操作的核心API給列在次圖中,讓大家對下一節的內容有大致的瞭解
接下來,將對涉及藍牙操作的幾個核心API進行介紹。
核心API
本節內容將講解藍牙操作的核心API,這裏說明一下,android的藍牙開發有涉及到不同的藍牙種類,例如低功耗藍牙(BluetoothGatt)、藍牙健康(BlueToothHealth)等,這裏介紹的依然是常規的藍牙開發API
再多囉嗦一句……API查看哪家強……那肯定是官方文檔啦~當然是對於英文基礎不錯的小夥伴,不過英語一般的小夥伴也不用太擔心,畢竟有很多優秀的翻譯軟件及API中文站,這裏我提供一個傳送們,希望深入理解的BlueTooth或者其他API的小夥伴有空可以經常去看看。
BlueToothAdapter
簡介
這個類代表着本地的藍牙適配器,讓你可以從事各種與藍牙相關的操作,例如開始和停止設備的查找;查詢已匹配的設備並以集合的形式返回;通過已知的設備地址,實例化一個BlueToothDevice;創建一個BluetoothServerSocket來監聽來自其他設備的鏈接請求等等,總之要想使用本機的藍牙,這個類是極其重要的。
getDefaultAdapter()
獲取本地的藍牙適配器,一般的調用代碼如下:
//獲取本地藍牙適配器
bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
getBondedDevices()
獲取已經匹配的設備列表,並以set集合的方式返回
調用代碼如下:
/*
*獲取已經配對的設備
* */
private void setPairingDevice() {
Set<BluetoothDevice> devices=bluetoothAdapter.getBondedDevices();
if(devices.size()>0){ //存在已配對過的設備
//利用for循環讀取每一個設備的信息
for(Iterator<BluetoothDevice> it = devices.iterator(); it.hasNext();){
BluetoothDevice btd=it.next();
```````
}
}else{
//不存在已經配對的藍牙設備
}
}
isDiscovering()
判斷當前是否正在查找設備,是返回true
startDiscovery()
這裏需要注意一下,由於搜素是一個耗時操作,所以這個方法應該在線程中去調用,同時需要配合着廣播去使用,關於廣播的內容,將在下一個小節中詳細講解。
開始查找設備,一般的調用代碼如下:
/**
* 開始附加設備的查找
*/
private void doDiscovery() {
new Thread(new Runnable() {
@Override
public void run() {
//如果adapter正在查詢,停止查詢
if(bluetoothAdapter.isDiscovering()){
bluetoothAdapter.cancelDiscovery();
}
bluetoothAdapter.startDiscovery();
}
}).start();
}
這裏再注意一個細節,那就是如果當前的adapter正在查找,那麼必須停止當前查找,然後再重新查找,這是因爲查找操作佔用很多的系統資源,我們需要避免重複的查找
cancelDiscovery()
取消查找設備,在上面的已經調用過
getRemoteDevice(String address)
根據一個藍牙設備的地址來獲取該地址,這個方法返回一個BlueToothDevice的實例
enable() | disable()
字面意思,打開或者關閉本機的藍牙。
一般的調用代碼如下:
//獲取藍牙適配器
mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
//如果藍牙沒有打開則打開藍牙
if (!mBluetoothAdapter.isEnabled()) {
//請求用戶開啓
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, REQUEST_COMMUNICATE);
}
getAddress() | getName() | getState()
getAddress()獲取本地藍牙地址
getName()獲取本地藍牙名稱
getState()獲取本地藍牙適配器當前狀態
listenUsingRfcommWithServiceRecord(String name,UUID uuid)
listenUsingRfcommWithServiceRecord(String name,UUID uuid)根據名稱,UUID創建並返回BluetoothServerSocket。這個方法是創建BluetoothSocket服務器端不可缺少的一步。
BluetoothDevice
簡介
這個類代表一個遠程設備,它能夠讓我們與一個其他相關設備創建連接,或者查詢與此設備相關的信息,例如名稱(name)、地址(address)、連接狀態(boud state)
createRfcommSocketToServiceRecord(UUIDuuid)
根據UUID創建並返回一個BluetoothSocket。
getAddress() | getName() | getState()
getAddress()獲取Address設備的藍牙地址
getName()獲取Address設備的地藍牙名稱
getState()獲取Address設備的藍牙適配器當前狀態
BluetoothServerSocket和BluetoothSocket
這裏把這兩個API放在一起說,這兩個方法相互對應,ServerSocket對應的服務端,Socket對應的是客戶端,具體內容在下一節中介紹
至此,所有的比較重要的API都已經介紹完畢了,現在正式進入代碼編寫的階段。
編碼階段
程序功能
本篇文章只完成附近藍牙設備的搜索和鏈接,關於數據通信的部分將在下一篇文章中介紹
功能:
(1)搜索附近藍牙設備
(2)與附近藍牙設備配對
程序設計
代碼目錄如下
類詳解
DeviceListAdapter
這個類是自定義的BaseAdapter,作爲用來顯示藍牙設備的listView的適配器
源碼:
/**
* Created by dell on 2016/9/22.
* 存放以匹配藍牙設備的ListView的Adapter
*/
public class DeviceListAdapter extends BaseAdapter {
//標識符,詳見【說明1】
private final int NEAR_DEVICE=1;
private final int PAIRING_DEVICE=2;
//存儲設備的容器
private DeviceListListener deviceListListener;
private ArrayList<Device> devices;
private BluetoothAdapter mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
private LayoutInflater inflater;
private Context context;
//用於標示附近設備和以配對設備的標識
private int flag;
//接口
public interface DeviceListListener{
//更新ArrayList
void notifyArrayList();
//提示取消配對成功
void cancelSuccess();
//配對成功
void bindSuccess();
}
public DeviceListAdapter(Context context, ArrayList<Device> devices){
this.devices=devices;
this.context=context;
inflater=LayoutInflater.from(context);
}
//爲adapter設置一個flag
public void setFlag(int i ){
flag=i;
}
public void setDeviceListListener(DeviceListListener deviceListListener){
this.deviceListListener=deviceListListener;
}
@Override
public int getCount() {
return devices.size();
}
@Override
public Object getItem(int i) {
return devices.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
//如果View是空,則實例化viewHolder
if(view==null){
viewHolder=new ViewHolder();
view=inflater.inflate(R.layout.binding_device_list_item,null);
viewHolder.deviceAddress= (TextView) view.findViewById(R.id.device_address);
viewHolder.deviceName= (TextView) view.findViewById(R.id.device_name);
view.setTag(viewHolder);
}else{
viewHolder= (ViewHolder) view.getTag();
}
final Device device=devices.get(i);
//設置設備名稱和地址
viewHolder.deviceAddress.setText(device.getAddress());
viewHolder.deviceName.setText(device.getDevName());
//爲view設置點擊事件
switch (flag){
case NEAR_DEVICE:
setNearDeViceEvent(view,device);
break;
case PAIRING_DEVICE:
setPairingDeviceEvent(view,device);
break;
}
return view;
}
/**
* 爲配對設備ListView設置相關事件
*/
private void setPairingDeviceEvent(View view,final Device device) {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
view.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
final AlertDialog.Builder builder =new AlertDialog.Builder(context);
builder.setTitle("提示").
setMessage("您確定要與該設備取消配對嗎?").
setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
BlueToothUnit.unBindDevice(mBluetoothAdapter,device,deviceListListener);
}
}).show();
return false;
}
});
}
/**
* 爲附近設備ListView設置相關事件
*/
private void setNearDeViceEvent(View view,final Device device) {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final AlertDialog.Builder builder=new AlertDialog.Builder(context);
builder.setTitle("提示").
setMessage("您確定要和此設備配對嗎?")
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
BlueToothUnit.bindTargetDevice(mBluetoothAdapter,device,deviceListListener);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}).
setNegativeButton("取消",null).
show();
}
});
}
class ViewHolder
{
TextView deviceName;
TextView deviceAddress;
}
}
【說明1】
因爲這個adapter既要被已匹配設備的listView使用,也要被附近設備的listView使用,而兩個listView對應 item點擊事件又是不一樣的,所以,在一開始設置了2個標識符,用以區分。
【說明2】
與藍牙有關的操作,都封裝在了BluetoothUnit當中
【說明3】
此類是一個標準BaseAdapter的寫法,getView()當中通過LayoutInfater加載了一個自定義的佈局,同時使用了viewHolder對listView進行優化。
Device
一個標準的Java Bean,表示一個藍牙設備的實例
public class Device {
//藍牙地址
private String address;
//設備名稱
private String devName;
public Device(String devName, String address) {
this.address = address;
this.devName = devName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDevName() {
return devName;
}
public void setDevName(String devName) {
this.devName = devName;
}
}
BlueToothUnit
封裝了與藍牙操作相關的方法
public class BlueToothUnit {
private final String TAG = "--BlueToothUnit--";
public static void unBindDevice(BluetoothAdapter mBluetoothAdapter, Device device, DeviceListAdapter.DeviceListListener deviceListListener){
//利用反射的方法取消配對
BluetoothDevice device0 = mBluetoothAdapter.getRemoteDevice(device.getAddress());
try {
Boolean returnValue ;
Method m = device0.getClass().getMethod("removeBond");
returnValue = (Boolean) m.invoke(device0);
if (returnValue)
deviceListListener.cancelSuccess();
} catch (Exception e) {
e.printStackTrace();
}
//成功取消配對後更新listView
deviceListListener.notifyArrayList();
}
/**
* 配對指定的設備
*/
public static void bindTargetDevice(BluetoothAdapter localBluetoothAdapter, Device device, DeviceListAdapter.DeviceListListener deviceListListener) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//在配對之前,一定要停止搜搜
if (localBluetoothAdapter.isDiscovering()) {
localBluetoothAdapter.cancelDiscovery();
}
//獲取配對的設備
BluetoothDevice btDev = localBluetoothAdapter.getRemoteDevice(device.getAddress());
Boolean returnValue;
if (btDev.getBondState() == BluetoothDevice.BOND_NONE) {
//利用反射方法調用BluetoothDevice.createBond(BluetoothDevice remoteDevice);
Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
Log.d("---", "開始配對");
returnValue = (Boolean) createBondMethod.invoke(btDev);
if (returnValue){
Log.d("---", "bindTargetDevice "+"配對成功");
deviceListListener.bindSuccess();
}
}
}
/**
* @param bluetoothAdapter 本地藍牙適配器
* 開始藍牙設備的搜索
*/
public static void findAvailableDevices(final BluetoothAdapter bluetoothAdapter) {
//開始搜索工作
new Thread(new Runnable() {
@Override
public void run() {
//如果藍牙正在搜索,則停止搜索,然後再重新開始搜索
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
//調用此方法會不斷的發送廣播,用戶只需自定義一個receiver接受即可
bluetoothAdapter.startDiscovery();
}
}).start();
}
}
通過反射的方法完成連接或取消配對
BtBrocastReceiver
接受藍牙相關的廣播,並作出相應的操作
public class BtBroadcastReceiver extends BroadcastReceiver {
private final String TAG="--broadcastReceiver--";
private ArrayList<Device> nearDevices;
private DeviceListAdapter adapter;
private ProgressDialog progressDialog;
public interface BroadcastListener{
void finishSearch();
void bindSuccess();
}
private BroadcastListener broadcastListener;
public BtBroadcastReceiver(Context context, ArrayList<Device> nearDevices,DeviceListAdapter adapter,BroadcastListener broadcastListener){
this.nearDevices=nearDevices;
this.broadcastListener=broadcastListener;
this.adapter=adapter;
progressDialog=new ProgressDialog(context);
progressDialog.setTitle("正在查詢附近設備");
progressDialog.setCancelable(false);
progressDialog.setMessage("請稍等……");
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action){
case BluetoothAdapter.ACTION_DISCOVERY_STARTED: //索索開始
Log.w(TAG,"--開始尋找設備");
progressDialog.show();
//清空nearList裏面的數據
nearDevices.clear();
break;
case BluetoothDevice.ACTION_FOUND: //發現設備
Log.w(TAG,"--找到設備");
//拿到藍牙設備
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//如果此設備的狀態是還未匹配,則把它加入到設備列表當中
if(device.getBondState()==BluetoothDevice.BOND_NONE) {
Device d=new Device(device.getName(),device.getAddress());
nearDevices.add(d);
adapter.notifyDataSetChanged();
}
progressDialog.setMessage("已找到"+nearDevices.size()+"臺設備……");
break;
case BluetoothDevice.ACTION_BOND_STATE_CHANGED: //狀態改變
device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
switch (device.getBondState()) {
case BluetoothDevice.BOND_BONDING:
Log.w("BlueToothTestActivity", "正在配對......");
progressDialog.setTitle("正在配對");
progressDialog.setMessage("請稍等……");
progressDialog.show();
break;
case BluetoothDevice.BOND_BONDED:
Log.w("BlueToothTestActivity", "配對完成");
broadcastListener.bindSuccess();
progressDialog.dismiss();
break;
case BluetoothDevice.BOND_NONE:
Log.w("BlueToothTestActivity", "取消配對");
default:
break;
}
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:// 搜索完成
Log.w("finish:----", "搜索完成!");
progressDialog.dismiss();
if(nearDevices.size()==0){
Toast.makeText(context,"附近沒有可用設備",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"搜索到"+nearDevices.size()+"臺設備",Toast.LENGTH_SHORT).show();
}
broadcastListener.finishSearch();
break;
}
}
}
這個類主要是監聽藍牙相關的廣播,這些廣播的註冊邏輯放在了PairingDeviceActivity當中
PairingDeviceActivity
顯示已配對設備的listView,以及搜索附近的設備和廣播的註冊
/**
* Created by dell on 2016/9/22.
* 本類用於顯示已經和手機匹配了的設備,並且可以搜尋附近的設備
*/
public class PairingDeviceActivity extends AppCompatActivity implements BtBroadcastReceiver.BroadcastListener {
private final String TAG="--Pairing--";
//狀態標識符
private final int NEAR_DEVICE=1;
private final int PAIRING_DEVICE=2;
private TextView emptyView;
//顯示已經匹配的設備
private ListView pairingListView;
//藍牙適配器
private BluetoothAdapter bluetoothAdapter;
//存儲以匹配設備的容器
private ArrayList<Device> pairingDevices=new ArrayList<>();
//存儲附近設備的容器
private ArrayList<Device> nearDevices=new ArrayList<>();
//已匹配設備的Adapter
private DeviceListAdapter pairingDeviceListAdapter;
//附近設備的Adapter
private DeviceListAdapter nearDeviceListAdapter;
//匹配附近設備時彈出的alter
private AlertDialog alertDialog;
private LayoutInflater inflater;
//是否進行了廣播接收器註冊的標識符
private boolean hasRegister=false;
//廣播接收器
private BtBroadcastReceiver mReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pairing_device_activity);
//初始化控件
init();
//初始化適配器
initAdapter();
//獲取當前匹配的數據
setPairingDevice();
nearDeviceListAdapter.setDeviceListListener(new DeviceListAdapter.DeviceListListener() {
@Override
public void notifyArrayList() {
}
@Override
public void cancelSuccess() {
}
@Override
public void bindSuccess() {
// Toast.makeText(PairingDeviceActivity.this,"配對成功!",Toast.LENGTH_SHORT).show();
}
});
//添加更新ListView的方法
pairingDeviceListAdapter.setDeviceListListener(new DeviceListAdapter.DeviceListListener() {
@Override
public void notifyArrayList() {
pairingDevices.clear();
//讓adapter獲得以匹配的設備
setPairingDevice();
pairingDeviceListAdapter.notifyDataSetChanged();
}
@Override
public void cancelSuccess() {
Toast.makeText(PairingDeviceActivity.this,"已取消配對",Toast.LENGTH_SHORT).show();
}
@Override
public void bindSuccess() {
Toast.makeText(PairingDeviceActivity.this,"配對成功!",Toast.LENGTH_SHORT).show();
}
});
}
/*
* 初始化ui及其他組件
* */
private void init() {
pairingListView= (ListView) findViewById(R.id.list_binding_devices);
emptyView= (TextView) findViewById(R.id.tv_empty);
inflater=LayoutInflater.from(PairingDeviceActivity.this);
}
/**
* 初始化適配器
*/
private void initAdapter() {
//獲取本地藍牙適配器
bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
//匹配設備和附加設備list的適配器
nearDeviceListAdapter=new DeviceListAdapter(this,nearDevices);
pairingDeviceListAdapter=new DeviceListAdapter(this,pairingDevices);
//設置adapter的標識符
pairingDeviceListAdapter.setFlag(PAIRING_DEVICE);
nearDeviceListAdapter.setFlag(NEAR_DEVICE);
//list與adapter綁定
pairingListView.setAdapter(pairingDeviceListAdapter);
//初始化接收器
mReceiver=new BtBroadcastReceiver(PairingDeviceActivity.this,nearDevices,nearDeviceListAdapter,this);
}
//尋找附近設備
public void onClickFindNearDevices(View view){
//開始查詢工作
doDiscovery();
}
/**
* 開始附加設備的查找
*/
private void doDiscovery() {
BlueToothUnit.findAvailableDevices(bluetoothAdapter);
}
@Override
protected void onStart() {
super.onStart();
//註冊廣播
if(!hasRegister) {
hasRegister = true;
//尋找到設備的過濾器
IntentFilter filterStar = new IntentFilter(BluetoothDevice.ACTION_FOUND);
//綁定狀態改變
IntentFilter changeFilter= new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//搜索完成
IntentFilter filterFinish = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
//開始搜搜
IntentFilter startSearch=new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
registerReceiver(mReceiver,startSearch);
registerReceiver(mReceiver, filterFinish);
registerReceiver(mReceiver, filterStar);
registerReceiver(mReceiver, changeFilter);
}
//註冊的廣播在活動結束時需要註銷
}
/*
*獲取已經配對的設備
* */
private void setPairingDevice() {
Set<BluetoothDevice> devices=bluetoothAdapter.getBondedDevices();
if(devices.size()>0){ //存在已配對過的設備
emptyView.setVisibility(View.GONE);
pairingListView.setVisibility(View.VISIBLE);
pairingDevices.clear();
for(Iterator<BluetoothDevice> it = devices.iterator(); it.hasNext();){
BluetoothDevice btd=it.next();
Device device =new Device(btd.getName(),btd.getAddress());
Log.d("---", "setPairingDevice: name "+btd.getName()+" address is "+btd.getAddress());
//將device添加到PairingDeviceActivity當中的devices,注意this
pairingDevices.add(device);
}
}else{ //不存在已經配對的藍牙設備
emptyView.setVisibility(View.VISIBLE);
pairingListView.setVisibility(View.GONE);
Toast.makeText(this,"不存在已配對設備",Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//如果藍牙適配器正在掃描,則停止掃描
if(bluetoothAdapter!=null&&bluetoothAdapter.isDiscovering())
bluetoothAdapter.cancelDiscovery();
//註銷廣播
if(hasRegister){
hasRegister=false;
unregisterReceiver(mReceiver);
}
}
@Override
public void bindSuccess() {
Log.d(TAG, "bindSuccess: ");
alertDialog.dismiss();
Toast.makeText(PairingDeviceActivity.this,"配對成功",Toast.LENGTH_SHORT).show();
//更新數據
setPairingDevice();
pairingDeviceListAdapter.notifyDataSetChanged();
}
//廣播完成搜索時
@Override
public void finishSearch() {
//停止查詢
//如果藍牙適配器正在掃描,則停止掃描
if(bluetoothAdapter!=null&&bluetoothAdapter.isDiscovering()){
Log.d("---", "finishSearch: " +"停止掃描");
bluetoothAdapter.cancelDiscovery();
}
AlertDialog.Builder builder=new AlertDialog.Builder(PairingDeviceActivity.this);
View view1=inflater.inflate(R.layout.near_devices_alertdialog,null);
ListView nearAvailableListView= (ListView) view1.findViewById(R.id.list_near_devices);
//爲附近可用設備的list綁定adaper
nearAvailableListView.setAdapter(nearDeviceListAdapter);
alertDialog=builder.setTitle("附近的設備")
.setView(view1)
.create();
alertDialog.show();
}
}
【說明1】PairingDeviceActivity實現了BtBroadcastReceiver的接口,這個接口中需要重寫三個方法,finishSearch()和bindSuccess()表示完成搜索和綁定成功。
總結
至此,就完成了藍牙的搜索和配對,上面的代碼還請大家更多關注邏輯上的處理,完整的項目代碼,會在下此寫藍牙數據通信時一併貼出。