2011-02-14 139 views
17

我的應用我試圖以編程方式配對藍牙設備。我能夠顯示我想要配對的設備的配對對話框,並且可以輸入PIN碼。當我按「對」時,對話框被刪除,沒有任何反應。如何以編程方式配對藍牙設備在Android

我只需要支持與Android 2.0及更高版本的設備。

目前我使用下面的代碼來開始配對的進展:


public void pairDevice(BluetoothDevice device) { 
     String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST"; 
     Intent intent = new Intent(ACTION_PAIRING_REQUEST); 
     String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE"; 
     intent.putExtra(EXTRA_DEVICE, device); 
     String EXTRA_PAIRING_VARIANT = "android.bluetooth.device.extra.PAIRING_VARIANT"; 
     int PAIRING_VARIANT_PIN = 0; 
     intent.putExtra(EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN); 
     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     context.startActivity(intent); 
    } 

開始配對請求我停止掃描新設備之前。

我的應用有以下藍牙權限:

  • android.permission.BLUETOOTH_ADMIN
  • android.permission.BLUETOOTH
+2

我花了幾天l對這個確切問題的解決方案進行補充。看起來谷歌認爲強制配對是一個安全問題,所以你在這裏列出的ACTION類型實際上並不存在。我發現你在這裏引用的類:http://developer.oesf.biz/em/developer/reference/cinnamon/android/bluetooth/BluetoothDevice.html#ACTION_PAIRING_REQUEST 但它不在官方文檔中: http:// developer .android.com/reference/android/bluetooth/BluetoothDevice.html – moonlightcheese 2011-06-24 18:40:07

+0

@FireFLy你有什麼解決方案嗎? – Pawan 2012-04-15 12:31:29

+0

你有解決方案嗎? – 2012-06-14 21:29:07

回答

0

可能是你需要startActivityForResult而不是僅startActivity?

其他選項是查看BluetoothChat應用程序示例並啓動RFComm連接套接字,只要您啓動套接字,配對請求就會自動出現,而無需發送單獨的配對意圖。這樣你就不需要處理配對。

http://developer.android.com/resources/samples/BluetoothChat/index.html

-2

除了我的評論,順便說一下,即使這些動作類型確實存在,這不是你如何使用它們。這裏有一個例子:

Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST); 
intent.putExtra(EXTRA_DEVICE, device); 
int PAIRING_VARIANT_PIN = 272; 
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN); 
sendBroadcast(intent); 
+3

我試過了,它不起作用。 – Derzu 2013-01-22 18:56:48

-1

我發現,使用不同的值PAIRING_VARIANT_PIN導致不同的配對UI行爲。

看到這個頁面: http://code.google.com/p/backport-android-bluetooth/source/browse/trunk/backport-android-bluetooth201/src/backport/android/bluetooth/BluetoothDevice.java?spec=svn67&r=67

我懷疑你遇到的問題是,這兩個設備都支持藍牙2.1,在這種情況下的配對請求應導致6位數字的密碼兩個設備上顯示。

最好的結果,我能夠實現使用PAIRING_VARIANT_PIN = 0是當由我的應用程序提示,我進入銷1234和一個6位密鑰出現我的目標設備上。配對用戶界面完成了,就是這樣。

要麼你需要找出如何啓動藍牙2.1配對請求,使用一些其他的配對變體或配對變種針。或者,你沒有捕捉正確運行的活動的結果。

鑑於時間我一直在試圖做到這一點的量,我已經決定,我的最終用戶就只能用我的應用程序之前,使用Android設置進行配對。

+0

@Peter O. Stack Overflow通知我你已經編輯了這個。因爲這是我的第一篇文章,所以我有一些問題,如果你不介意的話: - 我不記得我原來的信息,所以我看不到你刪除了什麼。有沒有辦法做到這一點? - 你有機會解決這個問題嗎? - 是否有辦法直接向用戶發送消息,而不是現在做我正在做的事情? 在此先感謝。 – user1007074 2011-12-02 17:10:00

+0

1.單擊單詞「編輯」後的日期以查看編輯歷史記錄。 2.不,我沒有辦法解決這個問題,因爲我不熟悉這個問題。不,不像私人信息那樣直接。但是,如果任一用戶至少有100個聲望,而另一個用戶至少有20個聲望,則前者可以[創建一個畫廊聊天室](http://chat.stackoverflow.com/rooms/new)並邀請其他用戶進入它。 – 2011-12-03 00:02:51

3

不幸的是,我認爲你會得到最好的是開放設置/無線&網絡/藍牙設置的用戶,像這樣:

Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS); 
    startActivityForResult(intent, REQUEST_PAIR_DEVICE); 
9

我設法自動請求與鍵盤配對過程通過作爲服務工作的應用程序檢查特定設備是否存在特定類型的設備以及設置應用程序的修改版本。

我不得不說,我正在使用運行Android 4.0.3的自定義設備,沒有外部控件(無回/家/確認按鈕):在啓動完成時將控制器配對完成,無需任何交互,直到PIN請求爲必填項。

首先我創建開始就啓動(與android.intent.action.BOOT_COMPLETEDandroid.permission.RECEIVE_BOOT_COMPLETED)定期檢查一個1344類設備對的onReceive回調存在(一個鍵盤,以根據要求輸入數據的唯一途徑)的活性的服務:

public void onReceive(Context context, Intent intent) 
... 
    BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
... 
if(dev.getBluetoothClass().getDeviceClass() == 1344){...} 

過濾後,我選擇第一鍵盤可用,然後我通過BT地址設置應用:

Intent btSettingsIntent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS); 
btSettingsIntent.putExtra("btcontroller", dev.getAddress()); 
startActivityForResult(btSettingsIntent, 1); 

最棘手的部分是尋找一個叫配對過程的最佳位置。只使用

intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN); 

讓我進入一個配對對話框,一旦關閉,我的設備配對,但無法使用。

挖掘到com.Android.settings.Bluetooth的班,我發現我的方式,通過

createDevicePreference(CachedBluetoothDevice cachedDevice) 
在DeviceListPreferenceFragment

從那裏我做比較我與那些可用來了,一旦匹配成功我打電話

cachedDevice.startPairing(); 

我知道,這是棘手和需要訪問Android源代碼之前選擇的BT地址,但在自定義它的工作環境。

我希望這可能會有所幫助。

+0

無法使其工作,你建議.. – 2013-02-15 04:42:25

0

我使用這個類做我的智能手機客戶端和服務器設備之間的連接:

private class ConnectThread extends Thread 
{ 
    private final BluetoothSocket mmSocket; 

    private final UUID WELL_KNOWN_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); 

    public ConnectThread(BluetoothDevice device) 
    { 
     // Use a temporary object that is later assigned to mmSocket,because 
     // mmSocket is final 
     BluetoothSocket tmp = null; 

     // Get a BluetoothSocket to connect with the given BluetoothDevice 
     try 
     { 
      tmp = device.createRfcommSocketToServiceRecord(WELL_KNOWN_UUID); 
      //This is the trick 
      Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class }); 
      tmp = (BluetoothSocket) m.invoke(device, 1); 
     } catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 

     mmSocket = tmp; 
    } 

    public void run() 
    { 
     DebugLog.i(TAG, "Trying to connect..."); 
     // Cancel discovery because it will slow down the connection 
     mBluetoothAdapter.cancelDiscovery(); 

     try 
     { 
      // Connect the device through the socket. This will block 
      // until it succeeds or throws an exception 
      mmSocket.connect(); 
      DebugLog.i(TAG, "Connection stablished"); 
     } catch (IOException connectException) 
     { 
      // Unable to connect; close the socket and get out 
      DebugLog.e(TAG, "Fail to connect!", connectException); 
      try 
      { 
       mmSocket.close(); 
      } catch (IOException closeException) 
      { 
       DebugLog.e(TAG, "Fail to close connection", closeException); 
      } 
      return; 
     } 
    } 

    /** Will cancel an in-progress connection, and close the socket */ 
    public void cancel() 
    { 
     try 
     { 
      mmSocket.close(); 
     } catch (IOException e) 
     { 
     } 
    } 
} 

首先獲得您想要連接(上市配對的設備或discoverying設備)的BluetoothDevice對象。然後做:

ConnectThread ct = new ConnectThread(device); 
ct.start(); 

因爲connect()是一個阻塞調用,這個連接過程應始終在一個線程從主線程的活動分開進行。有關更多詳細信息,請參閱Android Developers

-1

這是我如何得到它:

Bluetooth device = mBtAdapter.getRemoteDevice(address); 
//address:11:23:FF:cc:22 
Method m = device.getClass()   
.getMethod("createBond", (Class[]) null); 
     m.invoke(device, (Object[]) null); // send pairing dialog request 

After pairing// 
     connectDevice(address); 
2

反思是狡猾的,不同的廠商可以改變這些基本方法如他們所願!我已經在我們的10臺設備上測試了許多不同的應用程序,這些反射方法僅適用於大約75%的設備。如果你想要一個適用於每個人的應用,在使用反射時要非常小心 - 嘗試一些雲測試以在100多個設備上測試你的應用並檢查失敗率。

在這種情況下反射並不需要在所有自API 19(奇巧4.4)

BluetoothDevice類具有新方法CreateBond。

private void pairDevice(BluetoothDevice device) { 

      device.createBond(); 
    } 

developer.android.com/reference/android/bluetooth/BluetoothDevice.html

4

這是我的答案:

中的onCreate

()這樣寫:

registerReceiver(incomingPairRequestReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST)); 

然後創建變量

private final BroadcastReceiver incomingPairRequestReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     String action = intent.getAction(); 
     if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) { 
      BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
      //pair from device: dev.getName() 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
       dev.setPairingConfirmation(true); 
       //successfull pairing 
      } else { 
       //impossible to automatically perform pairing, 
       //your Android version is below KITKAT 
      } 
     } 
    } 
};