精华内容
下载资源
问答
  • 最近搞了搞蓝牙,我在蓝牙设备上定时...然而我使用电脑和iphone手机却可以接收到被安卓手机连接蓝牙设备的广播0 0,用另一部安卓手机也扫描不到设备广播。。。这是安卓本身的原因吗?如果可以解决,应该如何解决
  • 最近公司项目要通过手机蓝牙连接硬件设备,硬件设备的通讯方式采用的是BLE低功耗蓝牙,低功耗蓝牙与传统用蓝牙的区别现在做赘述,BLE在Android4.3以上系统开始提供支持,且目前大部分的蓝牙通讯模式采用的都是低...

    最近公司项目要通过手机蓝牙连接硬件设备,硬件设备的通讯方式采用的是BLE低功耗蓝牙,低功耗蓝牙与传统用蓝牙的区别现在不做赘述,BLE在Android4.3以上系统开始提供支持,且目前大部分的蓝牙通讯模式采用的都是低功耗蓝牙,下面是我再开发中了解到额一些知识,在这里做基础总结,如果有不对和欠妥的地方请指正。原谅小弟的学疏才浅

     

     

    1、权限声明

    特别注意蓝牙搜索需要位置权限

    <!--声明蓝牙权限-->
        <uses-permission android:name="android.permission.BLUETOOTH" />
        <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
        <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    1 获取蓝牙是适配器

    蓝牙适配器 BluetoothAdapter在此可以看做是搜索蓝牙设备的工具获得方式:

    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();

    3开始搜索蓝牙设备

    设计到一个搜索回调

    BluetoothAdapter.LeScanCallback leScanCallback;

     

     

    //蓝牙连接返回的对象

    BluetoothGatt bluetoothGatt;

    //搜索回调
    leScanCallback = new BluetoothAdapter.LeScanCallback() {
      @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
      @Override
      public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
       //停止搜索到条件 比如我们搜索到名字叫xx的设备就停止搜索
        if (!TextUtils.isEmpty(device.getName()) && "xx".equals(device.getName().trim())) {
          if (adapter.isDiscovering()) {
            adapter.stopLeScan(leScanCallback);
          }
    //蓝牙连接
          bluetoothGatt = device.connectGatt(ConnectActivivty.this, false, bluetoothGattCallback);
        }
      }
    };

     

    BluetoothGatt 是个非常重要的类,它由蓝牙连接成功后返回,连接成功的后得读写操作都要靠他来完成,所以一般把他定义成全局变量

    我们连接获取BluetoothGatt 之后就要进行服务端连接,我在这里是这么认为的,蓝牙设备连接成功之后现在还不能进行通讯,BluetoothGatt 下包含很多服务也就是 BluetoothGattService,而每个BluetoothGattService下面又有很多蓝牙通道BluetoothGattCharacteristic,我们只有确定了蓝牙传输通道,在这个通道内才可以进行通讯。

    上面的

    bluetoothGattCallback就是设备连接时候要设置的回调
     //连接的回调
        bluetoothGattCallback = new BluetoothGattCallback() {
          @Override
          public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
              if (newState == BluetoothProfile.STATE_CONNECTED) {
                //这里是子线程你不要做UI操作,否侧程序无法继续执行
                //连接成功
                //Toast.makeText(ConnectActivivty.this, "连接成功", Toast.LENGTH_LONG).show();
                //去发现服务
                bluetoothGatt.discoverServices();
    
              }
          }
    
       //发现服务
          @Override
          public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
    //我们通过服务id来获取唯一服务,这个一般由硬件厂商指定,当然它也有一个默认值
            BluetoothGattService bluetoothGattService = bluetoothGatt.getService(UUID.fromString("00001000-0000-1000-8000-00805f9b34fb"));
    //我们通过特征(也就是我们说的通道)id来获取唯一读取特征,这个一般由硬件厂商指定,当然它也有一个默认值
            BluetoothGattCharacteristic characteristic = bluetoothGattService.getCharacteristic(UUID.fromString("00001002-0000-1000-8000-00805f9b34fb"));
    拿到通道后我们设置监听此通道
            gatt.setCharacteristicNotification(characteristic, true);
          }
    
          @Override
          public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            Log.e("hhh", new String(characteristic.getValue()));
          }
    
          @Override
          public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);
          }
    
    
    //特征值发生变化,我们认为有新的消息发来
          @Override
          public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            Log.e("hhh", new String(characteristic.getValue()));
          }
    
          @Override
          public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorRead(gatt, descriptor, status);
          }
    
          @Override
          public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(gatt, descriptor, status);
          }
    
          @Override
          public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
            super.onReliableWriteCompleted(gatt, status);
          }
    
          @Override
          public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            super.onReadRemoteRssi(gatt, rssi, status);
          }
    
          @Override
          public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
            super.onMtuChanged(gatt, mtu, status);
          }
        };

     

     

    以下是在真正进入蓝牙连接之前索要做的零基础判断,包括是否支持BLE,蓝牙和定位是否开启,权限是否开启

     if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
          ToastUtils.showShort("您的手机不支持此功能");
          return;
        }
        boolean isBlueToothEnable = isBlueToothEnable();
        boolean isLocalEnable = isLocationEnabled();
        if (!isBlueToothEnable && isLocalEnable) {
          ToastUtils.showShort("请打开蓝牙功能");
          return;
        }
        if (isBlueToothEnable && !isLocalEnable) {
          ToastUtils.showShort("请打开定位功能");
          return;
        }
        if (!isBlueToothEnable && !isLocalEnable) {
          ToastUtils.showShort("请打开蓝牙和定位功能");
          return;
        }
    
          XXPermissions.with(ChooseCheckItemActivity.this)
            .constantRequest()
            .permission(new ArrayList(){{
              add(Manifest.permission.ACCESS_COARSE_LOCATION);
              add(Manifest.permission.BLUETOOTH);
              add(Manifest.permission.ACCESS_FINE_LOCATION);
              add(Manifest.permission.BLUETOOTH_ADMIN);}})
            .request(new OnPermission() {
              @Override
              public void hasPermission(List<String> granted, boolean isAll) {
                if (isAll) {
                  if (ChooseCheckItemActivity.this != null) {
                    //前往蓝牙连接
                    Intent intent = new Intent(ChooseCheckItemActivity.this, CheckBloodActivity.class);   
                    startActivity(intent);
                    finish();
                  }
                  ALog.dTag("", "获取权限成功");
                } else {
                  ALog.dTag("", "获取权限成功,部分权限未正常授予");
                }
              }
    
              @Override
              public void noPermission(List<String> denied, boolean quick) {
                if (quick) {
                  ALog.dTag("", "被永久拒绝授权,请手动授予权限");
                  //如果是被永久拒绝就跳转到应用权限系统设置页面
                  XXPermissions.gotoPermissionSettings(ChooseCheckItemActivity.this);
                } else {
                  ALog.dTag("", "获取权限失败");
                }
              }
            });
      }
    });
    //蓝牙是否打开
      public boolean isBlueToothEnable() {
         BluetoothAdapter mBluetoothAdapter = BluetoothAdapter
          .getDefaultAdapter();
        if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
          return true;
        }
        return false;
      }
    
      //定位手机定位功能是否打开
      public boolean isLocationEnabled() {
        int locationMode = 0;
        String locationProviders;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
          try {
            locationMode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE);
          } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
            return false;
          }
          return locationMode != Settings.Secure.LOCATION_MODE_OFF;
        } else {
          locationProviders = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
          return !TextUtils.isEmpty(locationProviders);
        }
      }

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 1.两个手机都打开蓝牙,如果离开设置蓝牙界面,难么你会发现你们都搜索不到彼此的设备。这不是你的错,这是谷歌的一个坑。 因为如下: 解决: //设置蓝牙可以被其他搜索到 blue.setScanMo...

    这两天又在搞蓝牙,蓝牙伤我千百遍,我待蓝牙如初恋。

    有位朋友说,做个appdemo,来和他的蓝牙模块进行交互。我发现我对蓝牙真的是连冰山一角都还没了解完。说说我都遇到了什么问题吧。

    1.两个手机都打开蓝牙,如果离开设置蓝牙界面,难么你会发现你们都搜索不到彼此的设备。这不是你的错,这是谷歌的一个坑。

    因为如下:

    解决:

     //设置蓝牙可以被其他搜索到 
     blue.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);    
    
     //设置蓝牙可见的时间。0:是永久可见
     blue.setDiscoverableTimeout(0);//0:蓝牙永久可见

    这个时候又郁闷了。BaseAdapter的源码里面setDiscoverableTimeout()和setScanMode()都被/*hide*/注释着。啊,是不是想要蓝牙现身有点曲折,我们想要用这两个方法还是有办法的。利用反射,调用这两个方法。

    添加如下代码:

    
        public void setDiscoverableTimeout(BluetoothAdapter adapter,int timeout) {
            try {
                Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
                setDiscoverableTimeout.setAccessible(true);
                Method setScanMode =BluetoothAdapter.class.getMethod("setScanMode", int.class,int.class);
                setScanMode.setAccessible(true);
    
                setDiscoverableTimeout.invoke(adapter, timeout);
                setScanMode.invoke(adapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE,timeout);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    这样就可以调用setDiscoverableTimeout()和setScanMode()方法了,就可以让其他设备扫描到我的设备了。

    2.监听手机蓝牙是否被了另一个设备匹配。

    我第一次用的是这个方法

        private BroadcastReceiver stateChangeRec=new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action=intent.getAction();
                if(action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)){
                    tv_bluetooth_status.setText("蓝牙连接状态:连接成功");
                    Log.i("tang","连接成功");
                    //do something
                }else if(action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)){
                    tv_bluetooth_status.setText("蓝牙连接状态:连接失败");
                    Log.i("tang","连接失败");
                }
            }
        };

    我会发现,在另外一台设备向我请求匹配的时候,就已经执行ACTION_BOND_STATE_CHANGED这个操作了。然后第一反应是绝对这个方法不适合我的情况。立刻重新找方法,

    于是就得到了这个:

    private BroadcastReceiver stateChangeRec=new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action=intent.getAction();
                if(action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)){
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    if (device.getBondState() == BluetoothDevice.BOND_BONDING) {
                        Log.i("tang","正在配对");
                    } else if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                        Log.i("tang","完成配对");
                        tv_bluetooth_status.setText("蓝牙连接状态:连接成功");
                    } else if (device.getBondState() == BluetoothDevice.BOND_NONE) {
                        Log.i("tang","取消配对");
                    }
                }
              
            }
        };

    这个就是在两个设备已经匹配完成的一个完整步骤。老夫也是松了一口气。

    3.还有一个,那就是修改本机蓝牙设备的名字。网上都说的是setName("xx")就好。我好你个香蕉巴拉。。。

    bluetoothAdapter.enable();//设置蓝牙为可用
    
    bluetoothAdapter.setName(deviceName);//写入你想要设置的设备名字

    setName其实是发送了一个广播,我们还需要来进行接收处理,完成整个操作。(很多博主都没说啊,坑死个人啊!)

    这儿,我们需要发送一个改名字的广播!向全世界宣布,我的蓝牙我做主!

    IntentFilter mFilter = new IntentFilter(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
    mFilter.addAction(BluetoothAdapter.EXTRA_LOCAL_NAME);
    registerReceiver(mReceiver, mFilter);

    下面就是接受广播操作

    //蓝牙广播接收器。修改名字时会调用。
        private BroadcastReceiver mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                tv_current_name.setText("当前蓝牙名字:"+bluetoothAdapter.getName());
                String action = intent.getAction();
                if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)){
                    Toast.makeText(context,"成功", Toast.LENGTH_SHORT).show();
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    
                    Set<BluetoothDevice> devices = bluetoothAdapter.getBondedDevices();
                    for(int i=0; i<devices.size(); i++)
                    {
                        BluetoothDevice device1 = (BluetoothDevice) devices.iterator().next();
                        Log.i("tang","2-2蓝牙名字="+device1.getName());
                        //System.out.println(device1.getName());
                    }
                }
                else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                    Toast.makeText(context,"finished", Toast.LENGTH_SHORT).show();
                }
            }
        };

    这才是一个ojbk的操作。

    这里面还有一个坑,真的是没找到有博主说过这个问题。setName(“xxx”)这里面的值,是有限制的!

    广播发送的字节好像是限制早<=60个字节,所以setName的值不是无限的,(如果你要广播发送包含了名字)。60个字节,30个汉字,包含所发送的其他信息,setName的值,限制也是跟随你所发送的信息多少而决定的。

    当蓝牙名字>限制的个数的时候,广播发送会失败,ErrorCode=18或者1,对于BLE蓝牙的ErrorCode网上也没有人说,也搜索不到。我也不知道为啥。(有谁知道为啥蓝牙名字>5的时候广播开启会失败,且ErrorCode=18/1,麻烦留言告知一声,谢谢!)

    4.还有个误区。我在断开蓝牙的时候使用的是disconnet(),但是我的小伙伴用他的手机和我测试的时候说,蓝牙没有断开啊。我说不可能啊,我又添加了close,双保险,这下没问题了吧。我小伙伴依然说,蓝牙没断开啊,一看。他看的是“已配对设备”,我特么操着键盘给他扔过去。

    已配对,不代表蓝牙没断开,只是说明两个设备在下次连接的时候不需要再次配对了。大家测试的时候不要进入这个误区了。

    持续更新一波,我app已经做好。小伙伴说搜索不到,让我把设备变成从设备。我这个蓝牙小白,一脸蒙圈,然后又去百度。设备分为主设备和从设备。

    话不多说,到底如何把一个设备变成从设备呢。代码敬上:

    这是一个设置广播,打开广播的操作。

    private void sendOutSheBei() {
    
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                settings = new AdvertiseSettings.Builder()
                        .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY) //广播模式: 低功耗,平衡,低延迟
                        .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH) //发射功率级别: 极低,低,中,高
                        .setConnectable(true) //能否连接,广播分为可连接广播和不可连接广播
                        .build();
    
                //广播数据(必须,广播启动就会发送)
                advertiseData = new AdvertiseData.Builder()
                        .setIncludeDeviceName(true) //包含蓝牙名称
                        .setIncludeTxPowerLevel(true) //包含发射功率级别
                        .addManufacturerData(1, new byte[]{23, 33}) //设备厂商数据,自定义
                        .build();
                //扫描响应数据(可选,当客户端扫描时才发送)
                scanResponse = new AdvertiseData.Builder()
                        .addManufacturerData(2, new byte[]{66, 66}) //设备厂商数据,自定义
                        .addServiceUuid(new ParcelUuid(UUID_SERVICE)) //服务UUID
                        //      .addServiceData(new ParcelUuid(UUID_SERVICE), new byte[]{2}) //服务数据,自定义
                        .build();
                mBluetoothLeAdvertiser = bluetoothAdapter.getBluetoothLeAdvertiser();
            }
    
            mBluetoothLeAdvertiser.startAdvertising(settings, advertiseData, scanResponse, mAdvertiseCallback);
            if (mBluetoothLeAdvertiser == null) {
                Toast.makeText(this, "该设备不支持蓝牙低功耗从设备通讯", Toast.LENGTH_SHORT).show();
                this.finish();
                return;
            }
        }

    这里面有一点需要注意,.setIncludeDeviceName(true) //包含蓝牙名称  我开始以为这只是是否传递蓝牙名字的一个设置,我给它修改为.setIncludeDeviceName(false) ,别人就搜不到我的蓝牙了。你要是想让别人搜索到你的蓝牙,那你就老老实实的写为true。

    这上面的代码还不够,还需要一个监听器,监听我们的广播是不是打开了。

    // BLE广播Callback
        private AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
            @Override
            public void onStartSuccess(AdvertiseSettings settingsInEffect) {
                Log.i("tang","BLE广播开启成功");
            }
    
            @Override
            public void onStartFailure(int errorCode) {
                Log.i("tang","BLE广播开启失败,错误码"+errorCode);
            }
        };

    我们一定还想要和其他设备进行信息交互,哪里监听?第一段代码里面就有一个监听回调,好的,现在敬上回调监听代码:

     // BLE服务端Callback
        private BluetoothGattServerCallback mBluetoothGattServerCallback = new BluetoothGattServerCallback() {
            @Override
            public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
                Log.i("tang", "从设备连接状态="+String.format(status == 0 ? (newState == 2 ? "与[%s]连接成功" : "与[%s]连接断开") : ("与[%s]连接出错,错误码:" + status)));
    
                if(newState==2){
                    //连接成功
                    tv_bluetooth_status.setText("蓝牙连接状态:连接成功");
                    mHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            tv_bluetooth_status.setText("蓝牙连接状态:连接中断");
                            Toast.makeText(mContext, "蓝牙断开", Toast.LENGTH_SHORT).show();
                            mBluetoothLe.disconnect();
                            mBluetoothLe.close();
                        }
                    }, getPostTime(deviceTime));
                }else{
                    tv_bluetooth_status.setText("蓝牙连接状态:连接中断");
                }
            }
    
            @Override
            public void onServiceAdded(int status, BluetoothGattService service) {
                Log.i("tang", "从设备连接状态="+String.format(status == 0 ? "添加服务[%s]成功" : "添加服务[%s]失败,错误码:" + status, service.getUuid()));
            }
    
            @Override
            public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
                String response = "CHAR_" + (int) (Math.random() * 100); //模拟数据
                mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, response.getBytes());// 响应客户端
                Log.i("tang","客户端读取Characteristic[" + characteristic.getUuid() + "]:\n" + response);
            }
    
            @Override
            public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] requestBytes) {
                // 获取客户端发过来的数据
                String requestStr = new String(requestBytes);
                Log.i("tang","客户端写入Characteristic[" + characteristic.getUuid() + "]:\n" + requestStr);
            }
    
            @Override
            public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
                String response = "DESC_" + (int) (Math.random() * 100); //模拟数据
                mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, response.getBytes()); // 响应客户端
                Log.i("tang","客户端读取Descriptor[" + descriptor.getUuid() + "]:\n" + response);
            }
    
            @Override
            public void onDescriptorWriteRequest(final BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
                // 获取客户端发过来的数据
                String valueStr = Arrays.toString(value);
                mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);// 响应客户端
              
    
                // 简单模拟通知客户端Characteristic变化
                if (Arrays.toString(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE).equals(valueStr)) { //是否开启通知
                    final BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            for (int i = 0; i < 5; i++) {
                                SystemClock.sleep(3000);
                                String response = "CHAR_" + (int) (Math.random() * 100); //模拟数据
                                characteristic.setValue(response);
                                mBluetoothGattServer.notifyCharacteristicChanged(device, characteristic, false);
                                Log.i("tang","通知客户端改变Characteristic[" + characteristic.getUuid() + "]:\n" + response);
                                //logTv("通知客户端改变Characteristic[" + characteristic.getUuid() + "]:\n" + response);
                            }
                        }
                    }).start();
                }
            }
    
            @Override
            public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
                Log.i("tang",String.format("onExecuteWrite:%s,%s,%s,%s", device.getName(), device.getAddress(), requestId, execute));
    
            @Override
            public void onNotificationSent(BluetoothDevice device, int status) {
                Log.i("tang",String.format("onNotificationSent:%s,%s,%s", device.getName(), device.getAddress(), status));
            }
    
            @Override
            public void onMtuChanged(BluetoothDevice device, int mtu) {
                Log.i("tang",String.format("onMtuChanged:%s,%s,%s", device.getName(), device.getAddress(), mtu));
            }
    
        };

    我做完了这些事之后,我发现,还有坑。我每次修改蓝牙本机名字之后,前几次没啥事儿,小伙伴突然给我说,不行了。一下回到解放前的名字了。我思考啊,思考啊。。。我觉得应该是发送广播里面设置名字的锅,它发广播只有一次,但是名字早给我发出去了,那我之后设置的不是都是打水漂?但是我仍然没把这一点想通,但是时间不等人啊,压力驱使我死马当活马医啊。

    然后我就在每次修改名字的时候,发送一次广播,断开前一次的广播,重新发一次广播。很鸡肋,但是却有效,要是有小伙伴知道怎么处理,麻烦给我说一下。哎~但愿天堂没有bug。

    不多就是这样,我遇到的就是这些坑。

    展开全文
  • 且进入后蓝牙连接不到任何数据。 而iOS切换国家后,设备会清除掉,重新注册添加后蓝牙通讯正常。 期望(必填) Android行为和iOS一致,切换国家后,设备会清除掉,重新...
  • 连接蓝牙设备

    2013-09-06 17:28:05
    蓝牙SIG(特别兴趣组,由爱立信等厂商组成)成立的时候,其发起者...利用蓝牙手机之间传送图片不是什么新鲜事,现在做的是要连接Linux主机和蓝牙手机。 15.2.1 蓝牙技术概述 蓝牙最早由瑞典的爱立信公司提出,其

    当蓝牙SIG(特别兴趣组,由爱立信等厂商组成)成立的时候,其发起者曾经指出,当蓝牙能够被集成入单芯片之中、成本下降到5美元的时候,将得到极大地普及。而今,小小的一个五号电池大小的几十块人民币的东西就可以提供这个功能了,蓝牙也真的进入了我们的生活。利用蓝牙在手机之间传送图片不是什么新鲜事,现在做的是要连接Linux主机和蓝牙手机。

    15.2.1  蓝牙技术概述

    蓝牙最早由瑞典的爱立信公司提出,其名称源于古代瑞典的一位国王,因为总吃某种果品,把牙齿染成蓝色的,被称作蓝牙(bluetooth)。那时的瑞典统治整个北欧,盛极一时,同样有野心的爱立信于是使用这个名字来命名这个被他们寄予厚望的短距离互联技术。

    Bluetooth用于连接个人周边的外围设备,比如无线耳机、打印机、扫描仪、手机、计算机等等,在这些设备之间交换文件和数据,替代低速串行线的工作,常用用途如下。

    l     文件共享、传输。

    l     语音传输。

    l     远程打印。

    l     RS-232串行口线替代。

    因为Bluetooth的功能十分实用,有了它既不需要麻烦的手机数据线了,也不需要像红外数据传输一样需要将两个设备对准,因此一经提出,立刻有一种一呼百应的感觉,随着成本的下降,蓝牙的用途也越来越广(当然了,这个过程也并非一帆风顺,成本的下降用了很多年才完成),大量的中低端手机也开始装备上了这项技术,以其更丰富、完善的协议栈,略高的传输速率,以及相对于红外线来说摆脱了必须毫无障碍的束缚,几乎完全取代了原来商务手机上普遍装备的红外接口。

    蓝牙来到中国之初,在台湾地区注册商标的时候把“牙”替换成了更有东方美感的“芽”字,不过后来已经统一为了“牙”。蓝牙实际上并不是一种简单的协议,它的协议很复杂。

    l     从网络结构和组网方式讲,蓝牙在10米区域内形成一个网络,其中可以有1个主设备,7个从设备,一共8个激活的设备,当然休眠的设备还可以有很多。对于更多的设备,可以使用adhoc的方式互联,本书不对此话题做更深入的介绍。

    l     从应用来看,蓝牙支持语音通信和串行线模拟,并且通过Profile来支持各种周边智能设备的应用,比如耳机、打印机等等,并且定义了一套服务发现和调用机制。

    蓝牙最有意思的莫过于第2层互联和应用层的Profile了,至于底层的跳频新意不大。另外,虽然蓝牙使用的频率和微波炉烹饪的频率毫无二致,但发射功率还是很小的,与手机相比,这个功率微不足道。

    15.2.2  Linux下的蓝牙协议栈

    Linux下有若干个蓝牙协议栈的实现,目前生存状况比较健康的是bluez和affix,后者是Nokia支持的,前者则是目前蓝牙的Linux官方版本,集成在Linux内核之中,也就是说,如果用户有一个比较新的2.6内核,那么,多半已经支持蓝牙了,而如果还不支持的话,重新编译一下或直接使用官方内核也就可以了。

    不要误认为Linux的协议栈比不上Windows里面的,bluez协议栈支持的硬件设备远远多于Windows系统支持的。如果和作者一样只用Linux,那么,买了蓝牙适配器之后就可以使用蓝牙了。

    内核的协议栈支持主要包含以下几个部分。

    l     HCI。这个是最底层的了,称为Host Control Interface(主机控制接口)。之所以称为HCI是源于蓝牙的应用模式的。蓝牙是连接智能外设的无线接口,接口的一侧是设备,另一侧就是主机(Host)了,采用类似记法的还有USB、IEEE1394,所以,从设计初衷来看,这几个产品都是针对差不多的市场的,只是各有所长。一个蓝牙适配器是否能被驱动起来,就看HCI的支持性了。最常见的蓝牙适配器就是作者持有的这类USB接口的了,对于大部分标准的蓝牙设备,它的驱动模块是hci-usb,对于2.6内核,插入这个适配器,该模块就被自动加载了。

    l     在HCI之上是L2CAP(Logical Link Control and Adaptation Protocal,逻辑链路控制与适配层),这一层的功能承上启下,向上层提供异步数据传输的链路控制功能,所谓异步,就是不存在一个主时钟来同步所有传输的一种传输方式,通常用于数据的传输;与之相反,同步传输是完全与时钟同步的,通常用在诸如语音或是多媒体通话之中。此外,在蓝牙中,语音同步传输也是被支持的,bluez协议栈中的SCO就是支持同步模式的。

    l     L2CAP之上有两个协议被较广泛地使用:RFCOMM和BNEP。前者用于取代传统的串行口,包括串行口上的各种应用,比如,传真和拨号上网、打印机、文件图片等数据传输;后者则可以提供一个以太网接口,被用于计算机组网。对于手机和计算机之间,RFCOMM更常被用到,另一方面,计算机之间的组网则更常用更高速的无线局域网而不是蓝牙。

    截止到这里就是内核提供的几乎所有蓝牙协议栈了,不过,仅有这些,蓝牙还不足以为用户所用,只有有了用户态的协议栈和工具相配合才能使用蓝牙。

    15.2.3  用户空间中的蓝牙协议栈与相关工具

    下面介绍用户空间的实现部分。

    l     在最上层,蓝牙定义了很多的Profile,每个Profile对应着一种应用,比如打印、耳机(Headset)、文件传输、Fax/Modem拨号功能等。其中,文件交换对应着OBEX协议,这是一个基于蓝牙、红外(IrDA)、串口等介质的文件(对象)交换协议,这几种介质被列到一起一点也不会让人感到意外,毕竟前两个都是用来在某种意义上取代串口的。当然,有些Profile,比如一些人机交互设备(键盘鼠标之类的)的Profile是在内核中实现的。

    l     SDP为服务发现协议,这个协议可以认为和RFCOMM处于同一层次,因为它并不承载于RFCOMM之上,不过,这个协议却十分特殊而重要,通过它,才能识别出某一蓝牙设备提供了哪些服务(Profile),从而进一步使用。

    协议栈已经有了,使用蓝牙是非常简单的事情。

    l     找到蓝牙设备,这是HCI层负责的,使用bluez-utils包提供的hcitool来找到蓝牙设备。

    l     找到服务,RFCOMM是通过不同的频道(channel)来提供不同的Profile的,所以需要找到要用的服务在设备上的哪个频道上,这是通过同一个软件包里的sdptool来完成的,就是SDP,服务发现协议。

    l     连接恰当的服务并使用。

    蓝牙的特点就是如上所述的那些了,而用户态的工具所要完成的任务就是发现服务和使用服务了。

    1.启动HCI设备

    首先,用户需要启动hcid,让HCI层的通信可以进行。对于Debian用户来说,需要安装bluez-utils包,并启动hcid。如果已经运行了bluetooth服务,插入USB适配器后,hcid就已经在运行了,看看相关信息,见清单15.2。

    清单15.2  HCI接口信息

    1    inspiration :/ etc/ bluetooth # hciconfig -a

    hci 0:  Type : USB

    3            BD Address : 11:11:11:11:11:11 ACL MTU: 678:8 SCO MTU: 48:10

            UP RUNNING PSCAN ISCAN

    5            RX bytes :413 acl :0 sco :0 events :19 errors :0

            TX bytes :323 acl :0 sco :0 commands :19 errors :0

    7            Features : 0xbf 0xfe 0x8d 0x78 0x08 0x18 0x00 0x00

            Packet type : DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3

    9            Link policy : RSWITCH HOLD SNIFF PARK

            Link mode : MASTER

    11           Name : 'inspiration -0'

            Class : 0x3e 0100

    13           Service Classes : Networking , Rendering , Capturing , Object Transfer , Audio

            Device Class : Computer , Uncategorized

    15           HCI Ver : 1.2 (0x2) HCI Rev : 0x1fe LMP Ver : 1.2 (0x2) LMP Subver : 0x1fe

                 Manufacturer : Integrated System Solution Corp . (57)

    这个过程是自动的,当然也可以用hciconfig(8)来手工控制。hcid的配置文件位于/etc/bluetooth/hcid.conf,通常使用软件包附带的版本就可以了,如果希望不用每次连接都在计算机这里确认一次PIN码的话,可以设置其中的security字段为auto,这样,每次连接就会使用passkey设置的PIN码了。

    2.寻找蓝牙设备

    HCI已经启动了,现在就可以用它来寻找蓝牙设备了,当然,一定要先开启蓝牙设备的蓝牙功能,这个不是废话,手机的蓝牙是默认关闭的,只有在手动控制之下才会发送信号,允许被扫描到,不过设备的个体差异性太大,这里没法介绍,作者假设读者已经自己摸索或参照说明书打开了设备的蓝牙电源。寻找蓝牙设备如清单15.3所示。

    清单15.3  寻找蓝牙设备

    inspiration :/ home / gnawux # hcitool scan

    18   Scanning ...

            00:17:00:7 B :18: B8         Motorola SLVR

    之后蓝牙设备就会被顺利地找到,当然,前提是不要忘了打开手机的蓝牙开关,并允许被找,这个功能平时最好不要打开,以防在公共场合遇到安全问题。

    3.查看设备提供的服务

    利用SDP协议,用户还可以查看每个设备都有功能,能提供什么服务,每种基于RFCOMM的服务都使用某种协议,占据一个“频道(channel)”,这是使用蓝牙服务时的一个重要参数。

    下面是例子,先看看本机,见清单15.4。

    清单15.4  本机提供的蓝牙服务

    20   gnawux@inspiration :~$ sdptool browse local

    Browsing FF:FF:FF :00:00:00 ...

    22   Service Name : OBEX Object Push

    Service RecHandle : 0x10000

    24   Service Class ID List :

      " OBEX Object Push " (0x1105)

    26   Protocol Descriptor List :

      "L2CAP" (0x0100)

    28     "RFCOMM " (0x0003)

        Channel : 9

    30     " OBEX " (0x0008)

    Profile Descriptor List :

    32     " OBEX Object Push " (0x1105)

         Version : 0x0100

    然后可以看看关心的设备提供的服务,手机提供的服务种类比较多,首先是SDP服务器,也就是服务发现服务器,有了这个服务,就可以接下来发现其他服务功能了,见清单15.5。

    清单15.5  手机提供的SDP功能

    34   gnawux@inspiration :~$ sdptool browse 00:17:00:7 B :18: B8

    Browsing 00:17:00:7 B :18: B8 ...

    36   Service RecHandle : 0x0

    Service Class ID List :

    38    "SDP Server " (0x 1000)

    Protocol Descriptor List :

    40    "L2CAP" (0x 0100)

           "SDP" (0x 0001)

    42   Profile Descriptor List :

      "SDP Server " (0x 1000)

    44       Version : 0x 0100

    手机的最基本功能就是用于(电话或网络)拨号,这里列出的第一项服务也是“拨号网络网关”,标识服务具体类型的字段是“Service Class ID”,它所在的频道是RFCOMM的频道1,如清单15.6所示。

    清单15.6  手机提供的拨号网络功能

    Service Name : Dialup Networking Gateway

    46   Service Description : Dialup Networking Gateway

    Service Provider : Motorola

    48   Service RecHandle : 0x 10001

    Service Class ID List :

    50    " Dialup Networking " (0x 1103)

    Protocol Descriptor List :

    52    "L2CAP" (0x 0100)

           " RFCOMM " (0x 0003)

    54        Channel : 1

    Language Base Attr List :

    56    code _ ISO 639: 0x 656e

     encoding :     0x6a

    58    base _ offset : 0x 100

     code _ ISO 639: 0x7a68

    60    encoding :     0x6a

     base _ offset : 0xc 800

    62  Profile Descriptor List :

     " Dialup Networking " (0x 1103)

    64        Version : 0x 0100

    除了拨号网络服务的频道位置相对固定之外,其他服务在不同手机上的频道通常是不同的,手机一般支持的其他服务包括音频/耳机服务、车载免提服务、OBEX对象推送服务、OBEX文件传输服务以及图片推送服务等,利用这些服务,可以利用手机拨号上网或是与手机交换图片、音乐等文件。

    15.2.4  使用蓝牙

    首先介绍如何利用蓝牙取代手机数据线,以便进行拨号等工作。之后介绍利用蓝牙传送文件的几个用法,都是借助于前面提到的OBEX协议。

    1.用蓝牙代替串口

    大家知道,蓝牙的一个基本功能就是模仿串口,而串口的重要作用之一(可能是最重要的了)就是拨号,传统的DTE也就是Modem。实际上,通过RFCOMM,蓝牙连接可以反映在/dev/rfcomm0这样的字符设备上,像串口一样操作。当然,最好先定义/etc/bluetooth/ rfcomm.conf,里面根据手机的设备号和频道号写上相应设置,见清单15.7。

    清单15.7  rfcomm设置

    rfcomm 0 {

    66          # Automatically bind the device at startup

        bind yes ;

    68

            # Bluetooth address of the device

    70      device 00:17:00:7 B :18: B8;

    72          # RFCOMM channel for the connection

        channel 1;

    74

            # Description of the connection

    76      comment " Motorola SLVR L7";

    }

    这样,在启动bluetooth服务的时候,就已经自动连接上了,而不需要使用rfcomm(1)命令自己费力气了。现在,可以使用任意一个喜欢的串口程序(minicom、gtkterm等等)来对/dev/rfcomm0进行操作了,当然也可以使用pppd建立拨号网络。

    2.利用OBEX推送文件

    这是使用手机或计算机提供的“OBEX Object Push”(0x1105)服务,由另一方向其推送如文件。使用的工具是openobex-apps包里的obex test工具。首先是利用手机的Push服务向手机推送,对于本例中的手机,这是通过清单15.5所使用的sdptool命令得到的结果的一部分,清单15.8所示。

    清单15.8  手机提供的对象推送功能

    78   Service Name : OBEX Object Push

    Service Description : OBEX Object Push

    80   Service Provider : Motorola

    Service RecHandle : 0x 10008

    82   Service Class ID List :

            " OBEX Object Push " (0x 1105)

    84   Protocol Descriptor List :

            "L2CAP" (0x 0100)

    86      " RFCOMM " (0x 0003)

           Channel : 8

    88      " OBEX " (0x 0008)

    可以看到,推送服务位于频道8,现在,在obex_test的命令行里指定设备和频道,如清单15.9所示。

    清单15.9  向手机推送文件

    gnawux@inspiration :~$ obex _ test -b 00:17:00:7 B :18: B8 8

    90   Using Bluetooth RFCOMM transport

    OBEX Interactive test client / server .

    92  > c

    Connect OK!

    94   Version : 0x10. Flags : 0x00

    > p wangxu . jpg me. jpg

    96   PUT file (local , remote )> name = wangxu .jpg , size =34177

    Going to send 34177 bytes

    98   Made some progress ...

    Made some progress ...

    100  Made some progress ...

    Made some progress ...

    102  Made some progress ...

    PUT successful !

    104  > q

    执行完obex-test之后,进入一个交互状态,首先建立连接,然后传送文件(本地文件名是wangxu.jpg,存在手机上叫me.jpg(这个是随意取的),最后退出。这个过程需要看着手机屏幕,可能要确认是否连接,文件存放在哪里,这个和手机有关。

    现在也可以看看手机向计算机推送,首先应该让计算机进入接收状态,如果本地没有启动Object PUSH服务,可以利用sdptool把它加上,如清单15.10所示。

    清单15.10  给计算机加上Object Push服务

    gnawux@inspiration :~$ sdptool add OPUSH

    106  OBEX Object Push service registered

    现在进入接收状态,注意要使用计算机(local)的地址和频道号,这些信息可以通过清单15.4所示方法得到,见清单15.11。

    清单15.11  接收手机推送的文件

    gnawux@inspiration :~$ obex _ test -b FF:FF:FF :00:00:00 9

    108  Using Bluetooth RFCOMM transport

    OBEX Interactive test client / server .

    110  > s

    现在,计算机进入了接收模式,在手机侧发送文件到计算机就可以了。

    3.使用obexftp上传下载

    使用“OBEX File Transfer”(0x1106)服务的obexftp是一个方便的工具,利用它可以查看手机上的内容,并进行上传下载,对于本例,对应的频道是9。先来查看一下有哪些目录,见清单15.12。

    清单15.12  obexftp列目录清单

     gnawux@inspiration :~$ obexftp -b 00:17:00:7 B :18: B8 -B 9 -l

    112  Browsing 00:17:00:7 B :18: B8 ...

     Channel : 9

    114  Connecting ... done

     Receiving "( null )"...| <? xml version ="1.0" ?>

    116   <! DOCTYPE folder - listing SYSTEM "obex - folder - listing . dtd">

     <folder - listing >

    118   <parent - folder />

     <folder name =" audio " size ="0" type =" folder " modified ="20060805 T 144844 Z" user

     - perm =" RW" />

    <!--[if !supportLists]-->120        <!--[endif]--><folder name =" video " size ="0" type =" folder " modified ="20060805 T 144844 Z"

          user - perm =" RW" />

     <folder name =" picture " size ="0" type =" folder " modified ="20060805 T 144844 Z"

     user - perm =" RW" />

    <!--[if !supportLists]-->121        <!--[endif]--><folder name =" MMC( Removable )" size ="0" type =" folder " modified ="19700101 T

          000000 Z"      user - perm =" RW"

    124    </folder - listing >done

      Disconnecting ... done

    可以看到,有4个有读写(RW)权限的目录,再看看audio里面有什么,见清单15.13。

    清单15.13  obexftp查看audio目录

    126  gnawux@inspiration :~$ obexftp -b 00:17:00:7 B :18: B8 -B 9 -l audio

     Browsing 00:17:00:7 B :18: B8 ...

    128   Channel : 9

     Connecting ... done

    130   Receiving " audio "...| <? xml version ="1.0" ?>

     <! DOCTYPE folder - listing SYSTEM "obex - folder - listing . dtd">

    132   <folder - listing >

     <parent - folder />

    <!--[if !supportLists]-->134       <!--[endif]--><file name ="a.mp 3" size ="977920" type =" audio /mp 3" modified ="20060805 T 145050

           Z" user   - perm =" RW"

    136   </folder - listing >done

     Disconnecting ... done

    可以看到,这里有一个MP3文件,把它取下来,如清单15.14所示。

    清单15.14  obexftp下载

    138   gnawux@inspiration :~$ obexftp -b 00:17:00:7 B :18: B8 -B 9 -c audio -g a.mp3

     Browsing 00:17:00:7 B :18: B8 ...

    140   Channel : 9

     Connecting ... done

    142   Sending " audio "... done

     Receiving "a.mp3"... - done

    144   Disconnecting ... done

    经过一段漫长的等待,传送终于完成了。再把wangxu.jpg放到picture目录去,如清单15.15所示。

    清单15.15  obexftp下载

    gnawux@inspiration :~$ obexftp -b 00:17:00:7 B :18: B8 -B 9 -c picture -p wangxu .jpg

    146  Browsing 00:17:00:7 B :18: B8 ...

    Channel : 9

    148  Connecting ... done

    Sending " picture "... done

    150  Sending " wangxu .jpg ".../ done

    Disconnecting ... done

    这些就是obexftp的基本用法,更复杂的用法可以参考它的手册页obexftp(1)。此外,还有obexserver、qobex(基于QT的图形化界面工具)等工具,此处不一一介绍。
    展开全文
  • 然而最近有网友在操作时却遇到了蓝牙连接不上的情况,很影响自己的使用,我们该怎么办呢?今天小编就来教大家关于苹果蓝牙连接不上的处理方法。处理方法如下:一、苹果 iphone7蓝牙连不上,可以试试iPhone 连接...

    在使用苹果7手机时我们会经常用到蓝牙设备:例如蓝牙音响,蓝牙耳机等。然而最近有网友在操作时却遇到了蓝牙连接不上的情况,很影响自己的使用,我们该怎么办呢?今天小编就来教大家关于苹果蓝牙连接不上的处理方法。

    处理方法如下:

    一、苹果 iphone7蓝牙连不上,可以试试iPhone 连接到其他的设备,看看它是否正常工作。如果你发现,问题真的出现在 iPhone 身上,可以试试以下操作:

    (1)关闭蓝牙,然后重启 iPhone,然后重新开启蓝牙。

    (2)如果设备还是无法连接,我们可以试着将已经配对的设备忘记。然后重新连接。

    (3)尝试着重置网络设置。这样做会使得 wifi 设置也被清除,我们需要重新加入 WiFi 网络。

    (4)将 iPhone 恢复出厂设置,或者更新至最新的 iOS 版本。(注意:但是恢复出厂设置和更新有风险,请谨慎操作。)

    二、苹果手机连接蓝牙的具体步骤如下:

    1、点击手机桌面上的设置。

    e1cee0f6f14b2e31ea5aa4df7d4dade2.png

    2、点击设置中的蓝牙。

    c19989042744c39a87450ee2e2fdb56d.png

    3、打开蓝牙。

    ef2f4ca976ee6bf94cf2676dc5596314.png

    4、把蓝牙设备放在手机可搜索范围内。

    6f833008a2c267ab672afd5e0d011e2f.png

    5、手机搜索到蓝牙设备。

    f567008f4e51b6997b1d578a8b993d63.png

    6、点击蓝牙设备的名称,连接即可。

    f59f89f4db1069cdd4b333b515f361f0.png

    苹果蓝牙连接不上的处理方法就为大家分享到这里啦,有遇到同样情况的可以参考上面的方法来解决哦。

    展开全文
  • 连接蓝牙设备

    千次阅读 2011-01-08 18:26:00
    利用蓝牙手机之间传送图片不是什么新鲜事,现在做的是要连接Linux主机和蓝牙手机。 15.2.1 蓝牙技术概述 蓝牙最早由瑞典的爱立信公司提出,其名称源于古代瑞典的一位国王,因为总吃某种果品,把牙齿染...
  • 15.2 连接蓝牙设备

    2017-06-15 13:35:00
    蓝牙SIG(特别兴趣组,由爱立信等厂商组成)成立的时候,其发起...利用蓝牙手机之间传送图片不是什么新鲜事,现在做的是要连接Linux主机和蓝牙手机。 15.2.1蓝牙技术概述 蓝牙最早由瑞典的爱立信公司提出,其...
  • 最近入手了一台Redmi小爱同学触屏版8Pro,发现正常连接手机蓝牙是可以播放音乐的,但是连接电脑后虽然提示连接成功,但是能播放音乐,在选择播放设备处没有显示该设备,如下图是正常的状态 (正常的样子) ...
  • Android手机连接蓝牙设备后,能通过搜索再次搜,网上各种方法试了均无效,反射机制也用了没啥用,哪位大神可以帮忙
  •  二、添加设备,打开“控制面板--设备与打印机--添加设备”此时你的蓝牙设备要打开蓝牙开关并处于可发现状态,此时在“添加设备”对话框,可以看到已搜索蓝牙设备,选择它并点击“下一步”。 三、在弹出的框中...
  • 微信小程序连接蓝牙设备

    千次阅读 2018-11-08 15:13:44
    部分oppo和vivo手机要把定位也打开,否则搜索不到附近蓝牙设备(比如我坑爹的oppoR11就必须把定位和蓝牙都打开才行) 下面直接上代码,复制粘贴就行,然后点击“开始扫描”(目前我知道苹果手表是低功耗设备,大家...
  • Android蓝牙API提供的方法中,isconnected(),基本做不到实时检测连接状态,其他的方法,等到的也是设备绑定的状态,并不是我想要的。本来通过写或读数据是可以判断连接状态的,但是,自己起线程轮询的收发数据...
  • 出现的情况是:手机蓝牙与蓝牙设备连接几次,交互信息后,无法再次连接与搜索服务,需重启手机蓝牙或者关闭APP后,再次启动APP,才能再次连接设备。 上网查找了不少资料。才找资料。非常感谢此博文提供的参考...
  • 本身手机系统,在设置界面就可以完成这一系列的动作,而我们的需求是在自己开发的APP上面需要经过打开,扫描,连接等动作,就可以获取目前系统的蓝牙连接状态? 我这个经验的限制在于必须指定一个具体的profile...
  • 蓝牙开发的时候,扫描外设的方法扫描到的设备只能是没有被连接...方法扫描到,一开始的手自己也没有注意到这个问题,结果在老板使用的工程中,老是出现系统已经连接蓝牙设备了,然后就找不到设备了的情况,无奈,是
  • 现在的FlutterBlue在安卓手机上很难搜索连接,在iOS上是没问题的,进行下列更改可以快速修复这个问题,但是会损失掉一些功能,能通过指定Service的UUID搜索到设备(因为uuids数组被改成了[])。 懒人可以直接用我...
  • 好几天手机上耳机,通过不同方法尝试后,终于通过一下步骤成功连接。 1、关上蓝牙耳机,给耳机冲几分钟电; 2、iPhone 蓝牙界面,打开蓝牙,点感叹号,进入后忽略此设备(之前配对蓝牙耳机); 3、关上手机上的...
  • NSUUID *uuid = [[NSUUID alloc]initWithUUIDString:@"F0010001-0451-4000-B000-000000000000"]; NSArray *bleArray = [NSArray ... 我用上边的方法获取设备可是就是连接不起来,请高手帮忙回答一下
  • (1)设备不支持蓝牙4.0及以上协议 (2)设备已经被另一个主机设备连接上了 (3)设备已经被另一个主机设备绑定上了 (4)没有打开蓝牙功能/支持蓝牙功能/驱动有问题 (5)没有授权App使用蓝牙/没有授权App使用...
  • loock.lock.v14就是v9改了pid 连接不蓝牙一直是-1 有可能是什么原因? 期望(必填) 可以正常连接蓝牙 其他的上下文/日志/截图</strong></p> <p><a href=...
  • //设置扫描到设备的委托 [baby setBlockOnDiscoverToPeripherals:^(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) { NSLog(@"搜索到了设备:%...
  • 蓝牙耳机 已连接 但就是找不到[【掉落在某个角落找不到】解决方式 以安卓手机为例【苹果手机除外】 首先 手机连接耳机 将音量跳到最大 去找【如果实在找不到 看第二点必杀技】 手机下载 蓝牙信号强度检测app 下载...
  • 最近刚入手小爱同学,想尝试一下小米的其他蓝牙设备是否可以连接到小爱同学,用小爱同学查询或者控制小米设备。 1、用到的设备有: 小爱触屏印象,米家蓝牙温湿度计2。设备图片如下。 2、连接步骤 此处小米...
  • 代码中解除手机已配对的蓝牙设备

    千次阅读 2016-10-19 11:09:12
    这几天被一个问题困扰了很久,就是app里面连接蓝牙设备之后解绑断开,蓝牙回调也显示了断开,但是自己再去搜就搜不到了。找了很久原因发现在手机设置的蓝牙配对列表中发现该设备已被配对,导致手机不到。然后就...
  • 蓝牙设备

    2015-11-25 14:57:57
     在开始前我们需要准备好一部手机而不是模拟器,且手机已经打开调试模式并连接到电脑上。文中的本地设备均指我们自己的手机,而远程设备则是指其他的设备(电脑、其他手机或者其他)。  通常情况下,我们对蓝牙的...

空空如也

空空如也

1 2 3 4 5 ... 14
收藏数 270
精华内容 108
关键字:

手机蓝牙连接不到设备