本文实例为大家分享了Android实现蓝牙串口通讯的具体代码,供大家参考,具体内容如下
最近在弄蓝牙串口,参考了不少网上的大佬,加上自己早期对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();
}
}
基本上操作就这些。