简体   繁体   English

Android低功耗蓝牙:从外围设备切换到中央设备

[英]Android Bluetooth Low Energy: Switching from Peripheral To Central

I think I'm hitting against a wall here. 我想我在这里撞墙。 I have two devices: a Mediatek Desire Plus running Android 6.0 and another, an ASUS X008DC running Android 6.0. 我有两个设备:运行Android 6.0的Mediatek Desire Plus和运行Android 6.0的ASUS X008DC。 On one device I run a ReaderActivity and on the other (the ASUS) I run a WriterActivity. 在一台设备上,我运行ReaderActivity,在另一台设备上(ASUS),我运行WriterActivity。 The ReaderActivity is supposed to do the following: ReaderActivity应该执行以下操作:

  1. Scan for Peripheral devices with a specific service UUID, UUID_1 扫描具有特定服务UUID UUID_1的外围设备
  2. Connect to the device, stop scanning, and start reading characteristics provided in the service description one after the other. 依次连接至设备,停止扫描并开始阅读服务说明中提供的特征。
  3. After reading ALL the characteristics, start as a Peripheral and advertise a service with UUID, UUID_2. 读取所有特征后,以外围设备开始并使用UUID UUID_2通告服务。

The WriterActivity is supposed to do the reverse of the ReaderActivity: WriterActivity应该与ReaderActivity相反:

  1. Advertise a given service with UUID, UUID_1 使用UUID_1来发布给定的服务
  2. When connected to a central, stop advertising and start serving characteristics one after the other (mostly in chunks on 20 bytes each) 当连接到中央服务器时,停止发布广告并一个接一个地开始提供特征(主要是在每个20字节的块中)
  3. After serving ALL the characteristics, stop (close) the GATT Server and start as Central looking for a service with UUID, UUID_2. 提供所有特征后,停止(关闭)GATT服务器并以Central身份启动,以查找带有UUID UUID_2的服务。

The problem: everything works FINE on both devices UNTIL point 2. After switching roles, both devices DON'T see each other, in other words, the onScanResult of the WriterActivity IS NEVER CALLED. 问题是:在两个设备上,一切正常,直到第2点为止。在切换角色之后,两个设备都看不到对方,换句话说,永远不会调用WriterActivity的onScanResult。

I have tried ALMOST everything: from rebooting bluetooth (using an asynchronous BroadcastReceiver), to interrupting the scanning/advertising on both devices for a given idle period, to stopping the WIFI connection, to ... 我已经尝试了ALMOST的所有方法:从重新启动蓝牙(使用异步的BroadcastReceiver),到在给定的空闲时间中断两个设备的扫描/广告,再到停止WIFI连接,...

I'm at THIS to give up on BLE and go back to standard Bluetooth. 我在此放弃BLE,回到标准蓝牙。 It's probably not a stable technology yet. 这可能还不是稳定的技术。 What am I missing here? 我在这里想念什么? Thanks in advance for your time. 在此先感谢您的时间。

EDIT 1: I have installed the "BLE Central,Peripheral Checker" from Play Store on both devices and it indicates that BOTH devices support BT classic, Central and Peripheral. 编辑1:我在两个设备上都从Play商店安装了“ BLE Central,Peripheral Checker”,这表明两个设备都支持BT classic,Central和Peripheral。

The error was that one device, the MediaTek Desire, didn't require Android 23 permission request, while the other the ASUS, was more strict and required it to allow the scanning of BLE devices. 错误是,一台设备联发科技Desire不需要Android 23许可请求,而另一台ASUS更加严格,并要求它允许扫描BLE设备。 Here is the function, called inside the onCreate method, that fixed the issue for good: 这是在onCreate方法内部调用的函数,可以永久解决此问题:

private void checkNetworkLocation() {
    try {
        boolean gps_enabled = false, network_enabled = false;
        LocationManager localLocationManager =
                (LocationManager) getSystemService(LOCATION_SERVICE);;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if ((checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
                    || (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
                throw new Exception();
            }
        }
        try {
            gps_enabled = localLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        } catch(Exception ex) {}

        try {
            network_enabled = localLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch(Exception ex) {}

        if(!gps_enabled && !network_enabled) {
            new AlertDialog.Builder(this).setMessage("Location service is disabled, please enable it to find BLE devices.").setCancelable(false).setNeutralButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt) {
                    DeviceScanActivity.this.startActivityForResult(new Intent("android.settings.LOCATION_SOURCE_SETTINGS"), 0);
                }
            }).show();
        }
        return;
    } catch (Exception e) {
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM