由于我这里只有一台支持android的手机(google nexus s),但我的电脑是支持蓝牙的,所以就利用电脑和手机进行蓝牙通信,利用电脑测试借助于小工具:串口调试小助手。上网下载。
原理:android的蓝牙通信类似java的socket编程,一端发送,一端接收,发送点相当于服务器,接收端相当于客户端,也就是说,如果有类库可以帮我们产生服务器和客户端的API接口实例,接下来问题就简单很多,就可以通过JavaIO操作实现数据传输。
代码实现必备知识点:
1、要操作蓝牙,先要在AndroidManifest.xml里加入权限,否则不能操作蓝牙。
<uses-permissionandroid:name="android.permission.BLUETOOTH" />
2、认识几个重要的蓝牙操作类
a) BluetoothAdapter(借助此类可以获得本机上的蓝牙设备)
b) BluetoothServerSocket(由名字可以看出,是蓝牙的服务端的操作类)
OK,需要蓝牙通信的重要类就两个,其他的自己去查看相关文档。
3、各种状态通过Handler来动态显示。
4、布局就是一个非常简单的layout.xml文件,一个textedit和一个button。
代码演示:
1、布局文件main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="match_parent"
- android:layout_height="match_parent">
- <EditText android:layout_height="wrap_content" android:id="@+id/edtMessage"
- android:layout_width="match_parent">
- <requestFocus></requestFocus>
- </EditText>
- <Button android:text="send message" android:id="@+id/btnSend"
- android:layout_width="match_parent" android:layout_height="wrap_content"></Button>
- </LinearLayout>
2、蓝牙核心代码
- package cn.com.leon.bluetooth;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.util.UUID;
- import android.bluetooth.BluetoothAdapter;
- import android.bluetooth.BluetoothServerSocket;
- import android.bluetooth.BluetoothSocket;
- import android.content.Context;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.widget.Toast;
- public class BusiessBlueToothChat {
- private static final String s_Tag = "BusniessBluetooth";
- private BluetoothAdapter m_BluetoothAdapter;
- private Context m_Context;
- private InputStream m_InputStream;
- private OutputStream m_OutputStream;
- private int m_State;
- private int m_StateConnected = 0;
- private int m_StateDisConnect = 1;
- private boolean m_IsNormalClose = false;
- private Message m_Message = new Message();
- private PortListenThread m_PortListenThread;
- private OnPortListener m_OnPortListener;
- private Handler m_Handler = new Handler() {
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case 1:
- Toast.makeText(m_Context, "蓝牙设备不存在或被关闭,打开后重新启动服务",
- Toast.LENGTH_SHORT).show();
- break;
- default:
- break;
- }
- }
- };
- private static final String S_NAME = "BluetoothChat";
- private static final UUID S_UUID = UUID
- .fromString("00001101-0000-1000-8000-00805F9B34FB");
- public interface OnPortListener {
- public abstract void OnReceiverData(String p_Message);
- }
- public BusiessBlueToothChat(Context p_context) {
- m_Context = p_context;
- m_Message.what = 1;
- m_OnPortListener = (OnPortListener) p_context;
- }
- public void CreatePortListen() {
- try {
- // 获得一个本机蓝牙设备
- m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
- // 判断是否不存在蓝牙设备或没有打开
- if (m_BluetoothAdapter != null || m_BluetoothAdapter.isEnabled()) {
- // 已开启蓝牙,创建一个无线射频通信(RFCOMM)蓝牙端口
- BluetoothServerSocket _BluetoothServerSocket = m_BluetoothAdapter
- .listenUsingRfcommWithServiceRecord(S_NAME, S_UUID);
- if (m_PortListenThread == null) {
- // 启动端口监听线程
- m_PortListenThread = new PortListenThread(
- _BluetoothServerSocket);
- m_PortListenThread.start();
- }
- } else {
- m_Handler.sendMessage(m_Message);
- }
- } catch (Exception e) {
- Log.i(s_Tag, e.getMessage());
- CreatePortListen();
- }
- }
- public class PortListenThread extends Thread {
- private BluetoothServerSocket m_BluetoothServerSocket;
- BluetoothSocket _BluetoothSocket;
- public PortListenThread(BluetoothServerSocket p_BluetoothServerSocket) {
- // 初始化Socket
- m_BluetoothServerSocket = p_BluetoothServerSocket;
- }
- @Override
- public void run() {
- try {
- // 调用accept接收对方数据请求
- BluetoothSocket _BluetoothSocket = m_BluetoothServerSocket
- .accept();
- // 获得输出流
- m_OutputStream = _BluetoothSocket.getOutputStream();
- // 修改连接状态,表示已连接
- m_State = m_StateConnected;
- // 建立一个长连接持续接收对方数据
- while (m_State == m_StateConnected) {
- // 获得输入流
- m_InputStream = _BluetoothSocket.getInputStream();
- ReceiverData();
- }
- } catch (Exception e) {
- Log.i(s_Tag, e.getMessage());
- if (!m_BluetoothAdapter.isEnabled()) {
- m_Handler.sendMessage(m_Message);
- }
- }
- }
- public void Close() {
- try {
- m_BluetoothServerSocket.close();
- if (_BluetoothSocket != null) {
- _BluetoothSocket.close();
- }
- if (m_OutputStream != null) {
- m_OutputStream.close();
- }
- if (m_InputStream != null) {
- m_InputStream.close();
- }
- } catch (Exception e) {
- Log.i(s_Tag, e.getMessage());
- }
- }
- }
- public void ReceiverData() {
- try {
- /*
- // 初始化字节数组
- byte[] _Byte = new byte[8];
- // 读取前8个字节获取数据长度
- m_InputStream.read(_Byte);
- // 将字节转换为String字符
- String _Msg = new String(_Byte);
- // 将String字符转换为int数字
- int _Length = Integer.parseInt(_Msg);
- // 按得到的长度再初始化一个字节数组
- _Byte = new byte[_Length];
- // 继续读取剩余的数据
- m_InputStream.read(_Byte);
- // 将两次数据合并为一个完整的数据
- _Msg += new String(_Byte);
- */
- byte[] _Byte = new byte[1024];
- int len = 0;
- int t_temp = 0;
- while((t_temp=m_InputStream.read())!=-1){
- _Byte[len++]=(byte)t_temp;
- }
- String _Msg = new String(_Byte,0,_Byte.length);
- // 调用回调函数,返回到界面处理
- m_OnPortListener.OnReceiverData(_Msg);
- } catch (Exception e) {
- Log.i(s_Tag, e.getMessage());
- if (!m_IsNormalClose) {
- Close(false);
- CreatePortListen();
- }
- }
- }
- public void SendData(String p_Data) {
- try {
- // 调用输出流向对方发送数据
- m_OutputStream.write(p_Data.getBytes());
- } catch (Exception e) {
- Log.i(s_Tag, e.getMessage());
- }
- }
- public void Close(boolean p_IsNormalClose) {
- m_IsNormalClose = p_IsNormalClose;
- m_State = m_StateDisConnect;
- if (m_PortListenThread != null) {
- m_PortListenThread.Close();
- m_PortListenThread = null;
- }
- }
- }
3、MainActivity.java,入口代码
- package cn.com.leon.bluetooth;
- import cn.com.leon.bluetooth.BusiessBlueToothChat.OnPortListener;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- public class MainActivity extends Activity implements OnClickListener, OnPortListener {
- private BusiessBlueToothChat m_BusiessBlueToothChat;
- EditText _edtMessage;
- Button _btnSend;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- InitView();
- InitListener();
- m_BusiessBlueToothChat = new BusiessBlueToothChat(this);
- m_BusiessBlueToothChat.CreatePortListen();
- }
- private void InitView(){
- _edtMessage = (EditText) this.findViewById(R.id.edtMessage);
- _btnSend = (Button) this.findViewById(R.id.btnSend);
- }
- private void InitListener(){
- _btnSend.setOnClickListener(this);
- }
- @Override
- public void onClick(View v){
- switch (v.getId()) {
- case R.id.btnSend:
- m_BusiessBlueToothChat.SendData(_edtMessage.getText().toString());
- break;
- default:
- break;
- }
- }
- @Override
- public void OnReceiverData(String p_Message) {
- Log.i("BusinessBluetooth", "接收到的数据:"+p_Message);
- }
- }
4、注册mianfest.xml文件
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="cn.com.leon.bluetooth"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="10" />
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".MainActivity"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- <uses-permission android:name="android.permission.BLUETOOTH"/>
- </manifest>
完成。