【问题标题】:Android Bluetooth Pairing without User Enter Pin and Confirmation Using Android API无需用户输入密码和使用 Android API 确认的 Android 蓝牙配对
【发布时间】:2016-06-01 20:29:05
【问题描述】:

我是 Android 编程的初学者,因为我才 3 个月前才开始。我正在做一个使用蓝牙将 android 应用程序连接到 arduino 的项目。我已经有一个 Android 应用程序的代码(bluetooth.adapter、sockets 等)。连接代码已经在工作。目标之一是让 android 应用程序在与蓝牙设备配对时自动输入密码,而不要求用户输入 PIN。

这个论坛上的旧帖子没有多大帮助。 (很多人建议使用不安全模式,但我确实需要安全模式,在我的情况下,arduino 是服务器,而手机应用程序是客户端,所以 createInsecureRfcommSocketToServiceRecord() 服务器方法对我不起作用)

我在 android 开发者网站上搜索并发现了这个关于蓝牙设备类的内容:

setPairingConfirmation(布尔确认) 确认 PAIRING_VARIANT_PASSKEY_CONFIRMATION 配对的密钥。

PAIRING_VARIANT_PIN = "系统将提示用户输入 pin 或应用程序将为用户输入 pin"。

PAIRING_VARIANT_PASSKEY_CONFIRMATION = "系统将提示用户确认屏幕上显示的密码或应用程序将为用户确认密码"

似乎使用代码,应用程序将是输入密码并确认的应用程序 密码使其成为“自动连接”功能,但 android 网站未提供有关如何使用此功能的示例代码。你们有没有使用这个或相关过程的示例代码?感谢您的帮助!

【问题讨论】:

    标签: android bluetooth android-bluetooth pairing


    【解决方案1】:

    是的,这可以通过代码来实现

    在你的主要活动中添加以下代码

    BluetoothReceiver myreceiver = new BluetoothReceiver();
    var intentfilterparingrequest = new IntentFilter(BluetoothDevice.ActionPairingRequest);
    RegisterReceiver(myreceiver, intentfilterparingrequest);
    

    在您的广播接收器中编写以下代码,如果没有创建一个新的广播接收器

    public class BluetoothReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            string BLE_PIN = "0000";
            var action = intent.Action;
            switch (action)
            {
                case BluetoothDevice.ActionPairingRequest:
                    BluetoothDevice bluetoothDevice = 
                  (BluetoothDevice)intent.GetParcelableExtra(BluetoothDevice.ExtraDevice);
                    bluetoothDevice.SetPin(Encoding.ASCII.GetBytes(BLE_PIN));
                    bluetoothDevice.CreateBond();
                    break;
            }
        } 
    }
    

    【讨论】:

      【解决方案2】:

      我也遇到了同样的问题,经过所有的研究,我想出了以下解决方案。

      (经过测试并且可以正常工作!!!)

      我基本上是在寻找一个特定的蓝牙设备(我知道 MAC 地址)并在找到后与它配对。首先要做的是使用 boradcast 接收器创建配对请求,并按如下方式处理请求。

      IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
                      intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
                      registerReceiver(broadCastReceiver,intentFilter);
      

      你需要编写broadcastReceiver并如下处理。

      String BLE_PIN = "1234"
      private BroadcastReceiver broadCastReceiver = new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
              String action = intent.getAction();
              if(BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action))
              {
                  BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                  bluetoothDevice.setPin(BLE_PIN.getBytes());
                  Log.e(TAG,"Auto-entering pin: " + BLE_PIN);
                  bluetoothDevice.createBond();
                  Log.e(TAG,"pin entered and request sent...");
              }
          }
      };
      

      瞧!您应该能够在没有任何手动干预的情况下与蓝牙设备配对。

      希望这会有所帮助 :-) 如果它适合你,请给出正确的答案。

      【讨论】:

      • 这个解决方案也适用于安卓 oreo 和 pie 吗?
      • 是的。据我所知,它有效。您可以尝试在此处发布您的更新。
      • 你能解释一下my question
      • 不工作!首先如果设置了Pin,还需要确认配对请求,这个操作只能人工干预(安卓安全)。其次,您不会使用“abortBroadcast()”来消除接收器内部的意图
      【解决方案3】:

      首先澄清一下,这个解决方案是为更新版本的 API(15 或更高版本?)设计的

      我在另一篇文章中找到了答案(请参阅 Roldofo 在Here 中的答案)。这是我重组后的详细代码答案。

      简而言之,您需要设置一个广播接收器来捕获 ACTION_PAIRING_REQUEST,然后以编程方式传递 PIN 并确认。

      注册一个广播接收器:

          IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
          getActivity().registerReceiver(mPairingRequestReceiver, filter);
      

      接收者的定义:

      private final BroadcastReceiver mPairingRequestReceiver = new BroadcastReceiver() {
          public void onReceive(Context context, Intent intent) {
              String action = intent.getAction();
              if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
                  try {
                          BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                          int pin=intent.getIntExtra("android.bluetooth.device.extra.PAIRING_KEY", 1234);
                          //the pin in case you need to accept for an specific pin
                          Log.d(TAG, "Start Auto Pairing. PIN = " + intent.getIntExtra("android.bluetooth.device.extra.PAIRING_KEY",1234));
                          byte[] pinBytes;
                          pinBytes = (""+pin).getBytes("UTF-8");
                          device.setPin(pinBytes);
                          //setPairing confirmation if neeeded
                          device.setPairingConfirmation(true);
                  } catch (Exception e) {
                      Log.e(TAG, "Error occurs when trying to auto pair");
                      e.printStackTrace();
                  }
              }
          }
      };
      

      然后在您的活动或片段(无论您想在哪里启动配对),您可以调用以下定义的 pairDevice() 方法来调用配对尝试(这将生成一个 ACTION_PAIRING_REQUEST)

      private void pairDevice(BluetoothDevice device) {
          try {
              Log.d(TAG, "Start Pairing... with: " + device.getName());
              device.createBond();
              Log.d(TAG, "Pairing finished.");
          } catch (Exception e) {
              Log.e(TAG, e.getMessage());
          }
      }
      

      【讨论】:

      • 如何处理密码/pin 包含字符串“hello123”之类的 varchars?
      • 为什么需要 setPairingConfirmation() ? Android 文档说它仅适用于 PAIRING_VARIANT_PASSKEY_CONFIRMATION,不适用于旧版配对。此外,在 Android6 上它需要 BLUETOOTH_PRIVILEGED
      • 不幸的是,在当前的 API 级别中,BLUETOOTH_PRIVILEGED 不可用。文档:This is not available to third party applications.
      • 如果我不希望弹出的配对键输入可见怎么办?
      • @SergioMartins 我在BluetoothDevice.setPairingConfirmation 的文档中看到并意识到它需要权限 BLUETOOTH_ADMIN 而不是 BLUETOOTH_PRIVILEGED
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      • 2012-07-22
      • 1970-01-01
      • 2013-07-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多