如何以编程方式配对蓝牙设备在Android

问题描述:

我的应用我试图以编程方式配对蓝牙设备。我能够显示我想要配对的设备的配对对话框,并且可以输入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

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

其他选项是查看BluetoothChat应用程序示例并启动RFComm连接套接字,只要您启动套接字,配对请求就会自动出现,而无需发送单独的配对意图。这样你就不需要处理配对。

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

除了我的评论,顺便说一下,即使这些动作类型确实存在,这不是你如何使用它们。这里有一个例子:

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

我发现,使用不同的值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.*.com/rooms/new)并邀请其他用户进入它。 – 2011-12-03 00:02:51

不幸的是,我认为你会得到最好的是开放设置/无线&网络/蓝牙设置的用户,像这样:

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

我设法自动请求与键盘配对过程通过作为服务工作的应用程序检查特定设备是否存在特定类型的设备以及设置应用程序的修改版本。

我不得不说,我正在使用运行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

使用反射可以从BluetoothDevice类调用createBond方法。

看到这个职位:How to unpair or delete paired bluetooth device programmatically on android?

还为解除配对的解决方案。

我使用这个类做我的智能手机客户端和服务器设备之间的连接:

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

这是我如何得到它:

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); 

反思是狡猾的,不同的厂商可以改变这些基本方法如他们所愿!我已经在我们的10台设备上测试了许多不同的应用程序,这些反射方法仅适用于大约75%的设备。如果你想要一个适用于每个人的应用,在使用反射时要非常小心 - 尝试一些云测试以在100多个设备上测试你的应用并检查失败率。

在这种情况下反射并不需要在所有自API 19(奇巧4.4)

BluetoothDevice类具有新方法CreateBond。

private void pairDevice(BluetoothDevice device) { 

      device.createBond(); 
    } 

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

这是我的答案:

中的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 
      } 
     } 
    } 
};