Android 蓝牙聊天室之官方例子


2013.09.05——— android 蓝牙聊天室之官方例子 


http://lipeng88213.iteye.com/blog/1937036



蓝牙开发的大致流程: 

1、蓝牙权限 

Java代码   收藏代码
  1. <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />  
  2.     <uses-permission android:name="android.permission.BLUETOOTH" />  


2、认设备是否支持蓝牙 
Java代码   收藏代码
  1. /** 
  2.          * 确认设备是否支持蓝牙 
  3.          * 如果getDefaultAdapter()返回null,则这个设备不支持蓝牙 
  4.          */  
  5.         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  
  6.   
  7.         // If the adapter is null, then Bluetooth is not supported  
  8.         //手机不支持蓝牙  
  9.         if (mBluetoothAdapter == null) {  
  10.             Toast.makeText(this"Bluetooth is not available", Toast.LENGTH_LONG).show();  
  11.             finish();  
  12.             return;  
  13.         }  


3、确定蓝牙能够使用 
Java代码   收藏代码
  1. /** 
  2.          * 确定蓝牙能够使用。 
  3.          * 通过isEnabled()来检查蓝牙当前是否可用。 
  4.          * 如果这个方法返回false,则蓝牙不能够使用。这个时候 就请求蓝牙使用,通过intent来请求 
  5.          * 在onActivityResult()里面判断 
  6.          */  
  7.         if (!mBluetoothAdapter.isEnabled()) {  
  8.             Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);  
  9.             startActivityForResult(enableIntent, REQUEST_ENABLE_BT);  
  10.         // Otherwise, setup the chat session  
  11.         }  

会打开一个对话框中显示请求使用蓝牙权限。如果响应"Yes",这个进程完成(或失败)后你的应用将能够使用蓝牙,选择no,就结束应用 

Java代码   收藏代码
  1. case REQUEST_ENABLE_BT:  
  2.             // When the request to enable Bluetooth returns  
  3.             if (resultCode == Activity.RESULT_OK) {  
  4.                 // Bluetooth is now enabled, so set up a chat session  
  5.                 //请求蓝牙成功,这个时候 蓝也可用  
  6.                 setupChat();  
  7.             } else {  
  8.                 // User did not enable Bluetooth or an error occurred  
  9.                 //请求蓝牙失败,退出应用  
  10.                 Log.d(TAG, "BT not enabled");  
  11.                 Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();  
  12.                 finish();  
  13.             }  



4、最为服务器端,你必须让其他设备能够看到你,才能跟你建立连接 
Java代码   收藏代码
  1. //设置自己可以被其他设备搜索到  
  2.     private void ensureDiscoverable() {  
  3.         if(D) Log.d(TAG, "ensure discoverable");  
  4.         if (mBluetoothAdapter.getScanMode() !=  
  5.             BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {  
  6.             Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);  
  7.             discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);  
  8.             startActivity(discoverableIntent);  
  9.         }  
  10.     }  

5、找已经匹配的设备 
在搜索设备前,查询配对设备看需要的设备是否已经是已经存在是很值得的,可以调用getBondedDevices()来做到,该函数会返回一个描述配对设备BluetoothDevice的结果集 
Java代码   收藏代码
  1. //查找已经匹配的设备  
  2.         Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();  
  3.   
  4.         // If there are paired devices, add each one to the ArrayAdapter  
  5.         if (pairedDevices.size() > 0) {  
  6.             findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);  
  7.             for (BluetoothDevice device : pairedDevices) {  
  8.                 mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());  
  9.             }  
  10.         } else {  
  11.             String noDevices = getResources().getText(R.string.none_paired).toString();  
  12.             mPairedDevicesArrayAdapter.add(noDevices);  
  13.         }  

6、扫描设备 
Java代码   收藏代码
  1. /** 
  2.      * Start device discover with the BluetoothAdapter 
  3.      */  
  4.     private void doDiscovery() {  
  5.         if (D) Log.d(TAG, "doDiscovery()");  
  6.   
  7.         // Indicate scanning in the title  
  8.         setProgressBarIndeterminateVisibility(true);  
  9.         setTitle(R.string.scanning);  
  10.   
  11.         // Turn on sub-title for new devices  
  12.         findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);  
  13.   
  14.         // If we're already discovering, stop it  
  15.         //如果正在搜索 就先停止  
  16.         if (mBtAdapter.isDiscovering()) {  
  17.             mBtAdapter.cancelDiscovery();  
  18.         }  
  19.   
  20.         // Request discover from BluetoothAdapter  
  21.         //搜索设备 用BroadcastReceiver接受BluetoothDevice.ACTION_FOUND  
  22.         mBtAdapter.startDiscovery();  
  23.     }  


要开始搜索设备,只需简单的调用startDiscovery() 。该函数时异步的,调用后立即返回,返回值表示搜索是否成功开始。可以再BroadcastReceiver里面监听结果 

Java代码   收藏代码
  1. private final BroadcastReceiver mReceiver = new BroadcastReceiver() {  
  2.         @Override  
  3.         public void onReceive(Context context, Intent intent) {  
  4.             String action = intent.getAction();  
  5.   
  6.             // When discovery finds a device  
  7.             if (BluetoothDevice.ACTION_FOUND.equals(action)) {  
  8.                 // Get the BluetoothDevice object from the Intent  
  9.                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  
  10.                 // If it's already paired, skip it, because it's been listed already  
  11.                 if (device.getBondState() != BluetoothDevice.BOND_BONDED) {  
  12.                     mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());  
  13.                 }  
  14.             // When discovery is finished, change the Activity title  
  15.             }  
  16.     };  


7、作为客户端连接 
扫描出来的列表,单击任意一个item,得到这个设备的mac地址和name 
Java代码   收藏代码
  1. // The on-click listener for all devices in the ListViews  
  2.     private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {  
  3.         public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {  
  4.             // Cancel discovery because it's costly and we're about to connect  
  5.             //停止搜索  
  6.             mBtAdapter.cancelDiscovery();  
  7.   
  8.             // Get the device MAC address, which is the last 17 chars in the View  
  9.             String info = ((TextView) v).getText().toString();  
  10.             String address = info.substring(info.length() - 17);  
  11.   
  12.             // Create the result Intent and include the MAC address  
  13.             Intent intent = new Intent();  
  14.             intent.putExtra(EXTRA_DEVICE_ADDRESS, address);  
  15.   
  16.             // Set result and finish this Activity  
  17.             setResult(Activity.RESULT_OK, intent);  
  18.             finish();  
  19.         }  
  20.     };  

根据mac地址 得到远端BluetoothDevice 
       
Java代码   收藏代码
  1. BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);  


然后 根据device得到BluetoothSocket,并建立连接 
Java代码   收藏代码
  1. private class ConnectThread extends Thread {  
  2.         private final BluetoothSocket mmSocket;  
  3.         private final BluetoothDevice mmDevice;  
  4.         private String mSocketType;  
  5.   
  6.         public ConnectThread(BluetoothDevice device, boolean secure) {  
  7.             mmDevice = device;  
  8.             BluetoothSocket tmp = null;  
  9.             mSocketType = secure ? "Secure" : "Insecure";  
  10.   
  11.             // Get a BluetoothSocket for a connection with the  
  12.             // given BluetoothDevice  
  13.             //来生成一个BluetoothSocket对象  
  14.             //这个uuid必须服务器和客户端是同一个  
  15.             try {  
  16.                 if (secure) {  
  17.                     tmp = device.createRfcommSocketToServiceRecord(  
  18.                             MY_UUID_SECURE);  
  19.                 } else {  
  20.                     tmp = device.createInsecureRfcommSocketToServiceRecord(  
  21.                             MY_UUID_INSECURE);  
  22.                 }  
  23.             } catch (IOException e) {  
  24.                 Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);  
  25.             }  
  26.             mmSocket = tmp;  
  27.         }  
  28.   
  29.         public void run() {  
  30.             Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);  
  31.             //设置当前线程名字  
  32.             setName("ConnectThread" + mSocketType);  
  33.   
  34.             // Always cancel discovery because it will slow down a connection  
  35.             //因为扫描设备 很浪费资源 停止扫描  
  36.             mAdapter.cancelDiscovery();  
  37.   
  38.             // Make a connection to the BluetoothSocket  
  39.             //用connect()完成连接  
  40.             //系统会在远程设备上完成一个SDP查找来匹配UUID。  
  41.             //如果查找成功并且远程设备接受连接,就共享RFCOMM信道,connect()会返回。  
  42.             //这也是一个阻塞的调用,不管连接失败还是超时(12秒)都会抛出异常。  
  43.             try {  
  44.                 // This is a blocking call and will only return on a  
  45.                 // successful connection or an exception  
  46.                 mmSocket.connect();  
  47.             } catch (IOException e) {  
  48.                 // Close the socket  
  49.                 try {  
  50.                     mmSocket.close();  
  51.                 } catch (IOException e2) {  
  52.                     Log.e(TAG, "unable to close() " + mSocketType +  
  53.                             " socket during connection failure", e2);  
  54.                 }  
  55.                 connectionFailed();  
  56.                 return;  
  57.             }  
  58.   
  59.             // Reset the ConnectThread because we're done  
  60.             synchronized (BluetoothChatService.this) {  
  61.                 mConnectThread = null;  
  62.             }  
  63.   
  64.             // Start the connected thread  
  65.             //启动连接成功 可以通信的线程  
  66.             connected(mmSocket, mmDevice, mSocketType);  
  67.         }  
  68.   
  69.         public void cancel() {  
  70.             try {  
  71.                 mmSocket.close();  
  72.             } catch (IOException e) {  
  73.                 Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e);  
  74.             }  
  75.         }  
  76.     }  


8、作为服务器端建立连接 

Java代码   收藏代码
  1. private class AcceptThread extends Thread {  
  2.         // The local server socket  
  3.         private final BluetoothServerSocket mmServerSocket;  
  4.         private String mSocketType;  
  5.   
  6.         public AcceptThread(boolean secure) {  
  7.             BluetoothServerSocket tmp = null;  
  8.             mSocketType = secure ? "Secure":"Insecure";  
  9.   
  10.             // Create a new listening server socket  
  11.             //通过调用listenUsingRfcommWithServiceRecord(String, UUID)得到一个BluetoothServerSocket对象  
  12.             try {  
  13.                 if (secure) {  
  14.                     tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,  
  15.                         MY_UUID_SECURE);  
  16.                 } else {  
  17.                     tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(  
  18.                             NAME_INSECURE, MY_UUID_INSECURE);  
  19.                 }  
  20.             } catch (IOException e) {  
  21.                 Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);  
  22.             }  
  23.             mmServerSocket = tmp;  
  24.         }  
  25.   
  26.         public void run() {  
  27.             if (D) Log.d(TAG, "Socket Type: " + mSocketType +  
  28.                     "BEGIN mAcceptThread" + this);  
  29.             setName("AcceptThread" + mSocketType);  
  30.   
  31.             BluetoothSocket socket = null;  
  32.   
  33.             // Listen to the server socket if we're not connected  
  34.             while (mState != STATE_CONNECTED) {  
  35.                 try {  
  36.                     // This is a blocking call and will only return on a  
  37.                     // successful connection or an exception  
  38.                     //通过调用accept()来侦听连接请求。  
  39.                     socket = mmServerSocket.accept();  
  40.                 } catch (IOException e) {  
  41.                     Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e);  
  42.                     break;  
  43.                 }  
  44.   
  45.                 // If a connection was accepted  
  46.                 if (socket != null) {  
  47.                     synchronized (BluetoothChatService.this) {  
  48.                         switch (mState) {  
  49.                         case STATE_LISTEN:  
  50.                         case STATE_CONNECTING:  
  51.                             // Situation normal. Start the connected thread.  
  52.                             connected(socket, socket.getRemoteDevice(),  
  53.                                     mSocketType);  
  54.                             break;  
  55.                         case STATE_NONE:  
  56.                         case STATE_CONNECTED:  
  57.                             // Either not ready or already connected. Terminate new socket.  
  58.                             try {  
  59.                                 socket.close();  
  60.                             } catch (IOException e) {  
  61.                                 Log.e(TAG, "Could not close unwanted socket", e);  
  62.                             }  
  63.                             break;  
  64.                         }  
  65.                     }  
  66.                 }  
  67.             }  
  68.             if (D) Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType);  
  69.   
  70.         }  
  71.   
  72.         public void cancel() {  
  73.             if (D) Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this);  
  74.             try {  
  75.                 mmServerSocket.close();  
  76.             } catch (IOException e) {  
  77.                 Log.e(TAG, "Socket Type" + mSocketType + "close() of server failed", e);  
  78.             }  
  79.         }  
  80.     }  


9、与远端设备通信 

Java代码   收藏代码
  1. //处理与远端的通信  
  2.     private class ConnectedThread extends Thread {  
  3.         private final BluetoothSocket mmSocket;  
  4.         private final InputStream mmInStream;  
  5.         private final OutputStream mmOutStream;  
  6.   
  7.         public ConnectedThread(BluetoothSocket socket, String socketType) {  
  8.             Log.d(TAG, "create ConnectedThread: " + socketType);  
  9.             mmSocket = socket;  
  10.             InputStream tmpIn = null;  
  11.             OutputStream tmpOut = null;  
  12.   
  13.             // Get the BluetoothSocket input and output streams  
  14.             try {  
  15.                 tmpIn = socket.getInputStream();  
  16.                 tmpOut = socket.getOutputStream();  
  17.             } catch (IOException e) {  
  18.                 Log.e(TAG, "temp sockets not created", e);  
  19.             }  
  20.   
  21.             mmInStream = tmpIn;  
  22.             mmOutStream = tmpOut;  
  23.         }  
  24.   
  25.         public void run() {  
  26.             Log.i(TAG, "BEGIN mConnectedThread");  
  27.             byte[] buffer = new byte[1024];  
  28.             int bytes;  
  29.   
  30.             // Keep listening to the InputStream while connected  
  31.             while (true) {  
  32.                 try {  
  33.                     // Read from the InputStream  
  34.                     bytes = mmInStream.read(buffer);  
  35.   
  36.                     // Send the obtained bytes to the UI Activity  
  37.                     mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)  
  38.                             .sendToTarget();  
  39.                 } catch (IOException e) {  
  40.                     Log.e(TAG, "disconnected", e);  
  41.                     connectionLost();  
  42.                     // Start the service over to restart listening mode  
  43.                     BluetoothChatService.this.start();  
  44.                     break;  
  45.                 }  
  46.             }  
  47.         }  
  48.   
  49.         /** 
  50.          * Write to the connected OutStream. 
  51.          * @param buffer  The bytes to write 
  52.          */  
  53.         //发送信息给远端  
  54.         public void write(byte[] buffer) {  
  55.             try {  
  56.                 mmOutStream.write(buffer);  
  57.   
  58.                 // Share the sent message back to the UI Activity  
  59.                 mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)  
  60.                         .sendToTarget();  
  61.             } catch (IOException e) {  
  62.                 Log.e(TAG, "Exception during write", e);  
  63.             }  
  64.         }  
  65.   
  66.         public void cancel() {  
  67.             try {  
  68.                 mmSocket.close();  
  69.             } catch (IOException e) {  
  70.                 Log.e(TAG, "close() of connect socket failed", e);  
  71.             }  
  72.         }  
  73.     } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值