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

来源:互联网 发布:软件如何脱壳 编辑:程序博客网 时间:2024/05/31 13:16

一、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<ActivityManager.RunningServiceInfo> 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";
@Overridepublic 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<List<BleConnectDevice>>() {                    }.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;}



@Overridepublic 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<String> 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<BleConnectDevice> lstConnectDevices = new ArrayList<BleConnectDevice>();        String connectedinfo = prefs.getString(                Constants.REMOTE_CONNECTED_DEVICES, "");        Gson gson = new Gson();        if (!connectedinfo.equals("")) {            try {                lstConnectDevices = gson.fromJson(connectedinfo,                        new TypeToken<List<BleConnectDevice>>() {                        }.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

1 0