App 和设备通过蓝牙连接收发数据

一、Android 中进行蓝牙开发需要用到的类和执行过程

        1,使用BluetoothAdapter.startLeScance来扫描设备

     2,在扫描到设备的回调函数中的得到BluetoothDevice 对象,并使用Bluetooth.stopLeScan停止扫描

     3,使用BluetoothDevice.connectGatt来获取到BluetoothGatt对象

     4,执行BluetoothGatt.discoverServices,这个方法是异步操作,在回调函数onServicesDiscovered中得到status,通过判断status是否等于BluetoothGatt.GATT_SUCCESS来            判断查找Service是否成功

     5,如果成功了,则通过BluetoothGatt.getService来获取BluetoothGattService

     6,接着通过BluetoothGattService.getCharacteristic获取BluetoothGattCharacteristic

     7,然后通过BluetoothGattCharacteristic.getDescriptor获取BluetoothGattDescriptor


二、收发数据

      收发数据是通过GATT,GATT是通过蓝牙收发数据的一种协议,包含Characteristic,Descriptor,Service 三个属性值,BLE 分为三个部分Service , Characteristic ,Descriptor  这三个部分都是由UUID做为唯一的标识符,一个蓝牙终端可以包含多个Service ,一个Service 可以包含多个Characteristic ,一个Characteristic 包含一个Value 和多个Descriptor,一个Descriptor包含一个Value


三、上代码(有些工具类是在其他文件里面,我这里没有在改了,直接复制上来了)

MainActivice.java:


BluetoothManager bluetoothManager;
BluetoothAdapter mBluetoothAdapter;
Intent intentBluetoothLeService = new Intent();
//低功耗蓝牙的文件名
public static String BLUETOOTHSERVICE = "com.boe.navapp.remote.BluetoothLeService";




bluetoothManager = (BluetoothManager) MainActivity.this
        .getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
    if (!(CommonUtil.isServiceRunning(MainActivity.this,
            Constants.BLUETOOTHSERVICE))) {
        intentBluetoothLeService = new Intent(MainActivity.this,
                BluetoothLeService.class);
        startService(intentBluetoothLeService);
    }
}
 
   
 
   
 
   
 
   
// 判断当前服务是否启动
public static boolean isServiceRunning(Context mContext, String className) {
    boolean isRunning = false;
    ActivityManager activityManager = (ActivityManager) mContext
            .getSystemService(Context.ACTIVITY_SERVICE);
    List serviceList = activityManager
            .getRunningServices(70);
    if (!(serviceList.size() > 0)) {
        return false;
    }
    for (int i = 0; i < serviceList.size(); i++) {
        if (serviceList.get(i).service.getClassName().equals(className) == true) {
            isRunning = true;
            break;
        }
    }
    return isRunning;
}


BluetoothLeService.java:(這里我讲下主要代码,文件我会传上去)

public final static String REMOTE_CONNECT_STATUS = "REMOTE_CONNECT_STATUS";// 当前选择的遥控器连接状态
public final static String REMOTE_CONNECTED_DEVICES = "REMOTECONNECTEDDEVICES";// 存储已经连接的设备列表
public final static String REMOTE_DEVICE_INFO = "REMOTEDEVICEINFO";
public final static String REMOTE_CURR_ADDR = "REMOTECURRADDR";// 当前连接设备的地址
public final static String ACTION_GATT_REMOTESEVEN_DISCONNECTED = "com.infisight.hudprojector.bluetooth.le.ACTION_GATT_REMOTESEVEN_DISCONNECTED";
private static final String SP_NAME = "address";
 
  
@Override
public void onCreate() {
    super.onCreate();
    LogTools.i(TAG, "BluetoothLeService onCreate");
    prefs = PreferenceManager.getDefaultSharedPreferences(this);
    telMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    prefs.edit().putBoolean(Constants.REMOTE_CONNECT_STATUS, false)
            .commit();
    LogTools.i(TAG, "BluetoothLeService before SaveUtils.loadArray");
    addressList = SaveUtils.loadArray(this, SP_NAME);  //存放连接的地址
    GetDeviceInfo();
    LogTools.i(TAG, "BluetoothLeService GetDeviceInfo");
}

/**
 * 获取设备信息 lstNeedConnectDevices
 */
private void GetDeviceInfo() {
    String connectedinfo = prefs.getString(
            Constants.REMOTE_CONNECTED_DEVICES, "");
    if (!connectedinfo.equals("")) {
        Gson gson = new Gson();
        try {
            lstNeedConnectDevices = gson.fromJson(connectedinfo,
                    new TypeToken>() {
                    }.getType());
            for (BleConnectDevice bleconnectdevice : lstNeedConnectDevices) {
                if (!lstNeedConnectAddress.contains(bleconnectdevice
                        .getAddress()))
                    lstNeedConnectAddress
                            .add(bleconnectdevice.getAddress());
            }
        } catch (Exception e) {
        }
    }
}

public boolean initialize() {
    // 获取蓝牙管理
    if (mBluetoothManager == null) {
        mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        if (mBluetoothManager == null) {
            return false;
        }
    }
    // 获取适配器
    mBluetoothAdapter = mBluetoothManager.getAdapter();
    return mBluetoothAdapter != null;
}



@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    LogTools.d(TAG, "onStartCommand:flags=" + flags + ",startId=" + startId);
    if (mBluetoothManager == null) {
        if (!initialize()) {
            LogTools.i(TAG, "Unable to initialize Bluetooth");
        }
    }
    if (isFirstRun) {
        try {
            handler.postDelayed(runnable, 2000);
        } catch (Exception e) {
        }
    } else {
        LogTools.i(TAG, "Constants.REMOTE_DEVICE_INFO:");
        String address = getSharedPreferences(Constants.REMOTE_DEVICE_INFO,
                0).getString(Constants.REMOTE_CURR_ADDR, "0");
        connect(address);
    }
    isFirstRun = false;
    return START_STICKY;
}


/**
 * 启动连接线程
 */
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        // 在这里启动连接,如果连接失败,就再重新试图连接
        LogTools.i(TAG, "try connect runnable");
        try {
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
            mBluetoothAdapter.startLeScan(mLeScanCallback); //扫描低功耗蓝牙设备
        } catch (Exception e) {
            // TODO Auto-generated catch block
            LogTools.i(TAG, "try connect runnable failed:" + e.getMessage());
            e.printStackTrace();
        }
        handler.postDelayed(this, 10000);
    }

};



// 设备查找回调得到BluetoothDevice对象
LeScanCallback mLeScanCallback = new LeScanCallback() {

    @Override
    public void onLeScan(final BluetoothDevice device, int rssi,
                         byte[] scanRecord) {
        LogTools.d(TAG, "device.getName:" + device.getName() + ",device.address:" + device.getAddress());
        if ("KeyCtrl".equals(device.getName())) {
            close(mGattMap.get(device.getAddress()));

            //获取BluetoothGatt 对象
            BluetoothGatt mBluetoothGatt = device.connectGatt(
                    BluetoothLeService.this, false, mGattCallback);
            mGattMap.put(device.getAddress(), mBluetoothGatt);
        } else if ("infisight_r".equals(device.getName()))//对蓝牙OBD功能进行连接
        {
            try {
                close(mGattMap.get(device.getAddress()));
                BluetoothGatt mBluetoothGatt = device.connectGatt(
                        BluetoothLeService.this, false, mGattCallback);
                mGattMap.put(device.getAddress(), mBluetoothGatt);
            } catch (Exception e) {
                LogTools.e(TAG, "mBluetoothGatt failed:" + e.getMessage());
            }
        }

    }
};


    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {

        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                            int newState) {
            // 连接状态发生变更
            String intentAction = Constants.ACTION_GATT_REMOTESEVEN_DISCONNECTED;
            LogTools.e(TAG, "onConnectionStateChange:name:" + gatt.getDevice().getName() + "Addr:" + gatt.getDevice().getAddress() + ",newState:" + newState);
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                hmIsConnected.put(gatt.getDevice().getAddress(), true);
                SaveUtils.saveArray(BluetoothLeService.this, SP_NAME,
                        addressList);
                if ("KeyCtrl".equals(gatt.getDevice().getName())) {
                    intentAction = Constants.ACTION_GATT_REMOTE_CONNECTED;
                } else if ("infisight_r".equals(gatt.getDevice().getName())) {
                    LogTools.e(TAG, "ble ACTION_GATT_REMOTE_CONNECTED");
                    intentAction = Constants.ACTION_GATT_REMOTESEVEN_CONNECTED;
                }
                prefs.edit().putBoolean(Constants.REMOTE_CONNECT_STATUS, true)
                        .commit();
                broadcastUpdate(intentAction);
                LogTools.e(TAG, "ble gatt.discoverServices");
                gatt.discoverServices();
                SaveDeviceInfo(gatt.getDevice());
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                LogTools.d(TAG, "BluetoothProfile.STATE_DISCONNECTED");
                // 开启线程,不断时的试图连接设备
                hmIsConnected.put(gatt.getDevice().getAddress(), false);
                if ("KeyCtrl".equals(gatt.getDevice().getName())) {
                    intentAction = Constants.ACTION_GATT_REMOTE_DISCONNECTED;
                } else if ("infisight_r".equals(gatt.getDevice().getName())) {
                    LogTools.d(TAG, "BLE BluetoothProfile.STATE_DISCONNECTED");
                    intentAction = Constants.ACTION_GATT_REMOTESEVEN_DISCONNECTED;
                }
                prefs.edit().putBoolean(Constants.REMOTE_CONNECT_STATUS, false)
                        .commit();
//                close(gatt);
                disconnect(gatt);
                broadcastUpdate(intentAction);
            }
        }

        //通过status 是否等于BluetoothGatt.GATT_SUCCESS来判断查找Service是否成功
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            // 发现服务的广播
            LogTools.e(TAG, "onServicesDiscovered:" + gatt.getDevice().getAddress());
            if (status == BluetoothGatt.GATT_SUCCESS) {
                displayGattServices(getSupportedGattServices(gatt), gatt);
                broadcastUpdate(Constants.ACTION_GATT_SERVICES_DISCOVERED);

            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic, int status) {
            LogTools.d(TAG, "onCharacteristicRead");
            if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(Constants.ACTION_DATA_AVAILABLE, gatt, characteristic);
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            LogTools.d(TAG, "onCharacteristicChanged");
            broadcastUpdate(Constants.ACTION_DATA_AVAILABLE, gatt, characteristic);
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt,
                                          BluetoothGattCharacteristic characteristic, int status) {

        }
    };

   

 public static boolean saveArray(Context context, String spname, ArrayList list) {
        mySharedPreferences = context.getSharedPreferences(spname, Context.MODE_PRIVATE);
        Editor edit = mySharedPreferences.edit();
        edit.putInt("Status_size", list.size()); /*sKey is an array*/

        for (int i = 0; i < list.size(); i++) {
            edit.putString("Status_" + i, list.get(i) + "");
        }
//     LogTools.i("saveArray", list+"");
        return edit.commit();
    }
 
  
  private void broadcastUpdate(final String action) {
        final Intent intent = new Intent(action);
        sendBroadcast(intent);
    }
 
  
 
  
/**
     * 保存设备信息
     */
    private void SaveDeviceInfo(BluetoothDevice bluetoothdevice) {
        List lstConnectDevices = new ArrayList();
        String connectedinfo = prefs.getString(
                Constants.REMOTE_CONNECTED_DEVICES, "");
        Gson gson = new Gson();
        if (!connectedinfo.equals("")) {

            try {
                lstConnectDevices = gson.fromJson(connectedinfo,
                        new TypeToken>() {
                        }.getType());
            } catch (Exception e) {
            }
        }
        if (!lstNeedConnectAddress.contains(bluetoothdevice.getAddress())) {
            lstNeedConnectAddress.add(bluetoothdevice.getAddress());
            BleConnectDevice bledevice = new BleConnectDevice(); //保存设备的信息
            bledevice.setAddress(bluetoothdevice.getAddress());
            bledevice.setName(bluetoothdevice.getName());
            lstConnectDevices.add(bledevice);
            try {
                String newaddr = gson.toJson(lstConnectDevices);
                prefs.edit()
                        .putString(Constants.REMOTE_CONNECTED_DEVICES, newaddr)
                        .commit();
            } catch (Exception e) {
            }
        } else if ("KeyCtrl".equals(bluetoothdevice.getName())) {
            mTypeMap.put(bluetoothdevice.getAddress(), "remote");
//        }else  if (bluetoothdevice.getName().contains("BLE"))//对蓝牙OBD功能进行连接
        } else if ("infisight_r".equals(bluetoothdevice.getName()))//对蓝牙OBD功能进行连接
        {
            mTypeMap.put(bluetoothdevice.getAddress(), "remote");
        }

    }
 
  
 
  
 
  
 
  
  public boolean connect(final String address) {
        // 确认已经获取到适配器并且地址不为空
        if (mBluetoothAdapter == null || address == null || address.equals("0")) {
            return false;
        }

        final BluetoothDevice device = mBluetoothAdapter
                .getRemoteDevice(address);
        // 通过设备地址获取设备
        if (device == null) {
            LogTools.e(TAG, "Device not found.  Unable to connect.");
            return false;
        }
        // LogTools.i(TAG, "device.connectGatt(this, false, mGattCallback)");
        if (mGattMap.keySet().contains(address)) {
            BluetoothGatt mBluetoothGatt = mGattMap.get(address);
            if (mBluetoothGatt != null) {
                // close(mBluetoothGatt);
                disconnect(mBluetoothGatt);
            }
        }
        BluetoothGatt mBluetoothGatt = device.connectGatt(this, false,
                mGattCallback);
        mGattMap.put(address, mBluetoothGatt);
        addressList.add(address);
//        mConnectionState = STATE_CONNECTING;

        return true;
    }

 
  
 
  
public void disconnect(BluetoothGatt mBluetoothGatt) {
    // LogTools.i("LIFECYCLE", "disconnect");
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        LogTools.e(TAG, "BluetoothAdapter not initialized disconnect");
        return;
    }
    mBluetoothGatt.disconnect();
    // 断开连接
}

 
  
 
  
 
  
  // 从特征中分析返回的数据并表示为action后进行广播
    private void broadcastUpdate(final String action, BluetoothGatt gatt,
                                 final BluetoothGattCharacteristic characteristic) {
        if ("KeyCtrl".equals(gatt.getDevice().getName())) {
            final byte[] data = characteristic.getValue();
            if (data != null && data.length > 0) {
                final StringBuilder stringBuilder = new StringBuilder(data.length);
                for (byte byteChar : data)
                    stringBuilder.append(String.format("%02X ", byteChar));
                if (stringBuilder.toString().trim().equals("01")) {
                    // 上
                    int operFlag = 1;
                    Message msg = sendKeyHandler.obtainMessage(operFlag);
                    msg.what = operFlag;
                    msg.sendToTarget();
                    LogTools.i(TAG, "keys01");

                } else if (stringBuilder.toString().trim().equals("02")) {
                    LogTools.i(TAG, "isPhoneIng:"+ProcessMsgService.isPhoneIng);
                    if(ProcessMsgService.isPhoneIng == true)
                    {
                        try {
                            PhoneUtils.getITelephony(telMgr)
                                    .answerRingingCall();
                        } catch (RemoteException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (Exception e) {
                            LogTools.i(TAG, "error:"+e.getMessage());
                            CommonUtil.answerRingingCall(this);
                        }
                        return;
                    }
                    // 确定
                    int operFlag = 5;
                    Message msg = sendKeyHandler.obtainMessage(operFlag);
                    msg.what = operFlag;
                    msg.sendToTarget();
//          ProcessBroadcast(Constants.GESTURE_INFO,
//                Constants.GESTURE_SINGLETAP);
                    LogTools.i(TAG, "keys02");
                } else if (stringBuilder.toString().trim().equals("04")) {
                    // 唤醒
                    MainActivity.svr.controlToWake(true);
                    LogTools.i(TAG, "keys04");
                } else if (stringBuilder.toString().trim().equals("08")) {
                    LogTools.i(TAG, "isPhoneIng:"+ProcessMsgService.isPhoneIng);
                    LogTools.i(TAG, "keys08");
                    if(ProcessMsgService.isPhoneIng == true)
                    {
                        try {
                            PhoneUtils.getITelephony(telMgr).endCall();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return;
                    }
                    // 返回
                    int operFlag = 0;
                    Message msg = sendKeyHandler.obtainMessage(operFlag);
                    msg.what = operFlag;
                    msg.sendToTarget();
//          ProcessBroadcast(Constants.GESTURE_INFO,
//                Constants.GETSTURE_BACK);
                    LogTools.i(TAG, "keys08");
                } else if (stringBuilder.toString().trim().equals("10")) {
                    // 下
                    int operFlag = 2;
                    Message msg = sendKeyHandler.obtainMessage(operFlag);
                    msg.what = operFlag;
                    msg.sendToTarget();
//          ProcessBroadcast(Constants.GESTURE_INFO,
//                Constants.GESTURE_TODOWN);
                    LogTools.i(TAG, "keys10");
                }
                // intent.putExtra(EXTRA_DATA, new String(data) + "\n" +
                // stringBuilder.toString());
            }
//        }else if (gatt.getDevice().getName().contains("BLE"))
        } else if ("infisight_r".equals(gatt.getDevice().getName())) {
            final byte[] data = characteristic.getValue();
            if (data != null && data.length > 0) {
                final StringBuilder stringBuilder = new StringBuilder(data.length);
                for (byte byteChar : data)
                    stringBuilder.append(String.format("%02X ", byteChar));
                if (stringBuilder.toString().trim().equals("15")) {
                    // 上
                    int operFlag = 1;
                    Message msg = sendKeyHandler.obtainMessage(operFlag);
                    msg.what = operFlag;
                    msg.sendToTarget();

                } else if (stringBuilder.toString().trim().equals("12")) {
                    //如果在通话中,接听电话
                    if(ProcessMsgService.isPhoneIng == true)
                    {
                        try {
                            PhoneUtils.getITelephony(telMgr)
                                    .answerRingingCall();
                        } catch (RemoteException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (Exception e) {
                            CommonUtil.answerRingingCall(this);
                        }
                        return;
                    }
                    // 确定
                    int operFlag = 5;
                    Message msg = sendKeyHandler.obtainMessage(operFlag);
                    msg.what = operFlag;
                    msg.sendToTarget();
//          ProcessBroadcast(Constants.GESTURE_INFO,
//                Constants.GESTURE_SINGLETAP);
                } else if (stringBuilder.toString().trim().equals("14")) {
                    // 唤醒
                    MainActivity.svr.controlToWake(true);
                } else if (stringBuilder.toString().trim().equals("16")) {
                    //如果已经在通话中,直接挂断电话
                    LogTools.i(TAG, "key:16");
                    LogTools.i(TAG, "isPhoneIng:"+ProcessMsgService.isPhoneIng);
                    if(ProcessMsgService.isPhoneIng == true)
                    {
                        try {
                            PhoneUtils.getITelephony(telMgr).endCall();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return;
                    }
                    // 返回
                    int operFlag = 0;
                    Message msg = sendKeyHandler.obtainMessage(operFlag);
                    msg.what = operFlag;
                    msg.sendToTarget();
//          ProcessBroadcast(Constants.GESTURE_INFO,
//                Constants.GETSTURE_BACK);
                } else if (stringBuilder.toString().trim().equals("11")) {
                    // 下
                    int operFlag = 2;
                    Message msg = sendKeyHandler.obtainMessage(operFlag);
                    msg.what = operFlag;
                    msg.sendToTarget();
//          ProcessBroadcast(Constants.GESTURE_INFO,
//                Constants.GESTURE_TODOWN);
                } else if (stringBuilder.toString().trim().equals("13")) {
                    // 左
                    int operFlag = 3;
                    Message msg = sendKeyHandler.obtainMessage(operFlag);
                    msg.what = operFlag;
                    msg.sendToTarget();
//          ProcessBroadcast(Constants.GESTURE_INFO,
//                Constants.GESTURE_TOLEFT);
                } else if (stringBuilder.toString().trim().equals("17")) {
                    // 右
                    int operFlag = 4;
                    Message msg = sendKeyHandler.obtainMessage(operFlag);
                    msg.what = operFlag;
                    msg.sendToTarget();
//          ProcessBroadcast(Constants.GESTURE_INFO,
//                Constants.GESTURE_TORIGHT);
                }
            }
        }

    }

BluetoothService 下载地址http://download.csdn.net/detail/pigseesunset/9690371

 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  

你可能感兴趣的:(App 和设备通过蓝牙连接收发数据)