1. 程式人生 > >Android連續的獲取藍芽的RSSI

Android連續的獲取藍芽的RSSI

 基於藍芽的RSSI可以有很多應用,要獲得藍芽的RSSI無外乎兩種方法,一種就是基於掃瞄的方法,優點是Android本身支援,缺點是scan的時間比較長,並且中間過程不受控制,為了連續的測量,需要不斷的scan;第二種就是,基於連線的方法,前提是要建立兩個藍芽裝置的連線後,再測量RSSI,優點是後期測量比較方便,間隔時間也較短。

連續測量Android裝置(Java)的藍芽RSSI教程

在撰寫本文時,即使存在用於獲取WiFi RSSI的API,也沒有可用於連續檢索現有藍芽連線的RSSI的API。當前API將只在初始連線建立過程中獲得藍芽RSSI。在本文中,我們將瞭解如何從執行Linux的計算機上連續獲取Android裝置和諾基亞行動電話的藍芽RSSI。

連線到計算機的任何裝置的RSSI可以通過在Linux中使用HCIOOL來確定。但是,對於商業化的Android裝置,這可能是不可能的,因為要使用Android NDK從藍芽HCI層呼叫任何函式,需要根訪問。出於實驗目的,為了開發商用手持裝置上的藍芽裝置,我們將通過將這些裝置連線到計算機或膝上型計算機來測量這些裝置的RSSI。

在這個實驗中,RSSI從安卓裝置(Nexus 7平板)和諾基亞手機(Xpress Music)上連續地從基於Ubuntu的計算機上進行測量。原始碼使用BlueClub藍芽庫從這些連線的裝置中提取RSSI資訊。Android裝置和諾基亞裝置就像伺服器一樣,計算機就像客戶機一樣。

在計算機上,我們需要編寫客戶端程式碼,它將不斷地從我們已知的裝置中輪詢RSSI。為了做到這一點,我們需要首先從這裡檢查bluecove藍芽庫(http://bluecove.org/source-repository.html)。然後我們可以利用BLUTEOTROSRIPSION CIENT.java來獲取RSSI讀數。我們可以利用我們已知裝置的藍芽MAC地址過濾掉其他發現的裝置。在將裝置與計算機連線之後,我們可以從Ubuntu中的藍芽選單的偏好選項卡獲得裝置的藍芽MAC地址。

客戶端:

public void PollRSSI()
{
try { 
while(true)
                 {
          try {
          System.out.println();
          if(Android_Device != null)
          System.out.println("Android RSSI = " + RemoteDeviceHelper.readRSSI(Android_Device));
     } catch (Exception e) { System.out.println("Android RSSI = Connection Error"); }
          try {
          if(Nokia != null)
          System.out.println("Nokia RSSI = " + RemoteDeviceHelper.readRSSI(Nokia));
      } catch (Exception e) { System.out.println("Nokia RSSI = Connection Error"); }   
          Thread.sleep(2000);
                }
     } catch (Exception e){ e.printStackTrace(); }
}
對於Android裝置,我們需要編寫自己的伺服器程式碼,以克服[13 ]許可權拒絕錯誤。我們可能需要在Android裝置上執行多個伺服器執行緒(Access Tox.java),這樣一來,傳入的連線請求將在初始許可權拒絕錯誤之後最終被接受。我們還將指定客戶端可以搜尋和連線的RfCOMM UUID和服務名稱。整個伺服器必須在Android(BrutoToSursService,Java)中實現為服務,這樣,如果顯示螢幕超時,連線不會丟失。

服務端:

public AcceptThread()
{
                   BluetoothServerSocket tmp = null;
                   mBluetooth = BluetoothAdapter.getDefaultAdapter();
                   mUuid = UUID.fromString("00000003-0000-1000-8000-00805F9B34FB");
        try {
                tmp = mBluetooth.listenUsingInsecureRfcommWithServiceRecord("BluetoothCustomService",      mUuid);          
             } catch (IOException e) { }
                myServerSocket = tmp;
         }

public void onCreate()
{
super.onCreate();

thread1 = new Thread(new AcceptThread());
thread1.start(); //First thread will often be denied
thread2 = new Thread(new AcceptThread());
thread2.start(); //Most probably be accepted

}

 

對於諾基亞裝置,不需要顯式的伺服器,我們可以簡單地使用藍芽串列埠配置檔案連線url進行連線。一旦建立連線,我們就可以週期性地輪詢來自兩個裝置的RSSI。

注意:藍芽的RSSI可能不是室內定位等應用的有效和可靠的引數。

原始碼:

藍芽

參考文獻:

“基於藍芽的超級市場導航系統”-珍珠馬諾哈蘭,維格納什·斯巴拉曼尼亞和阿努沙·武相簿裡-課程專案-移動系統16:332:559:02F12(羅格斯秋季2012)->

HTTP://ExcRe.ANDROID.COM/GUID/TopICS/CaluleVisty/BuLotoTo.HTML

HTTP://StAccOfFult.COM/DISSMS/1225178/ANDROID-BLUTITOT-RES-RSSI-訊號強度

HTTP://BueleCovi.Org/BeLeCoo-Expuls/BraveCooTeSt/Dex.HTML

有TX問到,為什麼RSSI=0,解釋如下文,簡單點就是這個值是裝置相關的。

 

http://www.robomotic.com/android/bluetooth-rssi/

RSSI是一個8位有符號整數,表示Re-(RX)功率電平在金的內部或上方或下方接收機功率範圍(GRPR),被認為是理想的

RX功率範圍。圖1說明了兩者之間的關係。GRPR和RSSI在藍芽技術中的應用。POS—固定或負RSSI(dB)表示RX功率電平為

GRPR的上方或下方,而零點意味著這是理想的(也就是說,在GRPR內)。上下閾值GRPR的幼體是鬆散結合的,留下它們是裝置。這反過來又影響RSSI,因為它僅僅是一個相關引數。事實上,它的絕對準確性不是人。在特定的情況下,唯一的要求是能夠指示它是否在GRPR的內部、上方或下方。這個藍芽的RSSI狀態引數特別適用於用於電力控制目的〔6〕。接收器傳送“in -“傳送”或“減少”TPL請求到傳送端,DE懸而未決的RSSI是否被認為是負面的或陽性。