Android實(shí)現(xiàn)藍(lán)牙串口通訊
本文實(shí)例為大家分享了Android實(shí)現(xiàn)藍(lán)牙串口通訊的具體代碼,供大家參考,具體內(nèi)容如下
最近在弄藍(lán)牙串口,參考了不少網(wǎng)上的大佬,加上自己早期對C#的學(xué)習(xí),寫一個(gè)給自己的備忘錄,如果有大佬看到還請多多指教。
1.簡介
Android設(shè)備中提供了一整套藍(lán)牙的API,我這邊只取了其中需要的部分。
初期權(quán)限
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
1.BluetoothAdapter
BluetoothAdapter是本地藍(lán)牙適配器的對象,是所有藍(lán)牙交互操作的入口。
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; ? ? private BluetoothAdapter mBluetoothAdapter = null; public ArrayList<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>(); ? ? // 初始化藍(lán)牙 private void BlueInit() { ?? ?// 獲取藍(lán)牙適配器 ?? ?mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); ?? ?// 請求開啟藍(lán)牙 ?? ?if (!mBluetoothAdapter.isEnabled())? ?? ?{ ?? ??? ?Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); ?? ??? ?((Activity)_context).startActivityForResult(enableBtIntent, 1); ?? ?} }
這里我只獲取了已經(jīng)匹配好的藍(lán)牙模塊,Android本身自帶搜索匹配藍(lán)牙設(shè)備功能。太麻煩了,還有匹配,還要輸PIN碼。
直接搜索已經(jīng)匹配的藍(lán)牙模塊。
2.BluetoothDevice
表示遠(yuǎn)程的藍(lán)牙設(shè)備可進(jìn)行遠(yuǎn)程藍(lán)牙設(shè)備的連接請求,以及查詢該藍(lán)牙設(shè)備的信息,例如名稱,地址等。
protected void onResume()? { ?? ?// 將已配對的設(shè)備添加到列表中 ?? ?Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); ?? ?deviceList.clear(); ?? ?if (pairedDevices.size() > 0)? ?? ?{ ?? ??? ?String[] nameList = new String[pairedDevices.size()]; ?? ??? ?int i=0; ?? ??? ?for (BluetoothDevice device : pairedDevices) ?? ??? ?{ ? ? ? ? ? ? ? ?deviceList.add(device); ?? ??? ??? ?nameList[i] = device.getName() + "\n" + device.getAddress(); ?? ??? ??? ?i++; ??? ?} ?? ??? ?//創(chuàng)建一個(gè)ArrayAdapter ?? ??? ?ArrayAdapter<?> adapter=new ArrayAdapter<Object>((Activity)_context,android.R.layout.simple_expandable_list_item_1,nameList); ?? ??? ?DeviceView.setAdapter(adapter); ?? ??? ?//注冊一個(gè)元素單擊事件監(jiān)聽方法 ?? ??? ?DeviceView.setOnItemClickListener(new DeviceClick()); ?? ?} }
然后直接返回給主窗體
//事件按鈕觸發(fā) public class DeviceClick implements AdapterView.OnItemClickListener? { ?? ?@Override ?? ?public void onItemClick(AdapterView<?> arg0, View view, int position, long id)? ?? ?{ ?? ??? ?onConfirmListener.confirm(deviceList.get(position)); ?? ?} ??? ??? ? } public interface OnConfirmListener? { ? ? public void confirm(BluetoothDevice device); }
這里其實(shí)用了一個(gè)Activity的作為一個(gè)Dialog。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ? ? xmlns:tools="http://schemas.android.com/tools" ? ? android:layout_width="match_parent" ? ? android:layout_height="match_parent" ? ? android:paddingBottom="@dimen/activity_vertical_margin" ? ? android:paddingLeft="@dimen/activity_horizontal_margin" ? ? android:paddingRight="@dimen/activity_horizontal_margin" ? ? android:paddingTop="@dimen/activity_vertical_margin" ? ? tools:context="bluetoothtoserial.DeviceActivity" > ? ? ? <ListView ? ? ? ? android:id="@+id/DeviceView" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="match_parent" ? ? ? ? android:layout_alignParentLeft="true" ? ? ? ? android:layout_alignParentTop="true" > ? ? </ListView> </RelativeLayout>
也是方便后面調(diào)用
package bluetoothtoserial; ? import java.util.ArrayList; import java.util.Set; import android.app.Activity; import android.app.Dialog; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; ? public class DeviceActivity extends Dialog? { ?? ?Context _context; ? ? public OnConfirmListener onConfirmListener; ?? ?private ListView DeviceView; ?? ?private BluetoothAdapter mBluetoothAdapter = null; ?? ?public ArrayList<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>(); ? ?? ?public DeviceActivity(Context context)? ?? ?{ ?? ??? ?super(context); ?? ??? ?this._context = context; ?? ??? ?// TODO Auto-generated constructor stub ?? ?} ?? ?@Override ?? ?protected void onCreate(Bundle savedInstanceState)? ?? ?{ ?? ??? ?super.onCreate(savedInstanceState); ?? ??? ?setContentView(R.layout.activity_device); ?? ??? ?DeviceView = (ListView)findViewById(R.id.DeviceView); ?? ??? ?BlueInit(); ?? ??? ?onResume(); ?? ?} ?? ?// 初始化藍(lán)牙 ?? ?private void BlueInit() ?? ?{ ?? ??? ?// 獲取藍(lán)牙適配器 ?? ??? ?mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); ?? ??? ?// 請求開啟藍(lán)牙 ?? ??? ?if (!mBluetoothAdapter.isEnabled())? ?? ??? ?{ ?? ??? ??? ?Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); ?? ??? ??? ?((Activity)_context).startActivityForResult(enableBtIntent, 1); ?? ??? ?} ?? ?} ?? ?protected void onResume()? ?? ?{ ?? ??? ?// 將已配對的設(shè)備添加到列表中 ?? ??? ?Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); ?? ??? ?deviceList.clear(); ?? ??? ?if (pairedDevices.size() > 0)? ?? ??? ?{ ?? ??? ??? ?String[] nameList = new String[pairedDevices.size()]; ?? ??? ??? ?int i=0; ?? ??? ??? ?for (BluetoothDevice device : pairedDevices) ?? ??? ??? ?{ ? ? ? ? ? ? ? ? deviceList.add(device); ?? ??? ??? ??? ?nameList[i] = device.getName() + "\n" + device.getAddress(); ?? ??? ??? ??? ?i++; ?? ??? ??? ?} ?? ??? ??? ?//創(chuàng)建一個(gè)ArrayAdapter ?? ??? ??? ?ArrayAdapter<?> adapter=new ArrayAdapter<Object>((Activity)_context,android.R.layout.simple_expandable_list_item_1,nameList); ?? ??? ??? ?DeviceView.setAdapter(adapter); ?? ??? ??? ?//注冊一個(gè)元素單擊事件監(jiān)聽方法 ?? ??? ??? ?DeviceView.setOnItemClickListener(new DeviceClick()); ?? ??? ?} ?? ?} ?? ?//事件按鈕觸發(fā) ? ?? ?public class DeviceClick implements AdapterView.OnItemClickListener? ? ?? ?{ ?? ??? ?@Override ?? ??? ?public void onItemClick(AdapterView<?> arg0, View view, int position, long id)? ?? ??? ?{ ?? ??? ??? ?onConfirmListener.confirm(deviceList.get(position)); ?? ??? ?} ? ?? ??? ? ? ?? ?} ? ?? ?public interface OnConfirmListener? ? ? { ? ? ? ? public void confirm(BluetoothDevice device); ? ? } }
3.BluetoothSocket
BluetoothSocket 藍(lán)牙的socket接口,與TCP Socket類似,設(shè)備添加完成可以開始連接設(shè)備。
這里我直接寫了一個(gè)Session通訊類
package Channel; ? import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.UUID; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.os.Handler; import android.os.Message; ? public class Session extends Thread? { ?? ?private BluetoothDevice _device = null; ?? ?private BluetoothSocket _socket = null; ?? ?private OutputStream _outStream; ?? ?private InputStream _inStream = null;? ?? ?public boolean IsConnect = false; ?? ?public String Name=""; ?? ?public String Address=""; ?? ?Handler _handler; ?? ?public Session(BluetoothDevice _device,Handler _handler) ?? ?{ ?? ??? ?this._handler = _handler; ?? ??? ?this._device = _device; ?? ??? ?this.Name = this._device.getName(); ?? ??? ?this.Address = this._device.getAddress(); ?? ??? ?IsConnect = false; ?? ??? ?try? ? ?? ??? ?{ ? ?? ??? ? ? ?// 藍(lán)牙串口服務(wù)對應(yīng)的UUID。如使用的是其它藍(lán)牙服務(wù),需更改下面的字符串 ? ? ? ? ? ? // UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); ? ?? ??? ? ? ?_socket = _device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); ? ?? ??? ?} catch (Exception e)? ? ?? ??? ?{ ? ?? ??? ? ? ?return; ? ?? ??? ?} ?? ?} ?? ?public void connect() ?? ?{ ?? ??? ?try? ?? ??? ?{ ?? ??? ??? ?_socket.connect(); ?? ??? ??? ?_outStream = _socket.getOutputStream(); ?? ??? ??? ?_inStream = _socket.getInputStream(); ?? ??? ??? ?IsConnect = true; ?? ??? ?} ?? ??? ?catch (IOException e)? ?? ??? ?{ ?? ??? ??? ?IsConnect = false; ?? ??? ??? ?try { ?? ??? ??? ??? ?_socket.close(); ?? ??? ??? ?} catch (IOException e1)? ?? ??? ??? ?{ ?? ??? ??? ?} ? ?? ??? ? ? ?return; ?? ??? ?} ?? ?} ?? ?@Override ?? ?public void run()? ?? ?{ ? ?? ??? ?byte [] buffer = new byte [1024]; ?? ??? ?int len = 0; ?? ??? ?while(true)? ?? ??? ?{ ?? ??? ??? ? //從InputStream讀取 ?? ??? ??? ?try? ?? ??? ??? ?{ ?? ??? ??? ??? ?len = _inStream.read(buffer); ?? ??? ??? ?} catch (IOException e)? ?? ??? ??? ?{ ?? ??? ??? ??? ?continue; ?? ??? ??? ?} ? ? ? ? ? ? if(len> 0) ? ? ? ? ? ? {? ? ? ? ? ? ? ?? ?Message msg = _handler.obtainMessage(); ? ? ? ? ? ? ?? ?msg.what = 0;? ? ? ? ? ? ? ?? ?try? ? ? ? ? ? ? ?? ?{ ?? ??? ??? ??? ??? ?msg.obj=new String(buffer,"UTF-8"); ?? ??? ??? ??? ?} catch (UnsupportedEncodingException e)? ? ? ? ? ? ? ?? ?{ ?? ??? ??? ??? ?} ? ? ? ? ? ? ?? ?_handler.sendMessage(msg); ? ? ? ? ? ? } ?? ??? ?} ?? ?} ?? ?public void Send(String _value) throws IOException ?? ?{ ?? ??? ?_outStream.write(_value.getBytes()); ?? ?} ?? ?public void Close() throws IOException ?? ?{ ?? ??? ?IsConnect = false; ?? ??? ?_socket.close(); ?? ?} }
接下來就是使用,彈窗選擇設(shè)備。
public void btnDevice_Click(View v)//選擇設(shè)備 { ?? ?final DeviceActivity _deviceDialog = new DeviceActivity(this); ?? ?_deviceDialog.onConfirmListener = new ?OnConfirmListener()? ?? ?{ ? ? ? ? @Override ? ? ?? ?public void confirm(BluetoothDevice device) ?? ??? ?{ ?? ??? ??? ?_device = device; ?? ??? ??? ?txtDevice.setText(device.getName()+"\n"+device.getAddress()); ?? ??? ??? ?_deviceDialog.dismiss(); ?? ??? ??? ?btnConnect.setText("連接設(shè)備"); ?? ??? ??? ?btnConnect.setVisibility(View.VISIBLE); ?? ??? ??? ?btnSend.setVisibility(View.INVISIBLE); ?? ??? ?} ?? ?}; ?? ?_deviceDialog.show(); }
選擇完設(shè)備,建立Session連接設(shè)備。
public void btnConnect_Click(View v)//連接設(shè)備 { ? ?? ?_session = new Session(_device,_handler); ? ?? ?setTitle(_session.Name); ? ?? ?_session.connect(); ? ?? ?if (_session.IsConnect) ? ?? ?{ ? ?? ??? ?_session.start(); ? ?? ??? ?btnConnect.setVisibility(View.INVISIBLE); ? ?? ??? ?btnSend.setVisibility(View.VISIBLE); ? ?? ??? ?btnSend.setText("發(fā)送消息"); ?? ?} ? ?? ?else ? ?? ?{ ? ?? ??? ?Toast.makeText(MainActivity.this, ? ?? ??? ??? ??? ?"連接失敗", ? ?? ??? ??? ??? ?Toast.LENGTH_LONG).show(); ? ?? ??? ?btnSend.setVisibility(View.INVISIBLE); ?? ?} }
建立回調(diào)函數(shù)。
Handler _handler=new Handler(Looper.getMainLooper()) { ? ? @Override ?? ?public void handleMessage(Message msg) ?? ?{ ?? ??? ?super.handleMessage(msg); ?? ??? ?edxMessage.setText(edxMessage.getText()+"\n"+msg.obj); ?? ?} };
發(fā)送消息。
public void btnSend_Click(View v)//發(fā)送消息 { ? ?? ?try ? ?? ?{ ?? ??? ?_session.Send(edxContent.getText().toString()); ?? ?} catch (IOException e)? ? ?? ?{ ?? ? ? ?Toast.makeText(MainActivity.this, ? ?? ??? ??? ??? ?"發(fā)送失敗", ? ?? ??? ??? ??? ?Toast.LENGTH_LONG).show(); ?? ?} }
基本上操作就這些。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android 監(jiān)聽?wèi)?yīng)用前/后臺切換實(shí)例代碼
本篇文章主要介紹了Android 監(jiān)聽?wèi)?yīng)用前/后臺切換實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06詳解Android Scroller與computeScroll的調(diào)用機(jī)制關(guān)系
這篇文章主要介紹了詳解Android Scroller與computeScroll的調(diào)用機(jī)制關(guān)系的相關(guān)資料,需要的朋友可以參考下2016-01-01微信小程序 實(shí)現(xiàn)列表刷新的實(shí)例詳解
這篇文章主要介紹了微信小程序 實(shí)現(xiàn)列表刷新的實(shí)例詳解的相關(guān)資料,這里提供了實(shí)現(xiàn)代碼及實(shí)現(xiàn)效果圖,需要的朋友可以參考下2016-11-11Android開發(fā)TextvView實(shí)現(xiàn)鏤空字體效果示例代碼
這篇文章主要介紹了Android開發(fā)TextvView實(shí)現(xiàn)鏤空字體效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10Android RadioGroup和RadioButton控件簡單用法示例
這篇文章主要介紹了Android RadioGroup和RadioButton控件簡單用法,結(jié)合實(shí)例形式分析了Android單選按鈕控件的基本定義、布局與功能實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-07-07Android?Flutter實(shí)現(xiàn)彈簧動畫交互的示例詳解
物理模擬可以讓應(yīng)用程序的交互感覺逼真和互動,本文章實(shí)現(xiàn)了演示了如何使用彈簧模擬將小部件從拖動的點(diǎn)移回中心,感興趣的可以了解一下2023-04-04Android?上實(shí)現(xiàn)DragonBones換裝功能
這篇文章主要介紹了Android?上實(shí)現(xiàn)DragonBones換裝功能,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-06-06總結(jié)Android中多線程更新應(yīng)用的頁面信息的方式
這篇文章主要介紹了總結(jié)Android中多線程更新應(yīng)用的頁面信息的方式,文中共總結(jié)了runOnUiThread、Handler、AsyncTask異步以及View直接在UI線程中更新的方法,需要的朋友可以參考下2016-02-02功能強(qiáng)大的登錄界面Android實(shí)現(xiàn)代碼
這篇文章主要為大家分享了功能強(qiáng)大的登錄界面Android實(shí)現(xiàn)代碼,驗(yàn)證碼制作方法,自帶一鍵刪除功能,用戶名密碼為空時(shí)抖動提示效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10Android 谷歌推薦的VR實(shí)現(xiàn)方式(分享)
下面小編就為大家分享一篇Android 谷歌推薦的VR實(shí)現(xiàn)方式。具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01