Android之蓝牙编程开发详解

   我们知道,Android从2.0版本后的sdk开始才支持蓝牙开发,现在一般都不用蓝牙,而且模拟器不支持,测试至少需要两部手机,所以制约了很多技术人员的开发,Demo在国内更是少之又少。技术来源于网络,也要归属于网络,所以此次放置上来供大家共享学习。

        由于我这里只有一台支持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

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical" android:layout_width="match_parent"  
  4.     android:layout_height="match_parent">  
  5.   
  6.     <EditText android:layout_height="wrap_content" android:id="@+id/edtMessage"  
  7.         android:layout_width="match_parent">  
  8.         <requestFocus></requestFocus>  
  9.     </EditText>  
  10.       
  11.     <Button android:text="send message" android:id="@+id/btnSend"  
  12.         android:layout_width="match_parent" android:layout_height="wrap_content"></Button>  
  13.   
  14. </LinearLayout>  


2、蓝牙核心代码

[java]  view plain copy
  1. package cn.com.leon.bluetooth;  
  2.   
  3. import java.io.InputStream;  
  4. import java.io.OutputStream;  
  5. import java.util.UUID;  
  6.   
  7. import android.bluetooth.BluetoothAdapter;  
  8. import android.bluetooth.BluetoothServerSocket;  
  9. import android.bluetooth.BluetoothSocket;  
  10. import android.content.Context;  
  11. import android.os.Handler;  
  12. import android.os.Message;  
  13. import android.util.Log;  
  14. import android.widget.Toast;  
  15.   
  16. public class BusiessBlueToothChat {  
  17.   
  18.     private static final String s_Tag = "BusniessBluetooth";  
  19.     private BluetoothAdapter m_BluetoothAdapter;  
  20.     private Context m_Context;  
  21.     private InputStream m_InputStream;  
  22.     private OutputStream m_OutputStream;  
  23.     private int m_State;  
  24.     private int m_StateConnected = 0;  
  25.     private int m_StateDisConnect = 1;  
  26.     private boolean m_IsNormalClose = false;  
  27.     private Message m_Message = new Message();  
  28.     private PortListenThread m_PortListenThread;  
  29.     private OnPortListener m_OnPortListener;  
  30.   
  31.     private Handler m_Handler = new Handler() {  
  32.   
  33.         public void handleMessage(Message msg) {  
  34.             switch (msg.what) {  
  35.             case 1:  
  36.                 Toast.makeText(m_Context, "蓝牙设备不存在或被关闭,打开后重新启动服务",  
  37.                         Toast.LENGTH_SHORT).show();  
  38.                 break;  
  39.             default:  
  40.                 break;  
  41.             }  
  42.         }  
  43.   
  44.     };  
  45.   
  46.     private static final String S_NAME = "BluetoothChat";  
  47.     private static final UUID S_UUID = UUID  
  48.             .fromString("00001101-0000-1000-8000-00805F9B34FB");  
  49.   
  50.     public interface OnPortListener {  
  51.   
  52.         public abstract void OnReceiverData(String p_Message);  
  53.   
  54.     }  
  55.   
  56.     public BusiessBlueToothChat(Context p_context) {  
  57.         m_Context = p_context;  
  58.         m_Message.what = 1;  
  59.         m_OnPortListener = (OnPortListener) p_context;  
  60.     }  
  61.   
  62.     public void CreatePortListen() {  
  63.         try {  
  64.             // 获得一个本机蓝牙设备  
  65.             m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  
  66.   
  67.             // 判断是否不存在蓝牙设备或没有打开  
  68.             if (m_BluetoothAdapter != null || m_BluetoothAdapter.isEnabled()) {  
  69.                 // 已开启蓝牙,创建一个无线射频通信(RFCOMM)蓝牙端口  
  70.                 BluetoothServerSocket _BluetoothServerSocket = m_BluetoothAdapter  
  71.                         .listenUsingRfcommWithServiceRecord(S_NAME, S_UUID);  
  72.   
  73.                 if (m_PortListenThread == null) {  
  74.                     // 启动端口监听线程  
  75.                     m_PortListenThread = new PortListenThread(  
  76.                             _BluetoothServerSocket);  
  77.                     m_PortListenThread.start();  
  78.                 }  
  79.             } else {  
  80.                 m_Handler.sendMessage(m_Message);  
  81.             }  
  82.         } catch (Exception e) {  
  83.             Log.i(s_Tag, e.getMessage());  
  84.             CreatePortListen();  
  85.         }  
  86.     }  
  87.   
  88.     public class PortListenThread extends Thread {  
  89.   
  90.         private BluetoothServerSocket m_BluetoothServerSocket;  
  91.         BluetoothSocket _BluetoothSocket;  
  92.   
  93.         public PortListenThread(BluetoothServerSocket p_BluetoothServerSocket) {  
  94.             // 初始化Socket  
  95.             m_BluetoothServerSocket = p_BluetoothServerSocket;  
  96.         }  
  97.   
  98.         @Override  
  99.         public void run() {  
  100.             try {  
  101.                 // 调用accept接收对方数据请求  
  102.                 BluetoothSocket _BluetoothSocket = m_BluetoothServerSocket  
  103.                         .accept();  
  104.                 // 获得输出流  
  105.                 m_OutputStream = _BluetoothSocket.getOutputStream();  
  106.                 // 修改连接状态,表示已连接  
  107.                 m_State = m_StateConnected;  
  108.                 // 建立一个长连接持续接收对方数据  
  109.                 while (m_State == m_StateConnected) {  
  110.                     // 获得输入流  
  111.                     m_InputStream = _BluetoothSocket.getInputStream();  
  112.                     ReceiverData();  
  113.                 }  
  114.             } catch (Exception e) {  
  115.                 Log.i(s_Tag, e.getMessage());  
  116.                 if (!m_BluetoothAdapter.isEnabled()) {  
  117.                     m_Handler.sendMessage(m_Message);  
  118.                 }  
  119.             }  
  120.         }  
  121.   
  122.         public void Close() {  
  123.             try {  
  124.                 m_BluetoothServerSocket.close();  
  125.                 if (_BluetoothSocket != null) {  
  126.                     _BluetoothSocket.close();  
  127.                 }  
  128.                 if (m_OutputStream != null) {  
  129.                     m_OutputStream.close();  
  130.                 }  
  131.                 if (m_InputStream != null) {  
  132.                     m_InputStream.close();  
  133.                 }  
  134.   
  135.             } catch (Exception e) {  
  136.                 Log.i(s_Tag, e.getMessage());  
  137.             }  
  138.         }  
  139.     }  
  140.   
  141.     public void ReceiverData() {  
  142.         try {  
  143.             /* 
  144.             // 初始化字节数组 
  145.             byte[] _Byte = new byte[8]; 
  146.             // 读取前8个字节获取数据长度 
  147.             m_InputStream.read(_Byte); 
  148.             // 将字节转换为String字符 
  149.             String _Msg = new String(_Byte); 
  150.             // 将String字符转换为int数字 
  151.             int _Length = Integer.parseInt(_Msg); 
  152.             // 按得到的长度再初始化一个字节数组 
  153.             _Byte = new byte[_Length]; 
  154.             // 继续读取剩余的数据 
  155.             m_InputStream.read(_Byte); 
  156.             // 将两次数据合并为一个完整的数据 
  157.             _Msg += new String(_Byte); 
  158.             */  
  159.             byte[] _Byte = new byte[1024];  
  160.             int len = 0;  
  161.             int t_temp = 0;  
  162.             while((t_temp=m_InputStream.read())!=-1){  
  163.                 _Byte[len++]=(byte)t_temp;  
  164.             }  
  165.             String _Msg = new String(_Byte,0,_Byte.length);  
  166.             // 调用回调函数,返回到界面处理  
  167.             m_OnPortListener.OnReceiverData(_Msg);  
  168.   
  169.         } catch (Exception e) {  
  170.             Log.i(s_Tag, e.getMessage());  
  171.             if (!m_IsNormalClose) {  
  172.                 Close(false);  
  173.                 CreatePortListen();  
  174.             }  
  175.         }  
  176.   
  177.     }  
  178.   
  179.     public void SendData(String p_Data) {  
  180.         try {  
  181.             // 调用输出流向对方发送数据  
  182.             m_OutputStream.write(p_Data.getBytes());  
  183.         } catch (Exception e) {  
  184.             Log.i(s_Tag, e.getMessage());  
  185.         }  
  186.     }  
  187.   
  188.     public void Close(boolean p_IsNormalClose) {  
  189.         m_IsNormalClose = p_IsNormalClose;  
  190.         m_State = m_StateDisConnect;  
  191.         if (m_PortListenThread != null) {  
  192.             m_PortListenThread.Close();  
  193.             m_PortListenThread = null;  
  194.         }  
  195.     }  
  196. }  


 3、MainActivity.java,入口代码

[java]  view plain copy
  1. package cn.com.leon.bluetooth;  
  2.   
  3. import cn.com.leon.bluetooth.BusiessBlueToothChat.OnPortListener;  
  4. import android.app.Activity;  
  5. import android.os.Bundle;  
  6. import android.util.Log;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.widget.Button;  
  10. import android.widget.EditText;  
  11.   
  12. public class MainActivity extends Activity implements OnClickListener, OnPortListener {  
  13.       
  14.     private BusiessBlueToothChat m_BusiessBlueToothChat;  
  15.       
  16.     EditText _edtMessage;  
  17.     Button _btnSend;  
  18.   
  19.     @Override  
  20.     public void onCreate(Bundle savedInstanceState) {  
  21.         super.onCreate(savedInstanceState);  
  22.         setContentView(R.layout.main);  
  23.       
  24.         InitView();  
  25.         InitListener();  
  26.           
  27.         m_BusiessBlueToothChat = new BusiessBlueToothChat(this);  
  28.         m_BusiessBlueToothChat.CreatePortListen();  
  29.     }  
  30.       
  31.     private void InitView(){  
  32.         _edtMessage = (EditText) this.findViewById(R.id.edtMessage);  
  33.         _btnSend = (Button) this.findViewById(R.id.btnSend);  
  34.     }  
  35.       
  36.     private void InitListener(){  
  37.         _btnSend.setOnClickListener(this);  
  38.     }  
  39.       
  40.     @Override  
  41.     public void onClick(View v){  
  42.         switch (v.getId()) {  
  43.         case R.id.btnSend:  
  44.             m_BusiessBlueToothChat.SendData(_edtMessage.getText().toString());  
  45.             break;  
  46.   
  47.         default:  
  48.             break;  
  49.         }  
  50.     }  
  51.   
  52.     @Override  
  53.     public void OnReceiverData(String p_Message) {  
  54.         Log.i("BusinessBluetooth""接收到的数据:"+p_Message);  
  55.           
  56.     }  
  57. }  


4、注册mianfest.xml文件

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="cn.com.leon.bluetooth"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.     <uses-sdk android:minSdkVersion="10" />  
  7.   
  8.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  9.         <activity android:name=".MainActivity"  
  10.                   android:label="@string/app_name">  
  11.             <intent-filter>  
  12.                 <action android:name="android.intent.action.MAIN" />  
  13.                 <category android:name="android.intent.category.LAUNCHER" />  
  14.             </intent-filter>  
  15.         </activity>  
  16.     </application>  
  17.       
  18.     <uses-permission android:name="android.permission.BLUETOOTH"/>  
  19.       
  20. </manifest>  


完成。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值