• 蓝牙篇


    首先说蓝牙分类:蓝牙貌似分为4.0,和2.0版本,4.0版本更省电(BLE)

    判断方式如下: 是否支持蓝牙: getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)

            是否支持BLE蓝牙 : getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)

    //判断远端蓝牙类型:
    BluetoothDevice类中有个方法getType();如果返回的是 BluetoothDevice.DEVICE_TYPE_CLASSIC;经典蓝牙,也就是2.0,若是则是 BluetoothDevice.DEVICE_TYPE_LE) {//低功耗蓝牙设备

    注册蓝牙需要的广播:

    IntentFilter action_found = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    getActivity().registerReceiver(mReceiver, action_found);
    IntentFilter action_bond = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
    getActivity().registerReceiver(mReceiver, action_bond);
    IntentFilter action_disconnected = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
    getActivity().registerReceiver(mReceiver, action_disconnected);
    IntentFilter action_discover_end = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    getActivity().registerReceiver(mReceiver, action_discover_end);
    IntentFilter action_pairing_request = new IntentFilter(ACTION_PAIRING_REQUEST);
    getActivity().registerReceiver(mReceiver, action_pairing_request);
    //蓝牙广播
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
    public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    if (BluetoothDevice.ACTION_FOUND.equals(action)) {//发现一台蓝牙设备
    addDevice(device);
    } else if (ACTION_PAIRING_REQUEST.equals(action)) {//新设备直接连接,不用用户输入pin码可以这么做;
    setBluetoothPairingPin(device);
    } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {//扫描附近设备完成)

    } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {//蓝牙连接状态改变
    int prevBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1);
    int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
    if (bondState == BluetoothDevice.BOND_BONDING) {
    Log.i(TAG, "蓝牙连接中:" + device.getName());
    } else if (bondState == BluetoothDevice.BOND_BONDED) {//已连接
    ((MainActivity) getActivity()).goTagFragment();
    } else if (bondState == BluetoothDevice.BOND_NONE) {
    Log.i(TAG, "蓝牙没有连接" + device.getName());
    } else if (bondState == BluetoothDevice.ERROR) {
    Log.i(TAG, "蓝牙连接错误" + device.getName());
    ToastUtils.show(R.string.error_bluetooth_connect);
    ((MainActivity) getActivity()).goConnectBluetoothFragment();
    }
    } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {//断开连接
    Log.i(TAG, "蓝牙断开连接" + device.getName());
    ToastUtils.show(getString(R.string.bluetooth_disconnected));
    ((MainActivity) getActivity()).goConnectBluetoothFragment();
    }
    }
    };

     

    //准备配对去人配对码pin  
    public void setBluetoothPairingPin(BluetoothDevice device) {
    String string = "1234";
    byte[] pinBytes = string.getBytes();
    try {
    //Log.d(TAG, "Try to set the PIN");
    Method m = device.getClass().getMethod("setPin", byte[].class);
    m.invoke(device, pinBytes);
    Log.d(TAG, "Success to add the PIN.");
    try {
    device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
    Log.d(TAG, "Success to setPairingConfirmation.");
    } catch (Exception e) {
    // TODO Auto-generated catch block
    // Log.e(TAG, e.getMessage());
    e.printStackTrace();
    }
    } catch (Exception e) {
    // Log.e(TAG, e.getMessage());
    e.printStackTrace();
    }
    }
    //取消蓝牙配对
    private void unpairDevice(BluetoothDevice device) {
    try {
    Method m = device.getClass().getMethod("removeBond", (Class[]) null);
    m.invoke(device, (Object[]) null);
    if (device.getAddress().equals(mLast_addr)) {
    sp.edit().putString(KEY_LAST_ADDR_STRING, "").commit();
    mLast_addr = "";
    }
    } catch (Exception e) {
    Log.e(TAG, e.getMessage());
    }
    }
    BluetoothAdapter是本地自己的蓝牙类,获取蓝牙方法:
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    bluetoothAdapter.isEnabled();是判断蓝牙是否打开;
    打开蓝牙方式:
    bluetoothAdapter.enable();打开蓝牙(不做提示,强行打开)
    //弹出对话框提示用户是后打开
    Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enabler, REQUEST_ENABLE_BT);
    bluetoothAdapter.disable()  ;关闭蓝牙
    bluetoothAdapter.cancelDiscovery();取消扫描
    bluetoothAdapter.startDiscovery();开始扫描附近蓝牙设备
    Set<BluetoothDevice> mBTpaired  = bluetoothAdapter.getBondedDevices();获取曾经连接过的设备
    再连接前最好停止扫描调用
    cancelDiscovery这样能够加速
    低功耗BLE蓝牙,连接与传输都使用的是回调的方式
    BluetoothDevice 中 .connectGatt(mContext, false, mGattCallback);方法连接,第一个是上下文,第二个是否自动连接,第三个是连接监听回调接接口,如下,创建,然后重写方法即可
    /**
    * 连接与远端蓝牙回调
    */
    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback()
    其中这个
    onConnectionStateChange方法中有个newstate是当前蓝牙连接状态,如果和 BluetoothProfile.STATE_CONNECTED一致则是连接完成,同时需要开线程准备写入工作,
    mBluetoothGatt.getDevice();然后获取当前连接的设备是这个
    经典蓝牙需要创建一个线程,然后通过
    BluetoothSocket mmSocket  = BluetoothDevice.createRfcommSocketToServiceRecord(SPP_UUID);的方法获取套接字一般UUID使用:
    // Unique UUID for this application这个应用程序的唯一UUID
    // 此处,必须使用Android的SSP(协议栈默认)的UUID:SPP UUID: 00001101-0000-1000-8000-00805F9B34FB
    private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    然后通过获取的套接字连接,为什么开线程就是因为这里会堵塞:
    // Connect the device through the socket. This will block until it succeeds or throws an exception
    // 通过插座连接设备。它会阻塞,直到它成功或抛出异常
    mmSocket.connect();
    然后需要在通过获取到的套接字socket进行获取输入输出流
    然后死循环一直进行
    BluetoothSocket socket中的socket.getInputStream();获取输入流
    socket.getOutputStream();获取输出流
    在连接前同时我们需要也开死循环判断服务端是否连接状态,实现多途径连接状态
    BluetoothServerSocket =bluetoothAdapter的listenUsingRfcommWithServiceRecord获取一个服务端的socket需要传入一个name和uuid,  name用当前类名就行,uuid还用刚才的
    然后死循环判断状态
    BluetoothServerSocket .accept();可以获取一个BluetoothSocket

     

  • 相关阅读:
    华章IT图书书讯(2011年第8期)
    iPhone游戏开发实践指南
    【北京讲座】Android系统Framework层源码分析(2011.09.24)
    深入理解Android
    你学或不学,Java就在那里,不离不弃
    近百本精品图书全部免费赠送——仅面向学生
    极限编程(Extreme Programming, XP)
    对任何希望深入理解C#的程序员来说,这本书都是不容错过的经典书籍
    C# 文件操作(转)
    一些数据格式化Eval( " ")和DataBinder.Eval(Container.DataItem, " ")的区别及用法
  • 原文地址:https://www.cnblogs.com/lizhanqi/p/7423191.html
Copyright © 2020-2023  润新知