Android--经典蓝牙(文件传输--socket通信)

标准蓝牙 UUID

0000xxxx-0000-1000-8000-00805F9B34FB

其中 xxxx 代表自定义部分

例如:
	蓝牙串口服务
			1101	-- SerialPortServiceClass_UUID
			1102    -- LANAccessUsingPPPServiceClass_UUID 
	拨号网络服务
			1103	-- DialupNetworkingServiceClass_UUID 
	信息同步服务
			1104 	-- IrMCSyncServiceClass_UUID 
	文件传输服务
			1106	-- OBEXFileTransferServiceClass_UUID
	蓝牙传真服务
			1111 	-- FaxServiceClass_UUID 
	蓝牙打印服务
			1126	-- HCRPrintServiceClass_UUID 
	个人局域网服务
			1115		-- PANUServiceClass_UUID 
	人机输入服务
			1124 	-- HumanInterfaceDeviceServiceClass_UUID 
			1125	-- HardcopyCableReplacementServiceClass_UUID 

经典蓝牙的绑定和通信

  1. 蓝牙的可被搜索和扫描
  2. 首先我们要绑定后才能正常通信
  3. 通信我们这里我们是通过socket来传输文件
服务端设置可被搜索/客户端开始扫描

一、服务端设置可被搜索和监听广播

  1. 首先使能蓝牙

     BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
     if (!adapter.isEnabled()) {
     	adapter.enable();
     }
    
  2. 设置可被搜索

    通过反射调动的setScanMode

     public static void setDiscoverableTimeout() {
     	try {
     		Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
     		setDiscoverableTimeout.setAccessible(true);
     		// Method setScanMode = BluetoothAdapter.class.getMethod("setScanMode", int.class, int.class);
     		Method setScanMode = BluetoothAdapter.class.getMethod("setScanMode", int.class);
     		setScanMode.setAccessible(true);
     		setDiscoverableTimeout.invoke(adapter, 0);
     		// Object state = setScanMode.invoke(adapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, 300);
     		Object state = setScanMode.invoke(adapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
     		Log.d(TAG, "setDiscoverableTimeout setScanMode:" + state);
     	} catch (Exception e) {
     		e.printStackTrace();
     		Log.e(TAG, "setDiscoverableTimeout failure:" + e.getMessage());
     	}
     }
    
  3. 服务端监听状态变化广播

二、客户端启动扫描和监听广播

  1. 首先也要先打开蓝牙(和上面方法相同)

  2. 开始扫描蓝牙

     if (!mBlueAdapter.isDiscovering()) {
         Log.d(TAG, "startDiscovery");
          mBlueAdapter.startDiscovery();
      }
    
  3. 服务端监听状态变化广播

    主要是为了获取绑定状态,连接状态,扫描返回,绑定请求

     IntentFilter filter = new IntentFilter();
     filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//蓝牙开关状态
     filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//蓝牙开始搜索
     filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//蓝牙搜索结束
    
     filter.addAction(BluetoothDevice.ACTION_FOUND);//蓝牙发现新设备(未配对的设备)
     filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);//在系统弹出配对框之前(确认/输入配对码)
     filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//设备配对状态改变
     filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);//最底层连接建立
     filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);//最底层连接断开
    
     filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); //BluetoothAdapter连接状态
     filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); //BluetoothHeadset连接状态
     filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); //BluetoothA2dp连接状态
     context.registerReceiver(this, filter);
    
扫描到蓝牙后开始绑定

一、客户创建绑定和确认绑定

  1. 扫描到蓝牙后–创建绑定

     public void onReceive(Context context, Intent intent) {
     	switch (intent.getAction()) {
     		case BluetoothDevice.ACTION_FOUND:
     			// 判断符合自己想要的蓝牙后,创建绑定
     			BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
     			creatBond(device.getClass(), device);
     			break;
     	}
    
     }
    
     private void creatBond(Class bluetoothClass, BluetoothDevice device) {
         try {
             Method createBondMethod = bluetoothClass.getMethod("createBond");
             Boolean value = (Boolean) createBondMethod.invoke(device);
             Log.d(TAG, "creatBond return " + value);
         } catch (NoSuchMethodException e) {
             e.printStackTrace();
         } catch (IllegalAccessException e) {
             e.printStackTrace();
         } catch (InvocationTargetException e) {
             e.printStackTrace();
         }
     }
    
  2. 配对请求

     public void onReceive(Context context, Intent intent) {
     	switch (intent.getAction()) {
     		case BluetoothDevice.ACTION_PAIRING_REQUEST:
     			BluetoothDevice device_bond= intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
     			int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
     			int pairingKey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR);
     			if (BluetoothDevice.BOND_NONE == type) {
     				abortBroadcast();//终止配对广播,取消系统配对框
     				// 注意setPairingConfirmation的调用需要系统权限
     				device.setPairingConfirmation(true);
     				device.setPin(intToByteArray(pairingKey));
     			}
     			break;
     	}
     }
    

二、服务端确认绑定

  1. 服务端收到广播后绑定

     public void onReceive(Context context, Intent intent) {
     	switch (intent.getAction()) {
     		case BluetoothDevice.ACTION_PAIRING_REQUEST:
     			BluetoothDevice device_bond= intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
     			int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
     			int pairingKey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR);
     			if (BluetoothDevice.BOND_NONE == type) {
     				abortBroadcast();//终止配对广播,取消系统配对框
     				// 注意setPairingConfirmation的调用需要系统权限
     				device.setPairingConfirmation(true);
     				device.setPin(intToByteArray(pairingKey));
     			}
     			break;
     	}
     }
    
绑定后开始连接

注意 SPP_UUID 为自定义的 uuid,保持客户端和服务端一致就好

public static final UUID SPP_UUID = UUID.fromString("0000ff01-0000-1000-8000-00805F9B34FB");

一、服务端监听

  1. 初始化服务端

     BluetoothServerSocket mSerSocket = adapter.listenUsingInsecureRfcommWithServiceRecord(TAG, SPP_UUID); //明文传输
     BluetoothSocket socket = mSocket.accept(); // 监听连接,阻塞
    

二、客户端连接

  1. 创建连接

     BluetoothSocket mBlueSocket = mDevice.createInsecureRfcommSocketToServiceRecord(SPP_UUID);
     try {
         mBlueSocket.connect();
         dataOut = new DataOutputStream(mBlueSocket.getOutputStream());
     } catch (IOException e) {
         e.printStackTrace();
     }
    
  2. 根据广播收到的连接成功-代表连接成功

数据传输

那么这里就是利用socket传输数据
输出,拿到输出流

	dataOut = new DataOutputStream(mBlueSocket.getOutputStream());

读取,拿到输入流

	dataIn = new DataInputStream(socket.getInputStream());
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值