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

2023-10-29

一、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";
 
@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<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;
}

@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<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

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

App 和设备通过蓝牙连接收发数据 的相关文章

  • 通过蓝牙打印机 Android 打印 Pdf 文件

    在我的项目中需要通过蓝牙打印机打印Pdf文件 我写了一个代码通过pdf打印 它对于文本来说很好 但我想在蓝牙打印机上打印PDF文件 我的打印文本的java代码 Override public void onCreate Bundle sav
  • iOS 蓝牙应用程序仅在后台模式下“由于信号 9 而终止”

    我正在 Objective c 中开发一个 IOS 应用程序 它显示来自蓝牙 BLE 的心率以及相应的图形 如果应用程序在前台运行 则一切都可以正常分叉 没有任何问题 但是 如果应用程序进入后台模式 BLE 测量仍然会继续 我正在使用 使用
  • 没有姓名或地址。 CBCentralManager 不再在 macOS 12 上运行

    自从我将 macOS 更新到 macOS 12 以来 我每次在使用 CoreBluetooth 时都会遇到问题 在我的一个应用程序中 我将使用以下命令列出所有 BLE 设备CGCentralManager class 这已经有效多年了 但现
  • 蓝牙连接无需配对

    连接蓝牙设备的正常方式是通过配对 我们需要以非正常方式连接到设备 仅使用蓝牙 MAC 地址 我们不希望系统提示输入 PIN 我们知道该设备支持此技术 但我们找不到在 Android 上执行此操作的方法 缩写代码如下所示 String mac
  • bluez 同时具有经典和低能耗设备

    Linux下的bluez是否可以同时连接多个经典和低能耗设备 bluez 网站提供这样的信息不是很有帮助 是的 我已经成功同时连接到 7 个低能耗设备 最大值因您使用的硬件而异 您还可以连接到多个经典设备 以下是我用于通过 L2CAP 连接
  • 在c#中通过设备名称获取蓝牙设备的COM端口

    我用 C 编写一些代码来获取映射具有特定名称的蓝牙设备的 COM 端口 我尝试了几种与列出的类似的解决方案here https stackoverflow com questions 25908734 get name of bluetoo
  • 如何将 iPhone 音频路由到蓝牙耳机

    我正在尝试使用 AVAudioPlayer AVAudioSession 和 AudioSessionSetProperty 将音频输出到蓝牙耳机 不是 A2DP 似乎有选择蓝牙耳机作为输入的函数 kAudioSessionProperty
  • 寻找另一部智能手机的笛卡尔坐标?

    考虑到我有两部智能手机 A 和 B 如果我拿着智能手机 A 有没有办法确定 B 相对于我自己的位置 所以如果我们有这张图片的情况 它会告诉我 B 位于位置 2 1 利用 WiFi 信号强度来获取位置等创造性方法更受欢迎 我还可以确定两部手机
  • 蓝牙文件发送

    我是蓝牙开发的新手 我发现了 32netfeet 现在我可以搜索附近的蓝牙设备并连接到它们 但如何发送文件 例如 SendTest txt 我尝试使用 OBEX 的 buttonclick 事件 但我不明白这是我的示例代码 using In
  • 连接关闭且应用程序终止后,BLE 堆栈反复重新连接到外设

    我有一个应用程序 它打开与 BLE 设备的短暂连接 执行一些特征读取和写入 然后断开并关闭连接 应用程序使用 autoReconnect false 并且设备未配对或绑定 我看到 Android 的一些非常奇怪的行为 它似乎反复且意外地重新
  • 检测蓝牙“通话”按钮按下情况

    我有一个蓝牙耳机 可以与我的手机通信 它有一个大的 通话 按钮 可以接听 结束通话 我正在尝试制作一个应用程序 该应用程序能够在按下通话按钮时进行拦截 我尝试过使用意图过滤器
  • 安卓蓝牙无法连接

    我遇到这个问题已经有一段时间了 但一直无法解决 我有一个 Android 应用程序 它将所有配对的设备放在列表视图中 当您单击列表项之一时 它将发起连接到该蓝牙设备的请求 我可以毫无问题地获取设备列表及其地址 问题是 一旦我尝试连接 我就会
  • 附近连接 2.0:混合不同策略?

    我一直在尝试新的安卓 附近连接 v2 0 https android developers googleblog com 2017 07 announcing nearby connections 20 fully htmlAPI 并对用于
  • 0x0A 和 0x0D 之间的区别

    我正在研究蓝牙 我试图编写代码以在连接时继续监听输入流 我遇到了以下代码片段 int data mmInStream read if data 0x0A else if data 0x0D buffer new byte arr byte
  • 我可以在 iOS 中测量蓝牙信号强度吗?

    Can I 测量信号强度我的 iPhone 范围内的蓝牙设备数量 基本上我想要做的是扫描范围内的设备列表 然后查看哪个设备的信号强度最高 在 iOS 中是否可行 如果可以 我该怎么做 是的 有一种方法可以测量蓝牙低功耗 4 0 的信号强度
  • Android Lollipop BLE 扫描 - 获取没有重复的外设

    Android Lollipop 引入了一种扫描 BLE 外设的新方法 通过蓝牙扫描仪 http developer android com reference android bluetooth le BluetoothLeScanner
  • 判断串口是普通COM还是SPP

    我正在寻找一种方法来确定 COM 是标准 COM 还是 SPP COM 也称为 COM 设备的电缆替换蓝牙适配器 我有一个可以在 USB COM gt USB 和蓝牙下工作的设备 并且蓝牙接口可以与 SPP 一起工作 我目前正在使用Syst
  • Android蓝牙权限问题

    首先 抱歉我的英语不好 我是西班牙人 并且是 Android 开发的新手 我正在开发一个简单的蓝牙文件发送器 我基于BluetoothChat android示例一步一步 现在我向用户发出蓝牙激活请求 并选择是或否选项应用程序崩溃 我拥有清
  • 通过蓝牙将字符串从作为客户端的 PC 发送到作为服务器的移动设备

    我需要通过蓝牙将字符串从 PC 传输到 Android 移动设备的帮助 Android 移动设备应充当服务器并在设备屏幕上显示字符串消息 作为客户端的 PC 应该将字符串发送到移动设备 我希望服务器对提取的字符串 通过蓝牙传输 做出反应 这
  • 我安排一个计时器使用 readRSSI 函数读取 RSSI,但是当我的应用程序进入后台时计时器停止

    我安排一个计时器使用 readRSSI 函数读取 RSSI 但是当我的应用程序进入后台时计时器停止 也许有一个好方法可以在应用程序进入后台时从外围设备的通知中获取 RSSI 值 但我不知道该怎么办 有人可以帮助我吗 有人有更好的方法吗 我也

随机推荐

  • ningx跨域的方案

    location home rewrite home 1 break proxy pass https 添加上述代码
  • 深度学习-全连接神经网络-训练过程-模型正则与超参数调优- [北邮鲁鹏]

    目录标题 神经网络中的超参数 学习率 超参数优化方法 网格搜索法 随机搜索法 超参数搜索策略 粗搜索 精搜索 超参数的标尺空间 神经网络中的超参数 超参数 网络结构 隐层神经元个数 网络层数 非线性单元选择等 优化相关 学习率 dorpou
  • 华为OD机试真题 Java 实现【微服务的集成测试】【2023Q1 100分】

    目录 一 题目描述 二 输入描述 三 输出描述 四 解题思路 五 Java算法源码 六 效果展示 1 输入 2 输出 一 题目描述 现在有n个容器服务 服务的启动可能有一定的依赖性 有些服务启动没有依赖 其次服务自身启动加载会消耗一些时间
  • pandas从时间序列中判断是一周的第几天或星期几

    把时间列标准化时间格式 df time slot1 pd to datetime df time slot1 输出这一天是周中的第几天 Monday 0 Sunday 6 df dayofweek df time slot1 dt dayo
  • 数据湖和数据仓库的区别?

    简介 数据湖这个概念和数据仓库这两个概念一直搞不清楚 之前感觉区别就是数据湖是数据仓库的父集 数据湖是个伪命题 平时生活中也用不到 然后今天听了我的一个师哥的讲解 然后简单总结下 常见的问题 1 数据湖和数据仓库的区别 相似点 都可以处理海
  • PyQt5最全81 信号与槽之为类添加多个参数可选的信号

    PyQt5最全81 信号与槽之为类添加多个参数可选的信号 from PyQt5 QtCore import class MultiSignal QObject 为类添加多个信号 signal1 pyqtSignal 无参数 signal2
  • h5 跳转小程序微信浏览器不显示跳转按钮

    问题 静态页面 h5 页面 跳转小程序 在微信内置浏览器里面没有显示出跳转按钮 但是在其他浏览器则正常显示 可能有以下一些原因 1 jweixin js 版本 引入 jweixin js 需要 1 6 0 版本 http res2 wx q
  • ALV DATA_CHANGE与DATA_CHANGE FINISHED的区别

    Alv grid OO ALV中有两个事件 Event data changed和ata changed finished 第一个事件在可编辑字段的数据发生变化时触发 可用来检查数据的输入正确性 第二个事件是当数据修改完成后触发 如果数据没
  • 飞猪平台用户行为分析—python

    文章目录 一 项目背景 1 1数据来源 1 2数据介绍 二 分析目的 三 分析思路 四 数据分析 3 1数据清洗 3 2用户分析 3 2 1用户维度 3 2 1 1浏览量pv 访客量uv 成交量分析 3 2 1 2留存分析 3 2 1 3用
  • 执行命令定义时出错_深入浅出SDC clock定义(下)

    前情提要 前面两次分别和大家一起学习了SDC的整体框架组成和clock定义的一部分内容 如果想要查看可以点击下方蓝色链接 从中可以看出 所有SDC构成中最基本的就是clock的定义 它作为所有SDC的基础 贯穿到几乎所有SDC指令当中 并且
  • 区块链学习笔记(3)--交易机制与双花

    比特币的交易机制 如何交易 一位所有者 A 利用他的私钥对前一次交易T1和下一位所有者 B 的地址签署一个随机散列的数字签名 A将此数据签名制作为交易单T2 并将交易单T2广播全网 电子 货币就发送给了下一位所有者 要点 1 交易发起者的私
  • Android面试常见问题总结

    1 AsyncTask是什么 有什么缺陷 AsyncTask是一种轻量级的异步任务类 它可以在线程池中执行后台任务 然后把执行的进度和最终结果传递给主线程并在主线程中更新UI 多个AsyncTask对象是串行执行的 Android 1 5刚
  • 2的n次方对照表和二进制、十进制的互相转换

    2的1次方 2 2的2次方 4 2的3次方 8 2的4次方 16 2的5次方 32 2的6次方 64 2的7次方 128 2的8次方 256 2的9次方 512 2的10次方 1024 这里我介绍二进制和十进制快速的转换方法 例1 137
  • 深度学习图像分割学习路径

    深 度 学 习 图 像 分 割 学
  • 见证国内人工智能与机器人技术的进步

    随着新一代人工智能与机器人技术的不断进步 人工智能与机器人技术已上升为国家十四五规划首要发展的科技技术 同时 亦是引领新一轮科技革命和产业变革的战略性技术 具有溢出带动性的 头雁 效应 人工智能与机器人专业是与 物联网 互联网 高新技术产业
  • LeetCode-1487. Making File Names Unique

    Given an array of strings names of size n You will create n folders in your file system such that at the ith minute you
  • 这张互联网支付牌照被正式注销!

    本应出现在年初续展结果中的支付机构百联优力 北京 投资有限公司 简称 百联优力 的支付牌照于2月10日被正式注销 注销原因为不予续展 2月15日 中国人民银行官网公示的 已注销许可 页面再添三家支付机构名单 分别为江苏飞银商务智能科技有限公
  • 国内IT公司病的有多重?技术圈交际花谈软件研发管理怪现状

    虎嗅注 在创业过程中 研发管理是很重要的内容 但是国内创业公司的研发管理却长期处于一种比较混乱的状态 国内创业公司的研发管理到底出了什么问题 技术人攻略的Gracia采访了素有 技术圈交际花兼娱记 称号的程显峰 从程显峰的口中 我们可以了解
  • STL之unique_copy

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

    一 Android 中进行蓝牙开发需要用到的类和执行过程 1 使用BluetoothAdapter startLeScance来扫描设备 2 在扫描到设备的回调函数中的得到BluetoothDevice 对象 并使用Bluetooth st