2013-09-27 20 views
17

Urządzenie Bluetooth, które próbuję połączyć, ma zawsze ten sam kod PIN. Powinno to umożliwić parowanie urządzenia poprzez programowe ustawienie pinezki.Programowo sparuj urządzenie Bluetooth bez wpisywania numeru przez użytkownika.

Po wypróbowaniu szukać, jak można to zrobić, skończyło się z poniższym kodzie:

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 daje mi NoSuchMethodException, co jest dziwne, ponieważ metoda nie istnieje w BluetoothDevice klasie.

Wygląda na to, że Setpin lub SetPasskey nic nie robi. Urządzenie po prostu się nie paruje. Paruje tylko po ręcznym wprowadzeniu szpilki.

Więc jedyna linia kodu, który działa to: wyjście

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

Co robię źle?

+0

@DuncanJones StackTrace dodałem do mojego startpost. – user1816451

Odpowiedz

11

Ukryta metoda cancelPairingUserInput nie istnieje w urządzeniu. Nie używaj go.

  1. Należy zarejestrować BroadcastReceiver dla android.bluetooth.device.action.PAIRING_REQUEST
  2. połączeń createBond()
  3. Poczekaj na BroadcastReceiver wywołać
  4. W BroadcastReceiver jeśli działanie jest android.bluetooth.device.action .PAIRING_REQUEST wywołanie tej metody
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(); 
     } 
} 

Działa również na urządzeniu z wersją Jelly Bean (4.1.2) Androida.

+2

Czy można to zrobić na poziomie interfejsu API przed 19? Android.bluetooth.device.action.PAIRING_REQUEST został wprowadzony tylko w interfejsie API 19 – FOliveira

+0

Dlaczego wymagana jest funkcja setPairingConfirmation()? Dokumenty z Androidem mówią, że dotyczy to tylko PAIRING_VARIANT_PASSKEY_CONFIRMATION, a nie parowania starszego typu. Co więcej, na Androidzie 6 wymaga BLUETOOTH_PRIVILEGED –

2

to działa na mnie:

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

czy ten kod jest wymagany tylko przez to urządzenie, które próbuje się sparować? Czy nie potrzebujemy kodu na innym urządzeniu, które jest sparowane? –

+0

Nie potrzebujesz żadnego kodu do drugiego urządzenia. Powinieneś po prostu zaakceptować połączenie. (Napisałem ten kod dla telefonu z Androidem, który łączył się z drukarką mobilną.) –

Powiązane problemy