Android蓝牙串口通讯
Roy•Mustang· 人气:0最近在弄蓝牙串口,参考了不少网上的大佬,加上自己早期对C#的学习,写一个给自己的备忘录,如果有大佬看到还请多多指教。
1.简介
Android设备中提供了一整套蓝牙的API,我这边只取了其中需要的部分。
初期权限
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
1.BluetoothAdapter
BluetoothAdapter是本地蓝牙适配器的对象,是所有蓝牙交互操作的入口。
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; private BluetoothAdapter mBluetoothAdapter = null; public ArrayList<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>(); // 初始化蓝牙 private void BlueInit() { // 获取蓝牙适配器 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // 请求开启蓝牙 if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); ((Activity)_context).startActivityForResult(enableBtIntent, 1); } }
这里我只获取了已经匹配好的蓝牙模块,Android本身自带搜索匹配蓝牙设备功能。太麻烦了,还有匹配,还要输PIN码。
直接搜索已经匹配的蓝牙模块。
2.BluetoothDevice
表示远程的蓝牙设备可进行远程蓝牙设备的连接请求,以及查询该蓝牙设备的信息,例如名称,地址等。
protected void onResume() { // 将已配对的设备添加到列表中 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++; } //创建一个ArrayAdapter ArrayAdapter<?> adapter=new ArrayAdapter<Object>((Activity)_context,android.R.layout.simple_expandable_list_item_1,nameList); DeviceView.setAdapter(adapter); //注册一个元素单击事件监听方法 DeviceView.setOnItemClickListener(new DeviceClick()); } }
然后直接返回给主窗体
//事件按钮触发 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); }
这里其实用了一个Activity的作为一个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>
也是方便后面调用
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(); } // 初始化蓝牙 private void BlueInit() { // 获取蓝牙适配器 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // 请求开启蓝牙 if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); ((Activity)_context).startActivityForResult(enableBtIntent, 1); } } protected void onResume() { // 将已配对的设备添加到列表中 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++; } //创建一个ArrayAdapter ArrayAdapter<?> adapter=new ArrayAdapter<Object>((Activity)_context,android.R.layout.simple_expandable_list_item_1,nameList); DeviceView.setAdapter(adapter); //注册一个元素单击事件监听方法 DeviceView.setOnItemClickListener(new DeviceClick()); } } //事件按钮触发 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 蓝牙的socket接口,与TCP Socket类似,设备添加完成可以开始连接设备。
这里我直接写了一个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 { // 蓝牙串口服务对应的UUID。如使用的是其它蓝牙服务,需更改下面的字符串 // 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(); } }
接下来就是使用,弹窗选择设备。
public void btnDevice_Click(View v)//选择设备 { 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("连接设备"); btnConnect.setVisibility(View.VISIBLE); btnSend.setVisibility(View.INVISIBLE); } }; _deviceDialog.show(); }
选择完设备,建立Session连接设备。
public void btnConnect_Click(View v)//连接设备 { _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("发送消息"); } else { Toast.makeText(MainActivity.this, "连接失败", Toast.LENGTH_LONG).show(); btnSend.setVisibility(View.INVISIBLE); } }
建立回调函数。
Handler _handler=new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { super.handleMessage(msg); edxMessage.setText(edxMessage.getText()+"\n"+msg.obj); } };
发送消息。
public void btnSend_Click(View v)//发送消息 { try { _session.Send(edxContent.getText().toString()); } catch (IOException e) { Toast.makeText(MainActivity.this, "发送失败", Toast.LENGTH_LONG).show(); } }
基本上操作就这些。
加载全部内容