Android蓝牙(二)
来源:互联网 发布:德云社 知乎 编辑:程序博客网 时间:2024/06/06 19:52
Android蓝牙开发(二)
有问题可以加群讨论:517018699
蓝牙官方文档
中文api
Android 可以通过Android BlueTooth访问蓝牙功能的途径,这些API允许应用以无线的形式连接到其他蓝牙,从而实现点到点和多点无线功能。
使用BlueTooth API,Android应用可以执行以下操作
* 扫描其他蓝牙设备
* 查询本地蓝牙适配器的配对蓝牙设备
* 建立RFCOMM通道
* 通过服务发现连接到其他设备
* 与其他设备进行双向数据传输
* 管理多个连接
Android蓝牙采用的是SDP协议进行通信,通信方式类似于平常使用的socket
权限
<!--需要硬件支持低功耗蓝牙--><uses-feature android:name"android.permission.BLUETOOTH_ADMIN"/><!--蓝牙权限--><uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/><uses-permission android:name="android.permission.BLUETOOTH"/><!--Android 5.0以上蓝牙好需要位置权限--><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/><uses-permission android:name="andriod.permission.ACCESS_FINE_LOCATION"/>
是的,你会发现使用蓝牙还需要位置权限?我开始也觉得一个蓝牙也要位置权限,后来在翻看官方文档的时候才知道的,不然你在5.0以上的手机上扫不出蓝牙的!详情请翻阅官方文档:
API提供的方法
在Android API里面提供了Bluetooth相关的类21个和一个接口
1.BluetoothAdapter 2.BluetoothAssignedNumbers 3.BluetoothA2dp 4.BluetoothClass 5.BluetoothDevice 6.BluetoothGatt 7.BluetoothGattCallback 8.BluetoothGattCharacteristic 9.BluetoothGattDescriptor 10.BluetoothGattServer 11.BluetoothGattService 12.BluetoothGattServerCallback 13.BluetoothHeadset 14.BluetoothLeAdvertiser 15.BluetoothLeScanner 16.BluetoothManager 17.BluetoothHealth 18.BluetoothHealthAppConfiguration 19.BluetoothHealthCallback 20.BluetoothServerSocket 21.BluetoothSocket 22.BluetoothProfile ----接口
日常开发中我们使用到的
BluetoothAdapter——蓝牙适配器
* 用于:建立蓝牙连接(bluetoothSocket)之前使用
* 提供方法:
* cancelDiscovery();——取消发现蓝牙设备
* disable()——关闭蓝牙
* enable()——打开蓝牙
* isEnabled()——判断本地蓝牙是否打开——true打开
* getAddress()——获取本地蓝牙地址
* getDefaultAdapter()——获取默认BluetoothAdapter,实际上,也只有这一种方法获取BluetoothAdapter
* getName()——获取本地蓝牙名称
* getRemoteDevice(String address)——根据蓝牙地址获取远程蓝牙设备
* getState()获取本地蓝牙是适配器当前状态
* isDiscovering()判断当前是否在查找设备——是返回true
* startDiscovery()——开始搜索
* listenUsingRfcommWithServiceRecord(String name,UUID uuid)根据名称,UUID创建并返回BluetoothServerSocket,这是创建BluetoothSocket服务器端的第一步
BluetoothDevice——蓝牙设备
- 提供方法:
- createRfcommSocketToServiceRecord(UUIDuuid)根据UUID创建并返回一个BluetoothSocket
- getState()蓝牙状态:只有在BluetoothAdapter.STATE_ON 状态下才可以监听
- getName()——获取本地蓝牙名称
- getAddress()——获取本地蓝牙地址
BluetoothServerSocket——服务端蓝牙通信
* 提供方法:
* 两个重载accept(),accept(inttimeout)两者的区别在于后面的方法指定了过时时间,需要注意的是,执行这两个方法的时候,直到接收到了客户端的请求(或是过期之后),都会阻塞线程,应该放在新线程里运行!两个方法都返回一个BluetoothSocket,最后的连接也是服务器端与客户端的两个BluetoothSocket的连接
* close()——关闭!
BluetoothSocket——客户端蓝牙通信
* 提供方法:
* connect()——连接
* getInptuStream()——获取输入流
* getOutputStream()——获取输入流
* getRemoteDevice()——获取远程设备——这里指的是获取bluetoothSocket指定连接的那个远程蓝牙设备
* close()——关闭
获取蓝牙适配器
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if(mBluetoothAdapter==null){//改设备不支持蓝牙}
开启蓝牙
if(!mBluetoothAdapter.isEnabled()){ //弹出对话框提示用户是后打开 startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), 1);private static final int REQUEST_BLUETOOTH_PERMISSION=10;private void requestBluetoothPermission(){ //判断系统版本 if (Build.VERSION.SDK_INT >= 23) { //检测当前app是否拥有某个权限 int checkCallPhonePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION); //判断这个权限是否已经授权过 if(checkCallPhonePermission != PackageManager.PERMISSION_GRANTED){ //判断是否需要 向用户解释,为什么要申请该权限 if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION)) ActivityCompat.requestPermissions(this ,new String[] {Manifest.permission.ACCESS_COARSE_LOCATION},REQUEST_BLUETOOTH_PERMISSION); return; }else{ } } else { }}//接下来我们就可以静默开启蓝牙了:BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();mBluetoothAdapter.enable(); //开启//mBluetoothAdapter.disable(); //关闭}
获取本地蓝牙信息
//获取本机蓝牙名称 String name = mBluetoothAdapter.getName(); //获取本机蓝牙地址 String address = mBluetoothAdapter.getAddress(); Log.d(TAG,"bluetooth name ="+name+" address ="+address); //获取已配对蓝牙设备 Set<BluetoothDevice> devices = mBluetoothAdapter.getBondedDevices(); Log.d(TAG, "bonded device size ="+devices.size()); for(BluetoothDevice bonddevice:devices){ Log.d(TAG, "bonded device name ="+bonddevice.getName()+" address"+bonddevice.getAddress()); }
搜索设备——停止搜索
mBluetoothAdapter.startDiscovery(); //——————搜索mBluetoothAdapter.cancelDiscovery(); //——————停止搜索 public boolean isDiscovering ();//返回true——正处于扫描设备中
设置蓝牙可见性
/**有时候扫描不到某设备,这是因为该设备对外不可见或者距离远,需要设备该蓝牙可见,这样该才能被搜索到。*可见时间默认值为120s,最多可设置300。*/if (mBluetoothAdapter.isEnabled()) { if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { Intent discoverableIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra( BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120); startActivity(discoverableIntent); } }
监听扫描结果
/***通过广播接收者查看扫描到的蓝牙设备,每扫描到一个设备,系统都会发送此广播(BluetoothDevice.ACTION_FOUNDE)。*其中参数intent可以获取蓝牙设备BluetoothDevice。*/private BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.d(TAG,"mBluetoothReceiver action ="+action); if(BluetoothDevice.ACTION_FOUND.equals(action)){//每扫描到一个设备,系统都会发送此广播。 //获取蓝牙设备 BluetoothDevice scanDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if(scanDevice == null || scanDevice.getName() == null) return; Log.d(TAG, "name="+scanDevice.getName()+"address="+scanDevice.getAddress()); //蓝牙设备名称 String name = scanDevice.getName(); if(name != null && name.equals(VnApplication.BLUETOOTH_NAME)){ mBluetoothAdapter.cancelDiscovery(); //取消扫描 mProgressDialog.setTitle(getResources().getString (R.string.progress_connecting)); //连接到设备。 mBlthChatUtil.connect(scanDevice); } }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){ } } };
连接设备
public BluetoothGatt connectGatt(Content content,boolean autoConnect,BluetoothGattCallback callback){ return(connectGatt(context,autoConnect,callback,TRANSPORT_AUTO)); } /** *第一个 Context 就不说了;第二个参数 autoConnect 的解释是“是否直接连接到远程设备(false)或一旦远程设备可用即可自动连接(true)”; *第三个参数也是上面提到的抽象类,这个类在连接过程中起到关键作用。最后方法会返回一个 BluetoothGatt 对象,后续我们通过这个对 *象可以重连、断开、关闭设备。贴下我例子中的连接方法: */ /** *连接设备,如果服务未开启或者地址为空的情况就返回false; *如果地址存在是否连接成功取决于蓝牙底层 *@param address *@return 是否连接到 */ @Override public boole connectDevice(String address){ if(address.equals(mAddress)&&mBluetoothGatt !=null){ return mBluetoothGatt.connect(); } BluetoothDevice device=arshowBluetooth.getBluetoothAdaoter(). getRemoteDevice(address); if(device ==null){ return fasle; } //false表示直接连接,ture表示远程设备可用之后连接 mBluetoothGatt=device.connectGatt(context,false,mGattCallback); mAddress=address; return true; }
Android蓝牙自动配对
- Android蓝牙(二)
- android -- 蓝牙 bluetooth (二) 打开蓝牙
- android -- 蓝牙 bluetooth (二) 打开蓝牙 .
- android -- 蓝牙 bluetooth (二) 打开蓝牙
- android -- 蓝牙 bluetooth (二) 打开蓝牙
- android -- 蓝牙 bluetooth (二) 打开蓝牙
- android -- 蓝牙 bluetooth (二) 打开蓝牙
- android -- 蓝牙 bluetooth (二) 打开蓝牙
- android -- 蓝牙 bluetooth (二) 打开蓝牙
- android -- 蓝牙 bluetooth (二) 打开蓝牙
- android -- 蓝牙 bluetooth (二) 打开蓝牙
- android -- 蓝牙 bluetooth (二) 打开蓝牙
- android -- 蓝牙 bluetooth (二) 打开蓝牙
- android -- 蓝牙 bluetooth (二) 打开蓝牙
- android 蓝牙通信(二)
- Android蓝牙开发(二)
- Android蓝牙使用(二)
- Android蓝牙开发(二)
- 5同步容器类
- js获取设备操作系统
- VNC连不上服务器,无法远程控制
- GPIO原理
- MySQL Query Cache 看上去很美
- Android蓝牙(二)
- DB Link导致SCN Headroom过低问题研究
- 记录一次重构
- hihocoder1393(二分图多重匹配)
- 解决Git push时重复输入用户名密码的问题。
- Android四大图片缓存(Imageloader,Picasso,Glide,Fresco)原理、特性对比
- GAN在目标检测应用
- js省市区下拉代码分享
- RecycleView的使用