2015-09-18 21 views
11

Używanie klasy do śledzenia Runtime show, że metoda onReceive() nie wywołuje, dlaczego?Rejestracja odbiornika dynamicznie nie działa - BluetoothDevice.ACTION_FOUND

Rejestracja odbiornik transmisji dynamicznie

private void discoverDevices() { 
    Log.e("MOHAB","BEFORE ON RECEIVE"); 

    mReceiver = new BroadcastReceiver() { 
     public void onReceive(Context context, Intent intent) { 
      Log.e("MOHAB","ON RECEIVE"); 
      String action = intent.getAction(); 
      // When discovery finds a device 
      if (BluetoothDevice.ACTION_FOUND.equals(action)) { 
       // Get the BluetoothDevice object from the Intent 
       BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
       // Add the name and address to an array adapter to show in a ListView 
       Bluetooth b = new Bluetooth(device.getName(),device.getAddress()); 
       list.add(b); 
      } 
     } 
    }; 
    Log.e("MOHAB","create intentFilter"); 
    // Register the BroadcastReceiver 
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 
    registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy 

} 
+0

Dlaczego twój odbiornik transmisji został zainicjowany w funkcji? –

+2

ten kod, aby odkryć pobliskie urządzenia bluetooth .. umieszczam ten kod w zdarzeniu onClick(), co jest właściwym sposobem? – Error

+0

BroadcastReceiver są wywoływane, gdy są rozróżniane przez nadawane wiadomości.zainicjuj go na zewnątrz na metodęCreate, a nie w swojej funkcji. –

Odpowiedz

6

co przegapiłeś jest to, że trzeba zacząć ożywienia urządzenie

Najpierw dostać adapter Bluetooth

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 

Po tym, rozpocznij wykrywanie, dzwoniąc pod numer

mBtAdapter.startDiscovery(); 

Powinieneś również przeczytać szczegóły tutaj, np. około cancelDiscovery() http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery%28%29

P.S. Sugeruje się również użycie context.getSystemService(Context.BLUETOOTH_SERVICE), aby uzyskać BluetoothAdapter na API 18+, zgodnie z oficjalnym dokumentem.

Aby uzyskać BluetoothAdapter reprezentujący lokalną adapter Bluetooth, gdy działa na JELLY_BEAN_MR1 i poniżej, należy wywołać metodę statyczną getDefaultAdapter(); przy uruchomieniu JELLY_BEAN_MR2 i nowszym, pobierz go przez getSystemService (Class) za pomocą BLUETOOTH_SERVICE.

Edit: przypomnieć, że trzeba BLUETOOTH_ADMIN pozwolenie na startDiscovery()

+1

Nie udało mi się uruchomić Discovery(), ale jest inny błąd z Odbiornikiem! – Error

0

Delegowanie to jako odpowiedź, jak nie mogę wypowiedzieć się z moim obecnym poziomie Rep.

Czy masz uprawnienia Bluetooth w swoim AndroidManifest.xml?

<uses-permission android:name="android.permission.BLUETOOTH"/> 
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> 

Jeśli nie, spróbuj (i sprawdź) każdy osobno, ponieważ nie pamiętam, jak ważne są poszczególne.

Jeśli tak, proszę podać więcej kodu, aby możliwe było zdiagnozowanie problemu.

+1

Problem nie z kodem Bluetooth i używam tych uprawnień. jest onReceive nie nazywa się – Error

3

Nie wiem, czy Twój kod jest poprawny w uzyskiwaniu urządzenia Bluetooth. Oto co czuję na temat twojego kodu. Inicjowanie i rejestrowanie BroadcastReceiver w funkcji jest złym pomysłem. powinieneś to zrobić poza metodą onCreate(). oto co trzeba zrobić w kodzie

jako o rejestracji Reciver że musi to być zrobione w onCreate() jak ten

registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND)); 

następujące z inicjowania lub odbiornik

private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      Log.e("MOHAB","ON RECEIVE"); 
      String action = intent.getAction(); 
      // When discovery finds a device 
      if (BluetoothDevice.ACTION_FOUND.equals(action)) { 
       // Get the BluetoothDevice object from the Intent 
       BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
       // Add the name and address to an array adapter to show in a ListView 
       Bluetooth b = new Bluetooth(device.getName(),device.getAddress()); 
       list.add(b); 
      } 
     } 
    }; 

wyrejestrowania reciver w onPause() nie zapomnij o tym, że

i tylko w Twoim discoverDevices() zwróć list urządzeń dodanych przez reciver dla każdego wywołania tej fumction;

+1

onReceive nie nazywa !!! – Error

+0

Twój kod nie może wysyłać audycji. –

+1

public void regigsterReceiver() { Filtr IntentFilter = new IntentFilter (BluetoothDevice.ACTION_FOUND); registerReceiver (mReceiver, filter); } Jak zarejestrować odbiornik – Error

30

Pomijając fakt, że starting with Android 6.0 you have to have the ACCESS_COARSE_LOCATION permission to receive ACTION_FOUND (jak @siniux już wspomniano), jest inny, powiązany rzecz:

ACCESS_COARSE_LOCATION jest wśród dangerous permissions że trzeba wyraźnie zażądać od użytkownika w czasie wykonywania (inny poprawy bezpieczeństwa, która weszła w 6,0).

Aby zdiagnozować, można uruchomić adb logcat | grep BroadcastQueue i zobaczyć coś takiego:

W/BroadcastQueue: Permission Denial: receiving Intent { 
    act=android.bluetooth.device.action.FOUND flg=0x10 (has extras) } 
    to ProcessRecord{9007:com.examplepackage} (pid=9007, uid=10492) 
    requires android.permission.ACCESS_COARSE_LOCATION due to sender 
    com.android.bluetooth (uid 1002) 

więc prawidłowa procedura wykrywania urządzeń BT na Marshmallowjest następująca:

  1. Have ACCESS_COARSE_LOCATION Wymagane uprawnienie w manifeście wraz ze zwykłymi uprawnieniami Bluetooth:

    <uses-permission android:name="android.permission.BLUETOOTH" /> 
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
    
  2. Ensure you have run-time permission dla ACCESS_COARSE_LOCATION

    protected void checkLocationPermission() { 
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) 
          != PackageManager.PERMISSION_GRANTED) { 
    
         ActivityCompat.requestPermissions(this, 
           new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 
           REQUEST_COARSE_LOCATION); 
        } 
    } 
    
    @Override 
    public void onRequestPermissionsResult(int requestCode, 
                String permissions[], int[] grantResults) { 
        switch (requestCode) { 
        case REQUEST_COARSE_LOCATION: { 
         if (grantResults.length > 0 
           && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
          proceedDiscovery(); // ---> 
         } else { 
          //TODO re-request 
         } 
         break; 
        } 
    } 
    

    }

  3. zarejestrować odbiornik do transmisji ACTION_FOUND i nazywają BluetoothAdapter.startDiscovery()

    protected void proceedDiscovery() { 
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 
        filter.addAction(BluetoothDevice.ACTION_NAME_CHANGED); 
        registerReceiver(mReceiver, filter); 
    
        mBluetoothAdapter.startDiscovery(); 
    } 
    

Najśmieszniejsze o ACTION_NAME_CHANGED. Chociaż 6.0 nie dostarczy Ci ACTION_FOUND bez zgody na lokalizację z grubsza, nadal będziesz otrzymywać zdarzenia ACTION_NAME_CHANGED, które zwykle są połączone z ACTION_FOUND po wykryciu urządzenia. To znaczy. dostaniesz oba zdarzenia, więc bez pozwolenia nadal możesz obsłużyć ACTION_NAME_CHANGED dla prawie takiego samego zachowania. (Guru, popraw mnie, jeśli się mylę)

+0

Prawidłowa rzecz^^ Dzięki. Myślę, że Google robi złe rzeczy teraz na Androida: D – Mesabloo

+0

Ten anwser dostarcza tyle przydatnych informacji. Dziękujemy –

+0

Tak, niestety po 3 godzinach, było to grube pozwolenie na znalezienie urządzeń .... (chociaż nie widziałem tego w dziennikach monitorów) – ElliotM

Powiązane problemy