蓝牙应该是如今每一部智能手机的标配了。想当年在山寨机横行的年代里,蓝牙均可以作为一个卖点~~~android
废话很少说了,进入正题:编程
使用蓝牙功能是须要权限的,关于蓝牙的权限也就两个:异步
<uses-permission android:name=”android.permission.BLUETOOTH” /> <uses-permission android:name=”android.permission.BLUETOOTH_ADMIN” />
第一个是最基本的,打开蓝牙,请求链接,接受链接都须要这个。ide
每二个从字面上看都以为高级一点,它主要用于像创建搜索、对蓝牙进行设置这些操做。spa
添加好权限以后就能够开始使用了code
Android系统为咱们提供了一个功能极其强大的类用于进行蓝牙操做,这个类就是BluetoothAdapter。经过这个类的方法能够知足咱们的大多数操做了。对象
要得到这个类的对象咱们能够直接调用它的一个静态方法getDefaultAdapter()。顺便看看它的源码是怎样的吧:blog
public static synchronized BluetoothAdapter getDefaultAdapter() { if (sAdapter == null) { IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE); if (b != null) { IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b); sAdapter = new BluetoothAdapter(managerService); } else { Log.e(TAG, "Bluetooth binder is null"); } } return sAdapter; }
典型的单例模式:进程
打开蓝牙资源
首先要先确实您的设备是否有蓝牙,这个验证仍是颇有必要的,由于咱们要考虑到咱们的应用不必定就是给手机用的,也多是平板之类的。
private boolean isBluetoothAvaliable() { return BluetoothAdapter.getDefaultAdapter() != null; }
咱们通常打开蓝牙会使用到系统提供的一个Activity。这个Activity的action为:BluetoothAdapter.ACTION_REQUEST_ENABLE。
而后咱们要使用startActivityForResult()这个方法来启动它。
这个Activity是有返回值的,若是用户选择的是打开,咱们应该能够收到一个RESULT_OK
若是用户选择的是取消,咱们应该能够收到一个RESULT_CANCELED。
好比像下面的这一段代码:
public void openBluetooth() { Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBT, 1); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 1) { if (resultCode == RESULT_OK) { System.out.println("蓝牙已打开"); } else if (resultCode == RESULT_CANCELED) { System.out.println("取消打开"); } } }
监听蓝牙状态的变化
当蓝牙的状态发生改变时,系统是会发出一个为BluetoothAdapter.ACTION_STATE_CHANGED的广播。
该广播携带两个参数,一个是BluetoothAdapter.EXTRA_PREVIOUS_STATE,表示以前的蓝牙状态。
另外一个是BluetoothAdapter.EXTRA_STATE,表示当前的蓝牙状态。而它们的值为如下四个:
BluetoothAdapter.STATE_TURNING_ON;
BluetoothAdapter.STATE_ON;
BluetoothAdapter.STATE_TURNING_OFF;
BluetoothAdapter.STATE_OFF;
分别表明,打开中,已打开,关闭中,已关闭。
private class BluetoothStateListener extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); String msg = null; switch (state) { case BluetoothAdapter.STATE_TURNING_ON: msg = "turning on"; break; case BluetoothAdapter.STATE_ON: msg = "on"; break; case BluetoothAdapter.STATE_TURNING_OFF: msg = "turning off"; break; case BluetoothAdapter.STATE_OFF: msg = "off"; break; } System.out.println(msg); } } protected void onResume() { super.onResume(); // 蓝牙开闭状态接收器 listener = new BluetoothStateListener(); IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); registerReceiver(listener, filter); }
固然在程序中的某刻,咱们能够调用BludetoothAdapter的getState()这个方法,该方法的返回值为上面的四个中的一个,再也不赘述。
查找蓝牙设备
这个关于查找设备要分为两个部分,一个是已绑定的设备,另外一个是搜索新的设备。
对于已绑定的设备,咱们能够直接经过BluetoothAdapter的getBondedDevices()这个方法来得到。
该方法返回的是一个Set<BluetoothDevice>咱们能够直接从人得到咱们须要的信息:
public void getBoundedDevices() { System.out.println("getPairedDevices"); // 这个要在打开蓝牙的状况下才能够,否则为空集 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); Set<BluetoothDevice> devices = adapter.getBondedDevices(); for (BluetoothDevice device : devices) { System.out.println(device.getName() + " : " + device.getAddress()); } }
另外就是查找新的设备了,这时咱们要调用startDiscovery()方法,这个方法并不会在咱们的程序中执行,它是系统进程来的,而后经过异步发送广播的方式来通知。
因此咱们还要注册一个广播接收器来接收系统的广播,这个广播的action为BluetoothDevice.ACTION_FOUND。
它携带两个值,一个是BluetoothDevice.EXTRA_DEVICE另外一个是BluetoothDevice.EXTRA_CLASS分别表示哪个具体的设备和这个设备的类型。
private class BluetoothDeviceScanListener extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // 这里能够把咱们的将咱们的设备添加到一个列表中 System.out.println(device.getName() + " : " + device.getAddress()); } }
在官方的文档中一直强调,查找设备这个动做是会消耗大量的系统资源的,并且它会大大减小蓝牙的可用带宽,因此当咱们找到了目标设备后,应该由咱们主动调用cancelDiscovery()这个方法来取消搜索,而不该该期待默认的搜索时间到了,由系统来取消搜索。
设置可被搜索
蓝牙的默认设置是不容许被搜索到的,这一点有时候挺蛋疼的。
因此咱们本身经过编程来实现打开可被搜索的选择,使用是很装简单的,也是调用系统的一个Activity。这个activity的action是BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE它一样是有返回值的。而且,这个咱们能够经过BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION这个参数来指定可被搜索的时间。
public void discoverable() { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); // 这个能够用来设置时间 intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200); startActivityForResult(intent, 2); }
这个Activity还同时具备打开蓝牙的功能,因此咱们并不须要先打开蓝牙,再设置可被发现的时间,一次就能够搞定。
最后,这个状态的改变系统也是会发出广播的,咱们能够注册一个广播接收器来捕捉这个状态的变化,或是经过调用BluetoothAdapter的getScanMod()这个方法来肯定,和以前是同样的。再也不细说了。
(未定待续)