2016-09-29 175 views
7

我試圖從我的應用程序管理幾個藍牙事件,因此用戶不需要離開應用程序&嘗試從Android設置搜索/配對藍牙設備。Android的藍牙BluetoothDevice.ACTION_FOUND沒有被觸發?

我能枚舉以前配對的設備,並開始發現,但我找不到附近的設備。

背景信息:

設備=三星Galaxy S6

OS =的Android 6.0.1,內核3.4.0-750027

藍牙設備通過Android的自身內置的發現

可見

這裏是我的相關代碼:

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(); 
      } 
     } 
    } 
} 

更新的清單:

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

的BroadcastReciever的BluetoothDevice.ACTION_FOUND不被觸發/被叫雖然ACTION_DISCOVERY_STARTED OR ACTION_DISCOVERY_FINISHED被調用。

請幫忙嗎?

謝謝

+0

您是否有機會在Android 6.0以下測試您的應用程序? –

回答

8

您的代碼似乎沒問題。我想你有BLUETOOTH權限(否則你不會收到ACTION_DISCOVERY_STARTED),但你也有ACCESS_COARSE_LOCATION權限?

You need it to receive ACTION_FOUND

ACTION_FOUND
廣播事件:遠程設備發現。
需要BLUETOOTHACCESS_COARSE_LOCATION才能收到。

+0

我試圖通過在清單中添加ACCESS_COARSE_LOCATION這種方法,但是,設備仍然沒有被發現?我將我的權限添加到原始帖子。 – cyber101

+2

由於Android 6(API 23),您還需要詢問用戶,「ACCESS_COARSE_LOCATION」是一個危險的權限。另一方面'BLUETOOTH'是一個正常的許可,並被自動授予。 – bwt

+0

如果將目標級別設置爲22,會發生什麼情況? – bwt