我正在尝试从我的应用程序管理多个蓝牙事件,因此用户无需离开应用程序&尝试从
Android设置搜索/配对蓝牙设备.
我能够枚举以前配对的设备,并开始发现,但我无法找到附近的设备.
背景资料:
设备=三星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",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",(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" />
尽管正在调用ACTION_DISCOVERY_STARTED或ACTION_DISCOVERY_FINISHED,但不会触发/调用BroadcastReciever的BluetoothDevice.ACTION_FOUND.
请帮忙???
谢谢
解决方法
你的代码似乎没问题.我猜你有BLUETOOTH权限(否则你不会收到ACTION_DISCOVERY_STARTED),但你是否也拥有ACCESS_COARSE_LOCATION权限?
You need it to receive ACTION_FOUND
:
ACTION_FOUND
Broadcast Action: Remote device discovered.
RequiresBLUETOOTH
andACCESS_COARSE_LOCATION
to receive.