Android實(shí)現(xiàn)藍(lán)牙串口通訊
本文實(shí)例為大家分享了Android實(shí)現(xiàn)藍(lán)牙串口通訊的具體代碼,供大家參考,具體內(nèi)容如下
最近在弄藍(lán)牙串口,參考了不少網(wǎng)上的大佬,加上自己早期對(duì)C#的學(xué)習(xí),寫(xiě)一個(gè)給自己的備忘錄,如果有大佬看到還請(qǐng)多多指教。
1.簡(jiǎn)介
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)牙適配器的對(duì)象,是所有藍(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();
?? ?// 請(qǐng)求開(kāi)啟藍(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è)備的連接請(qǐng)求,以及查詢?cè)撍{(lán)牙設(shè)備的信息,例如名稱(chēng),地址等。
protected void onResume()?
{
?? ?// 將已配對(duì)的設(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);
?? ??? ?//注冊(cè)一個(gè)元素單擊事件監(jiān)聽(tīng)方法
?? ??? ?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();
?? ??? ?// 請(qǐng)求開(kāi)啟藍(lán)牙
?? ??? ?if (!mBluetoothAdapter.isEnabled())?
?? ??? ?{
?? ??? ??? ?Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
?? ??? ??? ?((Activity)_context).startActivityForResult(enableBtIntent, 1);
?? ??? ?}
?? ?}
?? ?protected void onResume()?
?? ?{
?? ??? ?// 將已配對(duì)的設(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);
?? ??? ??? ?//注冊(cè)一個(gè)元素單擊事件監(jiān)聽(tīng)方法
?? ??? ??? ?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類(lèi)似,設(shè)備添加完成可以開(kāi)始連接設(shè)備。
這里我直接寫(xiě)了一個(gè)Session通訊類(lèi)
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ù)對(duì)應(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();
?? ?}
}接下來(lái)就是使用,彈窗選擇設(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();
?? ?}
}基本上操作就這些。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android藍(lán)牙服務(wù)查找附近設(shè)備分析探索
- Android藍(lán)牙服務(wù)啟動(dòng)流程分析探索
- Android學(xué)習(xí)筆記之藍(lán)牙功能
- Android?8.0實(shí)現(xiàn)藍(lán)牙遙控器自動(dòng)配對(duì)
- Android12?藍(lán)牙適配的實(shí)現(xiàn)步驟
- Android 連接藍(lán)牙掃碼器無(wú)輸入框的實(shí)現(xiàn)
- 通俗易通講解Android藍(lán)牙鍵值適配
- Android藍(lán)牙的開(kāi)啟和搜索設(shè)備功能開(kāi)發(fā)實(shí)例
相關(guān)文章
Android 監(jiān)聽(tīng)?wèi)?yīng)用前/后臺(tái)切換實(shí)例代碼
本篇文章主要介紹了Android 監(jiān)聽(tīng)?wèi)?yīng)用前/后臺(tái)切換實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧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-11
Android開(kāi)發(fā)TextvView實(shí)現(xiàn)鏤空字體效果示例代碼
這篇文章主要介紹了Android開(kāi)發(fā)TextvView實(shí)現(xiàn)鏤空字體效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
Android RadioGroup和RadioButton控件簡(jiǎn)單用法示例
這篇文章主要介紹了Android RadioGroup和RadioButton控件簡(jiǎn)單用法,結(jié)合實(shí)例形式分析了Android單選按鈕控件的基本定義、布局與功能實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-07-07
Android?Flutter實(shí)現(xiàn)彈簧動(dòng)畫(huà)交互的示例詳解
物理模擬可以讓?xiě)?yīng)用程序的交互感覺(jué)逼真和互動(dòng),本文章實(shí)現(xiàn)了演示了如何使用彈簧模擬將小部件從拖動(dòng)的點(diǎn)移回中心,感興趣的可以了解一下2023-04-04
Android?上實(shí)現(xiàn)DragonBones換裝功能
這篇文章主要介紹了Android?上實(shí)現(xiàn)DragonBones換裝功能,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-06-06
總結(jié)Android中多線程更新應(yīng)用的頁(yè)面信息的方式
這篇文章主要介紹了總結(jié)Android中多線程更新應(yīng)用的頁(yè)面信息的方式,文中共總結(jié)了runOnUiThread、Handler、AsyncTask異步以及View直接在UI線程中更新的方法,需要的朋友可以參考下2016-02-02
功能強(qiáng)大的登錄界面Android實(shí)現(xiàn)代碼
這篇文章主要為大家分享了功能強(qiáng)大的登錄界面Android實(shí)現(xiàn)代碼,驗(yàn)證碼制作方法,自帶一鍵刪除功能,用戶名密碼為空時(shí)抖動(dòng)提示效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10
Android 谷歌推薦的VR實(shí)現(xiàn)方式(分享)
下面小編就為大家分享一篇Android 谷歌推薦的VR實(shí)現(xiàn)方式。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01

