1. 程式人生 > 其它 >Android 藍芽操作詳解

Android 藍芽操作詳解

1.啟用藍芽並使裝置處於可發現狀態    

   1.1 在使用BluetoothAdapter類的例項進操作之前,應啟用isEnable()方法檢查裝置是否啟用了藍芽介面卡。

    // 使用意圖提示使用者啟用藍芽,並使裝置處於可發現狀態

 private void startBluetooth() {
          BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
  // 檢測藍芽是否開啟
  if (!bt.isEnabled()) {
              Intent enableIntent = new Intent(
                        BluetoothAdapter. ACTION_REQUEST_ENABLE);
              startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
          }
     }

 1.2返回意圖活動時,呼叫onActivityResult(),可以提取主裝置名稱和mac地址

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == REQUEST_ENABLE_BT
                   && resultCode == Activity. RESULT_OK) {
              BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
              String address = bt.getAddress();
              String name = bt.getName();
              String toastText = name + " :" + address;
              Toast. makeText(this, toastText, Toast.LENGTH_LONG).show();
              discoverable();
          }
     }

1.3 請求使用者授權,讓裝置可被其它臨近裝置發現:

 // 請求使用者授權,讓裝置在120秒內處於可發現狀態
 private void discoverable() {
          Intent discoverableIntent = new Intent(
 BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
          startActivity(discoverableIntent);
     }

2.連線啟用藍芽裝置

 2.1對於任何藍芽應用,都必須在AndroidManifst.xml中新增如下許可權:

    <uses-permission android:name= "android.permission.BLUETOOTH_ADMIN" />
 <uses-permission android:name= "android.permission.BLUETOOTH" />

2.2 建立到其他藍芽裝置的套接字連線

     我們應該在一個執行緒內持續監聽套接字流中的資料。可以在該執行緒外寫入連線的流。這種連線是一個阻塞呼叫,由於藍芽裝置發現是一個緩慢的過程,可能降低連線速率。所以,在連線其它裝置之前要取消裝置發現。

     藍芽套接字連線時阻塞呼叫,只在連線成功或者連線裝置發生異常時才會返回。BluetoothConnection一經例項化,就會建立到其他裝置的連線,並開始監聽來自連線裝置的資料。

package com.example.blueoothdemo;

 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.UUID;

 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothSocket;

 /**
 * 讀寫藍芽裝置
 *
 * @author hbbliyong
 *
 */
 public class BluetoothConnecion extends Thread {
      private final BluetoothSocket mSocket;
      private final InputStream mInStream;
      private final OutputStream mOutStream;
      byte[] buffer;
      private final BluetoothAdapter mAdapter;
      // 用於本應用程式唯一的UUID,
      private static final UUID MY_UUID = UUID
                .fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");

      public BluetoothConnecion(BluetoothDevice device) {
           BluetoothSocket tmp = null;
           mAdapter = BluetoothAdapter.getDefaultAdapter();
           // 獲得用於指定藍芽連線的BluetoothSocket
           try {
                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
           } catch (Exception e) {
                e.printStackTrace();
           }
           mSocket = tmp;

           // 在新執行緒中建立套接字連線,避免FC
           Thread connectionThread = new Thread(new Runnable() {
                @Override
                public void run() {
                     // TODO Auto-generated method stub
                     // 始終取消發現,因為它會降低連線的速度
                     mAdapter.cancelDiscovery();

                     // 建立到BluetoothSocket的連線
                     try {
                          // 這是一個阻塞呼叫,只在成功連線或者異常時返回
                          mSocket.connect();
                     } catch (Exception e) {
                          e.printStackTrace();
                          // 裝置連線失敗,關閉套接字
                          try {
                               mSocket.close();
                          } catch (Exception e2) {
                               // TODO: handle exception
                               e2.printStackTrace();
                          }
                     }
                }
           });

           connectionThread.start();

           InputStream tmpIn = null;
           OutputStream tmpOut = null;

           // 獲得BluetoothSoket輸入輸出流
           try {
                tmpIn = mSocket.getInputStream();
                tmpOut = mSocket.getOutputStream();
                buffer = new byte[1024];
           } catch (Exception e) {
                e.printStackTrace();
           }
           mInStream = tmpIn;
           mOutStream = tmpOut;
      }

      public void run() {
           // 連線時保持監聽InputStream
           while (true) {
                try {
                     // 從套接字流讀取資料
                     mInStream.read(buffer);
                     // 向UI Activity傳送獲取的資料
                } catch (Exception e) {
                     // TODO: handle exception
                     // 這裡的異常標誌著連線的丟失
                     // 向UI Activity傳送獲取的資料
                     break;
                }
           }
      }
 
      public void write(byte[] buffer)
      {
           try {
                mOutStream.write(buffer);
           } catch (Exception e) {
                e.printStackTrace();
           }
      }
 
      public void cancel()
      {
           try {
                mSocket.close();
           } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
           }
      }
 }

3.監聽和接收藍芽連線請求

在兩個藍芽裝置互動之前,其中一個通訊裝置必須起伺服器的作用。它獲取一個BluetoothServerSocket例項並監聽入站請求。這個例項通過呼叫藍芽介面卡上的listenUsingRfcommWithServiceRecord()方法獲得。有了這個例項我們可以通過start()方法開始監聽來自遠端裝置的入站請求。

  //使主裝置處於可發現狀態
  Intent disCoverableIntent = new Intent(
                      BluetoothAdapter. ACTION_REQUEST_DISCOVERABLE);
  startActivityForResult(disCoverableIntent,DISCOVERY_REQUEST_BLUETOOTH );

 //建立一個藍芽伺服器並接受連線
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == DISCOVERY_REQUEST_BLUETOOTH ) {
  boolean isDiscoverable = resultCode > 0;
  if (isDiscoverable) {
  // UUID
  // uuid=UUID.fromString("a60f35f0-b93a-11de-8a39-08002009c666");
  final UUID uuid = UUID.randomUUID();
  final String serverName = "BTServer" ;
  final BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
  final BluetoothServerSocket bluetoothServer;
                   Thread listenThread = new Thread(new Runnable() {
  @Override
  public void run() {
  // TODO Auto-generated method stub
  try {
                                  bluetoothServer = bt.listenUsingRfcommWithServiceRecord(serverName, uuid);
                    BluetoothSocket serverSocket = bluetoothServer.accept();
                    myHandleConnectionWiht(serverSocket);
                             } catch (Exception e) {
                                  e.printStackTrace();
                             }
                        }
  private void myHandleConnectionWiht(
                                  BluetoothSocket serverSocket) {
  // TODO Auto-generated method stub
                        }
                   });
                   listenThread.start();
              }
          }
     }