2013-09-27 85 views
17

Thiết bị Bluetooth mà tôi đang cố gắng kết nối luôn có cùng mã pin. Điều này sẽ giúp có thể ghép nối thiết bị bằng cách đặt ghim lập trình.Lập trình ghép nối thiết bị Bluetooth mà không cần người dùng nhập mã pin

Sau khi cố gắng tìm cách này có thể được thực hiện, tôi đã kết thúc với mã dưới đây:

BluetoothDevice device = getDevice(); 

//To avoid the popup notification: 
device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true); 
device.getClass().getMethod("cancelPairingUserInput", boolean.class).invoke(device, true); 
byte[] pin = ByteBuffer.allocate(4).putInt(1234).array(); 
//int pinn = 1234; 

//Entering pin programmatically: 
Method ms = device.getClass().getMethod("setPin", byte[].class); 
//Method ms = device.getClass().getMethod("setPasskey", int.class); 
ms.invoke(device, pin); 

//Bonding the device: 
Method mm = device.getClass().getMethod("createBond", (Class[]) null); 
mm.invoke(device, (Object[]) null); 

cancelPairingUserInput mang lại cho tôi một NoSuchMethodException, đó là kỳ lạ bởi vì phương pháp này không tồn tại trong BluetoothDevice lớp.

Có vẻ như Setpin hoặc SetPasskey không làm gì cả. Thiết bị sẽ không ghép nối. Nó chỉ cặp sau khi nhập thủ công ghim.

Vì vậy, dòng duy nhất của mã mà làm việc là: sản lượng

//Bonding the device: 
Method mm = device.getClass().getMethod("createBond", (Class[]) null); 
mm.invoke(device, (Object[]) null); 

Logcat:

09-27 12:34:46.408: ERROR/App(11671): cancelPairingUserInput [boolean] 
     java.lang.NoSuchMethodException: cancelPairingUserInput [boolean] 
     at java.lang.Class.getConstructorOrMethod(Class.java:460) 
     at java.lang.Class.getMethod(Class.java:915) 
     at test.app.bluetooth.model.BluetoothDiscoveryAndPairing.pair(BluetoothDiscoveryAndPairing.java:97) 
     at test.app.bluetooth.model.BluetoothDiscoveryAndPairing.access$000(BluetoothDiscoveryAndPairing.java:25) 
     at test.app.bluetooth.model.BluetoothDiscoveryAndPairing$1.onReceive(BluetoothDiscoveryAndPairing.java:79) 
     at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:756) 
     at android.os.Handler.handleCallback(Handler.java:615) 
     at android.os.Handler.dispatchMessage(Handler.java:92) 
     at android.os.Looper.loop(Looper.java:137) 
     at android.app.ActivityThread.main(ActivityThread.java:4921) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:511) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805) 
     at dalvik.system.NativeStart.main(Native Method) 

Vì vậy, những gì tôi làm sai?

+0

@DuncanJones tôi thêm stacktrace để startpost tôi. – user1816451

Trả lời

11

Phương thức ẩn cancelPairingUserInput không tồn tại trong thiết bị của bạn. Không sử dụng nó.

  1. Bạn nên đăng ký BroadcastReceiver cho android.bluetooth.device.action.PAIRING_REQUEST
  2. Gọi createBond()
  3. Chờ BroadcastReceiver để kích hoạt
  4. Trong BroadcastReceiver nếu hành động là android.bluetooth.device.action .PAIRING_REQUEST gọi phương pháp này
public void setBluetoothPairingPin(BluetoothDevice device) 
{ 
    byte[] pinBytes = convertPinToBytes("0000"); 
    try { 
      Log.d(TAG, "Try to set the PIN"); 
      Method m = device.getClass().getMethod("setPin", byte[].class); 
      m.invoke(device, pinBytes); 
      Log.d(TAG, "Success to add the PIN."); 
      try { 
       device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true); 
       Log.d(TAG, "Success to setPairingConfirmation."); 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       Log.e(TAG, e.getMessage()); 
       e.printStackTrace(); 
      } 
     } catch (Exception e) { 
      Log.e(TAG, e.getMessage()); 
      e.printStackTrace(); 
     } 
} 

Nó cũng hoạt động trên thiết bị có phiên bản Jelly Bean (4.1.2) của Android.

+2

Điều này có thể được thực hiện ở cấp API trước 19 không? Android.bluetooth.device.action.PAIRING_REQUEST chỉ được giới thiệu trên API 19 – FOliveira

+0

Tại sao setPairingConfirmation() cần thiết? Tài liệu Android cho biết rằng tài liệu chỉ áp dụng cho PAIRING_VARIANT_PASSKEY_CONFIRMATION, không áp dụng cho ghép nối kế thừa. Hơn nữa, trên Android6, yêu cầu BLUETOOTH_PRIVILEGED –

2

này là làm việc cho tôi:

IntentFilter filter2 = new IntentFilter(
      "android.bluetooth.device.action.PAIRING_REQUEST"); 
    mActivity.registerReceiver(
      pairingRequest, filter2); 

private final BroadcastReceiver pairingRequest = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 

     if (intent.getAction().equals("android.bluetooth.device.action.PAIRING_REQUEST")) { 
      mBluetoothDevice = needed; 
       try { 
        byte[] pin = (byte[]) BluetoothDevice.class.getMethod("convertPinToBytes", String.class).invoke(BluetoothDevice.class, "1234"); 
        Method m = mBluetoothDevice.getClass().getMethod("setPin", byte[].class); 
        m.invoke(mBluetoothDevice, pin); 
        mBluetoothDevice.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(mBluetoothDevice, true); 
} 
    catch(Exception e) 
{ 

    e.printStackTrace(); 

} 
+0

là mã này chỉ yêu cầu thiết bị đó đang cố gắng ghép nối? Chúng ta không cần bất kỳ mã nào trên thiết bị khác đang được ghép nối? –

+0

Bạn không cần bất kỳ mã nào cho thiết bị khác. Bạn chỉ nên chấp nhận kết nối. (Tôi đã viết mã này cho điện thoại Android được kết nối với máy in di động.) –

Các vấn đề liên quan