Android +以编程方式通过蓝牙配对设备

我想发现范围内的bluetooth设备,列表和点击它们对。 我使用下面的代码,但它只是closures应用程序,当我点击设备名称,我想配对。

我想知道我的代码中的错误或任何其他方式来做我所需要的。

 package com.marakana; import java.util.Set; import android.app.Activity; 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.util.Log; import android.view.View; import android.view.Window; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; public class BluetoothDemo extends Activity { // Debugging private static final String TAG = "DeviceListActivity"; private static final boolean D = true; // Return Intent extra public static String EXTRA_DEVICE_ADDRESS = "device_address"; // Member fields private BluetoothAdapter mBtAdapter; private ArrayAdapter<String> mPairedDevicesArrayAdapter; private ArrayAdapter<String> mNewDevicesArrayAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Setup the window requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.device_list); // Set result CANCELED incase the user backs out setResult(Activity.RESULT_CANCELED); // Initialize the button to perform device discovery Button scanButton = (Button) findViewById(R.id.button_scan); scanButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { doDiscovery(); v.setVisibility(View.GONE); } }); // Initialize array adapters. One for already paired devices and // one for newly discovered devices mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); // Find and set up the ListView for paired devices ListView pairedListView = (ListView) findViewById(R.id.paired_devices); pairedListView.setAdapter(mPairedDevicesArrayAdapter); pairedListView.setOnItemClickListener(mDeviceClickListener); // Find and set up the ListView for newly discovered devices ListView newDevicesListView = (ListView) findViewById(R.id.new_devices); newDevicesListView.setAdapter(mNewDevicesArrayAdapter); newDevicesListView.setOnItemClickListener(mDeviceClickListener); // Register for broadcasts when a device is discovered IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); this.registerReceiver(mReceiver, filter); // Register for broadcasts when discovery has finished filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); this.registerReceiver(mReceiver, filter); // Get the local Bluetooth adapter mBtAdapter = BluetoothAdapter.getDefaultAdapter(); // Get a set of currently paired devices Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices(); // If there are paired devices, add each one to the ArrayAdapter if (pairedDevices.size() > 0) { findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE); for (BluetoothDevice device : pairedDevices) { mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } } else { String noDevices = getResources().getText(R.string.none_paired).toString(); mPairedDevicesArrayAdapter.add(noDevices); } } @Override protected void onDestroy() { super.onDestroy(); // Make sure we're not doing discovery anymore if (mBtAdapter != null) { mBtAdapter.cancelDiscovery(); } // Unregister broadcast listeners this.unregisterReceiver(mReceiver); } /** * Start device discover with the BluetoothAdapter */ private void doDiscovery() { if (D) Log.d(TAG, "doDiscovery()"); // Indicate scanning in the title setProgressBarIndeterminateVisibility(true); setTitle(R.string.scanning); // Turn on sub-title for new devices findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE); // If we're already discovering, stop it if (mBtAdapter.isDiscovering()) { mBtAdapter.cancelDiscovery(); } // Request discover from BluetoothAdapter mBtAdapter.startDiscovery(); } // The on-click listener for all devices in the ListViews private OnItemClickListener mDeviceClickListener = new OnItemClickListener() { public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) { // Cancel discovery because it's costly and we're about to connect mBtAdapter.cancelDiscovery(); // Get the device MAC address, which is the last 17 chars in the View String info = ((TextView) v).getText().toString(); String address = info.substring(info.length() - 17); // Create the result Intent and include the MAC address Intent intent = new Intent(); intent.putExtra(EXTRA_DEVICE_ADDRESS, address); // Set result and finish this Activity setResult(Activity.RESULT_OK, intent); finish(); } }; // The BroadcastReceiver that listens for discovered devices and // changes the title when discovery is finished private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { 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); // If it's already paired, skip it, because it's been listed already if (device.getBondState() != BluetoothDevice.BOND_BONDED) { mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } // When discovery is finished, change the Activity title } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { setProgressBarIndeterminateVisibility(false); setTitle(R.string.select_device); if (mNewDevicesArrayAdapter.getCount() == 0) { String noDevices = getResources().getText(R.string.none_found).toString(); mNewDevicesArrayAdapter.add(noDevices); } } } }; } 

在我的第一个答案中,逻辑显示了那些想要只用逻辑的人。

我想我无法向@ chalukya3545说清楚,这就是为什么我要添加整个代码让他知道代码的确切stream程。

BluetoothDemo.java

 public class BluetoothDemo extends Activity { ListView listViewPaired; ListView listViewDetected; ArrayList<String> arrayListpaired; Button buttonSearch,buttonOn,buttonDesc,buttonOff; ArrayAdapter<String> adapter,detectedAdapter; static HandleSeacrh handleSeacrh; BluetoothDevice bdDevice; BluetoothClass bdClass; ArrayList<BluetoothDevice> arrayListPairedBluetoothDevices; private ButtonClicked clicked; ListItemClickedonPaired listItemClickedonPaired; BluetoothAdapter bluetoothAdapter = null; ArrayList<BluetoothDevice> arrayListBluetoothDevices = null; ListItemClicked listItemClicked; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); listViewDetected = (ListView) findViewById(R.id.listViewDetected); listViewPaired = (ListView) findViewById(R.id.listViewPaired); buttonSearch = (Button) findViewById(R.id.buttonSearch); buttonOn = (Button) findViewById(R.id.buttonOn); buttonDesc = (Button) findViewById(R.id.buttonDesc); buttonOff = (Button) findViewById(R.id.buttonOff); arrayListpaired = new ArrayList<String>(); bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); clicked = new ButtonClicked(); handleSeacrh = new HandleSeacrh(); arrayListPairedBluetoothDevices = new ArrayList<BluetoothDevice>(); /* * the above declaration is just for getting the paired bluetooth devices; * this helps in the removing the bond between paired devices. */ listItemClickedonPaired = new ListItemClickedonPaired(); arrayListBluetoothDevices = new ArrayList<BluetoothDevice>(); adapter= new ArrayAdapter<String>(BluetoothDemo.this, android.R.layout.simple_list_item_1, arrayListpaired); detectedAdapter = new ArrayAdapter<String>(BluetoothDemo.this, android.R.layout.simple_list_item_single_choice); listViewDetected.setAdapter(detectedAdapter); listItemClicked = new ListItemClicked(); detectedAdapter.notifyDataSetChanged(); listViewPaired.setAdapter(adapter); } @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); getPairedDevices(); buttonOn.setOnClickListener(clicked); buttonSearch.setOnClickListener(clicked); buttonDesc.setOnClickListener(clicked); buttonOff.setOnClickListener(clicked); listViewDetected.setOnItemClickListener(listItemClicked); listViewPaired.setOnItemClickListener(listItemClickedonPaired); } private void getPairedDevices() { Set<BluetoothDevice> pairedDevice = bluetoothAdapter.getBondedDevices(); if(pairedDevice.size()>0) { for(BluetoothDevice device : pairedDevice) { arrayListpaired.add(device.getName()+"\n"+device.getAddress()); arrayListPairedBluetoothDevices.add(device); } } adapter.notifyDataSetChanged(); } class ListItemClicked implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub bdDevice = arrayListBluetoothDevices.get(position); //bdClass = arrayListBluetoothDevices.get(position); Log.i("Log", "The dvice : "+bdDevice.toString()); /* * here below we can do pairing without calling the callthread(), we can directly call the * connect(). but for the safer side we must usethe threading object. */ //callThread(); //connect(bdDevice); Boolean isBonded = false; try { isBonded = createBond(bdDevice); if(isBonded) { //arrayListpaired.add(bdDevice.getName()+"\n"+bdDevice.getAddress()); //adapter.notifyDataSetChanged(); getPairedDevices(); adapter.notifyDataSetChanged(); } } catch (Exception e) { e.printStackTrace(); }//connect(bdDevice); Log.i("Log", "The bond is created: "+isBonded); } } class ListItemClickedonPaired implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position,long id) { bdDevice = arrayListPairedBluetoothDevices.get(position); try { Boolean removeBonding = removeBond(bdDevice); if(removeBonding) { arrayListpaired.remove(position); adapter.notifyDataSetChanged(); } Log.i("Log", "Removed"+removeBonding); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /*private void callThread() { new Thread(){ public void run() { Boolean isBonded = false; try { isBonded = createBond(bdDevice); if(isBonded) { arrayListpaired.add(bdDevice.getName()+"\n"+bdDevice.getAddress()); adapter.notifyDataSetChanged(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }//connect(bdDevice); Log.i("Log", "The bond is created: "+isBonded); } }.start(); }*/ private Boolean connect(BluetoothDevice bdDevice) { Boolean bool = false; try { Log.i("Log", "service method is called "); Class cl = Class.forName("android.bluetooth.BluetoothDevice"); Class[] par = {}; Method method = cl.getMethod("createBond", par); Object[] args = {}; bool = (Boolean) method.invoke(bdDevice);//, args);// this invoke creates the detected devices paired. //Log.i("Log", "This is: "+bool.booleanValue()); //Log.i("Log", "devicesss: "+bdDevice.getName()); } catch (Exception e) { Log.i("Log", "Inside catch of serviceFromDevice Method"); e.printStackTrace(); } return bool.booleanValue(); }; public boolean removeBond(BluetoothDevice btDevice) throws Exception { Class btClass = Class.forName("android.bluetooth.BluetoothDevice"); Method removeBondMethod = btClass.getMethod("removeBond"); Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice); return returnValue.booleanValue(); } public boolean createBond(BluetoothDevice btDevice) throws Exception { Class class1 = Class.forName("android.bluetooth.BluetoothDevice"); Method createBondMethod = class1.getMethod("createBond"); Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice); return returnValue.booleanValue(); } class ButtonClicked implements OnClickListener { @Override public void onClick(View view) { switch (view.getId()) { case R.id.buttonOn: onBluetooth(); break; case R.id.buttonSearch: arrayListBluetoothDevices.clear(); startSearching(); break; case R.id.buttonDesc: makeDiscoverable(); break; case R.id.buttonOff: offBluetooth(); break; default: break; } } } private BroadcastReceiver myReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Message msg = Message.obtain(); String action = intent.getAction(); if(BluetoothDevice.ACTION_FOUND.equals(action)){ Toast.makeText(context, "ACTION_FOUND", Toast.LENGTH_SHORT).show(); BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); try { //device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true); //device.getClass().getMethod("cancelPairingUserInput", boolean.class).invoke(device); } catch (Exception e) { Log.i("Log", "Inside the exception: "); e.printStackTrace(); } if(arrayListBluetoothDevices.size()<1) // this checks if the size of bluetooth device is 0,then add the { // device to the arraylist. detectedAdapter.add(device.getName()+"\n"+device.getAddress()); arrayListBluetoothDevices.add(device); detectedAdapter.notifyDataSetChanged(); } else { boolean flag = true; // flag to indicate that particular device is already in the arlist or not for(int i = 0; i<arrayListBluetoothDevices.size();i++) { if(device.getAddress().equals(arrayListBluetoothDevices.get(i).getAddress())) { flag = false; } } if(flag == true) { detectedAdapter.add(device.getName()+"\n"+device.getAddress()); arrayListBluetoothDevices.add(device); detectedAdapter.notifyDataSetChanged(); } } } } }; private void startSearching() { Log.i("Log", "in the start searching method"); IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND); BluetoothDemo.this.registerReceiver(myReceiver, intentFilter); bluetoothAdapter.startDiscovery(); } private void onBluetooth() { if(!bluetoothAdapter.isEnabled()) { bluetoothAdapter.enable(); Log.i("Log", "Bluetooth is Enabled"); } } private void offBluetooth() { if(bluetoothAdapter.isEnabled()) { bluetoothAdapter.disable(); } } private void makeDiscoverable() { Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent); Log.i("Log", "Discoverable "); } class HandleSeacrh extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case 111: break; default: break; } } } } 

这是main.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/buttonOn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="On"/> <Button android:id="@+id/buttonDesc" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Make Discoverable"/> <Button android:id="@+id/buttonSearch" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Search"/> <Button android:id="@+id/buttonOff" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Bluetooth Off"/> <ListView android:id="@+id/listViewPaired" android:layout_width="match_parent" android:layout_height="120dp"> </ListView> <ListView android:id="@+id/listViewDetected" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> </LinearLayout> 

将此权限添加到您的AndroidManifest.xml文件中:

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

此代码的输出将如下所示。 Bluutooth演示

最好的方法是不要使用任何配对代码 。 而不是onClick转到其他function或其他您使用UUID创build套接字的类。
如果已经没有配对,Android会自动popup配对。

或者看看这个链接,以更好的理解

以下是相同的代码:

 private OnItemClickListener mDeviceClickListener = new OnItemClickListener() { public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) { // Cancel discovery because it's costly and we're about to connect mBtAdapter.cancelDiscovery(); // Get the device MAC address, which is the last 17 chars in the View String info = ((TextView) v).getText().toString(); String address = info.substring(info.length() - 17); // Create the result Intent and include the MAC address Intent intent = new Intent(); intent.putExtra(EXTRA_DEVICE_ADDRESS, address); // Set result and finish this Activity setResult(Activity.RESULT_OK, intent); // **add this 2 line code** Intent myIntent = new Intent(view.getContext(), Connect.class); startActivityForResult(myIntent, 0); finish(); } }; 

Connect.java文件是:

 public class Connect extends Activity { private static final String TAG = "zeoconnect"; private ByteBuffer localByteBuffer; private InputStream in; byte[] arrayOfByte = new byte[4096]; int bytes; public BluetoothDevice mDevice; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.connect); try { setup(); } catch (ZeoMessageException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ZeoMessageParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void setup() throws ZeoMessageException, ZeoMessageParseException { // TODO Auto-generated method stub getApplicationContext().registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED)); getApplicationContext().registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED)); BluetoothDevice zee = BluetoothAdapter.getDefaultAdapter(). getRemoteDevice("**:**:**:**:**:**");// add device mac adress try { sock = zee.createRfcommSocketToServiceRecord( UUID.fromString("*******************")); // use unique UUID } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } Log.d(TAG, "++++ Connecting"); try { sock.connect(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } Log.d(TAG, "++++ Connected"); try { in = sock.getInputStream(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } Log.d(TAG, "++++ Listening..."); while (true) { try { bytes = in.read(arrayOfByte); Log.d(TAG, "++++ Read "+ bytes +" bytes"); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } Log.d(TAG, "++++ Done: test()"); }} private static final LogBroadcastReceiver receiver = new LogBroadcastReceiver(); public static class LogBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context paramAnonymousContext, Intent paramAnonymousIntent) { Log.d("ZeoReceiver", paramAnonymousIntent.toString()); Bundle extras = paramAnonymousIntent.getExtras(); for (String k : extras.keySet()) { Log.d("ZeoReceiver", " Extra: "+ extras.get(k).toString()); } } }; private BluetoothSocket sock; @Override public void onDestroy() { getApplicationContext().unregisterReceiver(receiver); if (sock != null) { try { sock.close(); } catch (IOException e) { e.printStackTrace(); } } super.onDestroy(); } } 

编辑:我刚刚解释了在这里配对的逻辑。 如果有人想用完整的代码去看看我的另一个答案。 我已经在这里回答了逻辑,但我无法正确解释,所以我在同一个线程中添加了另一个答案。

试试这个做配对:

如果你能够search设备,那么这将是你的下一个步骤

 ArrayList<BluetoothDevice> arrayListBluetoothDevices = NEW ArrayList<BluetoothDevice>; 

我假设你已经在arrayListBluetoothDevices添加了蓝牙设备列表:

 BluetoothDevice bdDevice; bdDevice = arrayListBluetoothDevices.get(PASS_THE_POSITION_TO_GET_THE_BLUETOOTH_DEVICE); Boolean isBonded = false; try { isBonded = createBond(bdDevice); if(isBonded) { Log.i("Log","Paired"); } } catch (Exception e) { e.printStackTrace(); } 

createBond()方法:

 public boolean createBond(BluetoothDevice btDevice) throws Exception { Class class1 = Class.forName("android.bluetooth.BluetoothDevice"); Method createBondMethod = class1.getMethod("createBond"); Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice); return returnValue.booleanValue(); } 

将此行添加到ACTION_FOUND中的Receiver中

 if (device.getBondState() != BluetoothDevice.BOND_BONDED) { mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); arrayListBluetoothDevices.add(device); } 

我们为什么需要思考? 有一个API可以做到这一点:

https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createBond();