2016-09-29 28 views
7

Próbuję zarządzać kilkoma zdarzeniami Bluetooth z mojej aplikacji, aby użytkownik nie musiał opuszczać aplikacji, próbując wyszukać/powiązać urządzenia Bluetooth z ustawieniami Androida.Android BluetoothDevice.ACTION_FOUND Bluetooth nie jest uruchamiany?

Jestem w stanie wyliczyć wcześniej sparowane urządzenia i rozpocząć wykrywanie, ale nie mogę znaleźć pobliskich urządzeń.

informacji Tło:

Device = Samsung Galaxy S6

OS Android 6.0.1 = Kernel 3.4.0-750027

urządzenia Bluetooth są widoczne przez Android własnego wybudowany w odkryciu

Oto mój kod:

package experiment.xyz.abc; 

import android.app.ListActivity; 
import android.bluetooth.BluetoothAdapter; 
import android.bluetooth.BluetoothDevice; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.os.Bundle; 
import android.os.Parcelable; 
import android.util.Log; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.Button; 
import android.widget.TextView; 
import android.widget.Toast; 

import java.lang.reflect.Method; 
import java.util.Iterator; 
import java.util.List; 
import java.util.Set; 

/** 
*  
* This activity is responsible for bluetooth device discovery, pairing, and selection. 
* 1) user can search for nearby devices 
* 2) pair with device 
* 3) unpair a device 
* 4) select a bt device(upon successful selection the activity navigates away). 
*/ 
public class BluetDeviceListActivity extends ListActivity 
{ 
public static String BLUETOOTH_DEVICE_ADDRESS= "BLUETOOTH_DEVICE_ADDRESS"; 

    List<BluetoothDevice> bluetList; 
    BluetoothDeviceListAdapter newBluetoothDeviceListAdapter = null; 
    private Set<BluetoothDevice> pairedDevices; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.bluet_list_view); 

     //instantiate adapter 
     newBluetoothDeviceListAdapter = new BluetoothDeviceListAdapter(this); 


     //populate bluet list 
     populatePairedBluetoothDevices(); 

     //set the ListActivity's adapter with our custom adapter 
     setListAdapter(newBluetoothDeviceListAdapter); 
     //on item click get the associated item based index & use Intent to send BluetoothDevice 
     getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       BluetoothDevice bluetoothDevice= newBluetoothDeviceListAdapter.getListOfBluetoothDevices().get(position); 

       if (bluetoothDevice!=null) { 
        Intent returnIntent = new Intent(); 
        returnIntent.putExtra(BLUETOOTH_DEVICE_ADDRESS, bluetoothDevice.getAddress()); 
        setResult(RESULT_OK, returnIntent); 
       } 

       finish(); 

       if (mReceiver!=null) 
       { 

        try { 
         unregisterReceiver(mReceiver); 
        } 
        catch (IllegalArgumentException exc) 
        { 
         exc.printStackTrace(); 
        } 
       } 
      } 
     }); 

     //cancel activity dialog 
     Button cancelButton = (Button) findViewById(R.id.cancelBluetoothDialogButton); 
     cancelButton.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 

       finish(); 

       if (mReceiver!=null) 
       { 

        try { 
         unregisterReceiver(mReceiver); 
        } 
        catch (IllegalArgumentException exc) 
        { 
         exc.printStackTrace(); 
        } 
       } 
      } 
     }); 

     //search for bluetooth devices 
     Button searchAndPairButton = (Button) findViewById(R.id.searchPairButton); 
     searchAndPairButton.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 


       //update textview 
       populateDiscoveredBluetoothDevices(); 
      } 
     }); 


     //pair or unpair selected device 
     Button pairOrUnpairButton = (Button) findViewById(R.id.pairUnpairDialogButton); 
     pairOrUnpairButton.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 

       //TODO: 

      } 
     }); 



    }//end onCreate 


    //discover nearby devices & add to list 
    private void populateDiscoveredBluetoothDevices() 
    { 
     StreamApiUtility.getBluetoothAdapter(); 


     //is bluet enabled 
     BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
     if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) { 

      //if already discovering cancel 
      if(mBluetoothAdapter.isDiscovering()){ 
       mBluetoothAdapter.cancelDiscovery(); 
      } 

      //start a new discovery 
      mBluetoothAdapter.startDiscovery(); 


      }//end there are paired devices 
      else 
      { 
       Log.i("EEGdataCapture", "No paired devices, select Search & Pair."); 
       TextView textView =(TextView) findViewById(R.id.textViewBluetoothListInstruction); 
       textView.setText("No paired devices, select Search & Pair."); 

      } 

     } 


    //query already paired & add to list 
    private void populatePairedBluetoothDevices() 
    { 
     StreamApiUtility.getBluetoothAdapter(); 

     //is bluet enabled 
     BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
     if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) { 

      //if already discovering cancel 
      if(mBluetoothAdapter.isDiscovering()){ 
       mBluetoothAdapter.cancelDiscovery(); 
      } 

      //start a new discovery 
      mBluetoothAdapter.startDiscovery(); 

      //iterate paired/bonded devices and if there are any add them to the custom adapter 
      pairedDevices = mBluetoothAdapter.getBondedDevices(); 
      if (pairedDevices.size() > 0) { 
       BluetoothDevice bluetoothDevice; 
       Iterator<BluetoothDevice> it = pairedDevices.iterator(); 
       while (it.hasNext()) { 
        bluetoothDevice = (BluetoothDevice) it.next(); 
        //add to adapter 
        newBluetoothDeviceListAdapter.addDevice(bluetoothDevice); 
        newBluetoothDeviceListAdapter.notifyDataSetChanged(); 
        Log.i("EEGdataCapture", "paired device, name: " + bluetoothDevice.getName() + ", address: " + bluetoothDevice.getAddress()); 
       } 


      }//end there are paired devices 
      else 
      { 
       Log.i("EEGdataCapture", "No paired devices, select Search & Pair."); 
       TextView textView =(TextView) findViewById(R.id.textViewBluetoothListInstruction); 
       textView.setText("No paired devices, select Search & Pair."); 

      } 

     } 
    } 



    private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 
     public void onReceive(Context context, Intent intent) { 
      String action = intent.getAction(); 
      BluetoothDevice device; 

      if (BluetoothDevice.ACTION_FOUND.equals(action)) { 

       device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 


       Log.i("EEGdataCapture", "BluetoothDevice.ACTION_FOUND"); 

       Log.i("EEGdataCapture", device.getName() + "\n" + device.getAddress()); 

       //update list 

       newBluetoothDeviceListAdapter.addDevice(device); 
       newBluetoothDeviceListAdapter.notifyDataSetChanged(); 


      } 
      else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) { 

       Log.i("EEGdataCapture", "BluetoothDevice.ACTION_BOND_STATE_CHANGED"); 

       final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR); 
       final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR); 

       if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) { 

        Toast.makeText(MyApp.getAppContext(), "Paired", Toast.LENGTH_SHORT).show(); 
       } else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED) { 
        Toast.makeText(MyApp.getAppContext(), "Unpaired", Toast.LENGTH_SHORT).show(); 
       } 


      } 
      else if (BluetoothDevice.ACTION_UUID.equals(action)) { 

       Log.i("EEGdataCapture", "BluetoothDevice.ACTION_UUID"); 



      } 

      else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) { 

       Log.i("EEGdataCapture", "BluetoothAdapter.ACTION_DISCOVERY_STARTED, Discovery Started..."); 


      } 

      else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { 
       Log.i("EEGdataCapture", "BluetoothAdapter.ACTION_DISCOVERY_FINISHED, Discovery finished."); 


     } 
      else 
      { 
       Log.i("EEGdataCapture", "BluetoothAdapter, ACTIOM is not supported, action ="+action); 
      } 


     }}; 



    private void pairDevice(BluetoothDevice device) { 
     try { 
      Method method = device.getClass().getMethod("createBond", (Class[]) null); 
      method.invoke(device, (Object[]) null); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    private void unpairDevice(BluetoothDevice device) { 
     try { 
      Method method = device.getClass().getMethod("removeBond", (Class[]) null); 
      method.invoke(device, (Object[]) null); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 



    @Override 
    protected void onPause() { 
     super.onPause(); 

     if (StreamApiUtility.getBluetoothAdapter()!=null) { 
      StreamApiUtility.getBluetoothAdapter().cancelDiscovery(); 
     } 
     if (mReceiver!=null) 
     { 

      try { 
       unregisterReceiver(mReceiver); 
      } 
      catch (IllegalArgumentException exc) 
      { 
       exc.printStackTrace(); 
      } 
     } 
    } 

    @Override 
    protected void onResume() 
    { 
     super.onResume(); 
     //filter to capture bluet events 
     IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 
     filter.addAction(BluetoothDevice.ACTION_UUID); 
     filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); 
     filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); 

     //register listener for bluet events before starting discovery again 
     registerReceiver(mReceiver, filter); 

    } 


    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 

     if (mReceiver!=null) 
     { 

      try { 
       unregisterReceiver(mReceiver); 
      } 
      catch (IllegalArgumentException exc) 
      { 
       exc.printStackTrace(); 
      } 
     } 
    } 
} 

aktualizowane Oczywisty:

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

na BroadcastReciever za BluetoothDevice.ACTION_FOUND nie jest wyzwalane/nazywa chociaż ACTION_DISCOVERY_STARTED LUB ACTION_DISCOVERY_FINISHED są nazywane.

Proszę o pomoc ???

Dzięki

+0

Czy masz szansę przetestować swoją aplikację pod Androidem 6.0? –

Odpowiedz

8

Twój kod wydaje się być w porządku. Domyślam się, że masz uprawnienie BLUETOOTH (w przeciwnym razie nie otrzymasz ACTION_DISCOVERY_STARTED), ale czy masz również uprawnienie ACCESS_COARSE_LOCATION?

You need it to receive ACTION_FOUND:

ACTION_FOUND
Broadcast Działanie: Urządzenie zdalnego odkryte.
Wymaga BLUETOOTH i ACCESS_COARSE_LOCATION do odbioru.

+0

Próbowałem tego podejścia, dodając ACCESS_COARSE_LOCATION w manifeście, jednak urządzenia nadal nie zostały odkryte ??? Dodałem moje uprawnienia do oryginalnego wpisu. – cyber101

+2

Od Androida 6 (API 23), musisz również zapytać użytkownika, "ACCESS_COARSE_LOCATION" jest niebezpiecznym zezwoleniem. Z drugiej strony 'BLUETOOTH' jest normalnym uprawnieniem i jest przyznawana automatycznie. – bwt

+0

Co się stanie, jeśli ustawisz poziom docelowy na 22? – bwt

Powiązane problemy