【问题标题】:Im having trouble reading BLE Advertisements in my android app我无法在我的 android 应用程序中阅读 BLE 广告
【发布时间】:2018-09-14 11:40:33
【问题描述】:

我正在学习本教程: https://code.tutsplus.com/tutorials/how-to-advertise-android-as-a-bluetooth-le-peripheral--cms-25426

遇到了一些错误,但大部分已修复。这是我的代码:

public class MainActivity extends AppCompatActivity {
    Button btnDiscover,btnAdvertise;
    TextView tv;
    private BluetoothLeScanner mBluetoothLeScanner;
    private Handler mHandler = new Handler();
    int rssi;

    private static final int PERMISSION_REQUEST_COARSE_LOCATION = 456;

    private ScanCallback mScanCallBack =new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            if(result==null
                    || result.getDevice()==null
                    || TextUtils.isEmpty(result.getDevice().getName())){
                return;                                                                 //Do Nothing
            }

            StringBuilder builder =new StringBuilder(result.getDevice().getName());     //Get RSSI Available
            StringBuilder builder1 = new StringBuilder(result.getRssi());
            builder.append("\n").append(new String(result.getScanRecord().getServiceData(result.getScanRecord().getServiceUuids().get(0)),Charset.forName("UTF-8")));

            tv.setText(builder.toString());

        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            super.onBatchScanResults(results);
        }

        @Override
        public void onScanFailed(int errorCode) {
            Log.e("BLE","Discovery onScanFailed: "+errorCode);
            super.onScanFailed(errorCode);
        }
    };
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_COARSE_LOCATION: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // Permission granted, yay! Start the Bluetooth device scan.
                } else {
                    tv.setText("Buttons Disabled");

                    btnDiscover.setEnabled( false );
                    btnAdvertise.setEnabled( false );
                    // Alert the user that this application requires the location permission to perform the scan.
                }
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnAdvertise=(Button)findViewById(R.id.btnAdvertise);
        btnDiscover=(Button)findViewById(R.id.btnDiscover);
        tv=(TextView) findViewById(R.id.textView);

        mBluetoothLeScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();

        implementListeners();


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
        }


        if( !BluetoothAdapter.getDefaultAdapter().isMultipleAdvertisementSupported() ) {
            Toast.makeText( this,
                    "Multiple advertisement not supported",
                    Toast.LENGTH_SHORT )
                    .show();
            tv.setText("Buttons Disabled");

            btnDiscover.setEnabled( false );
            btnAdvertise.setEnabled( false );
        }


    }

    private void implementListeners() {
        btnDiscover.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                discover();
            }
        });

        btnAdvertise.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                advertise();
            }
        });

    }

    private void advertise() {
        BluetoothLeAdvertiser advertiser =BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
        AdvertiseSettings settings = new AdvertiseSettings.Builder()
                .setAdvertiseMode( AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY )       //Low Latency
                .setTxPowerLevel( AdvertiseSettings.ADVERTISE_TX_POWER_HIGH )           //High Transmission
                .setConnectable( false )                                                //Dont Connect
                .build();

        ParcelUuid pUuid =new ParcelUuid(UUID.fromString(getString(R.string.ble_uuid)));

        AdvertiseData data = new AdvertiseData.Builder()
                .setIncludeDeviceName(false)
                .addServiceUuid(pUuid)
                .setIncludeTxPowerLevel(true)
                .addServiceData(pUuid,"Data".getBytes(Charset.forName("UTF-8")))
                .build();

        tv.setText(String.valueOf(data));

        AdvertiseCallback advertiseCallback=new AdvertiseCallback() {
            @Override
            public void onStartSuccess(AdvertiseSettings settingsInEffect) {
                Log.d("BLE","Started Advertising");
                super.onStartSuccess(settingsInEffect);
            }

            @Override
            public void onStartFailure(int errorCode) {
                Log.e("BLE","Advertising onStartFailure: "+errorCode);
                super.onStartFailure(errorCode);

            }
        };

        advertiser.startAdvertising(settings,data,advertiseCallback);


    }
    private void discover() {
        List<ScanFilter> filters = new ArrayList<ScanFilter>();


        ScanFilter filter = new ScanFilter.Builder()
                .setServiceUuid(new ParcelUuid(UUID.fromString(getString(R.string.ble_uuid))))
                .build();
        filters.add(filter);

        ScanSettings settings= new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .build();

        mBluetoothLeScanner.startScan(filters,settings,mScanCallBack);
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mBluetoothLeScanner.stopScan(mScanCallBack);
            }
        }, 10000);
    }
}

我稍微修改了一下。具体来说,我添加了位置权限。

我认为广告部分正在发挥作用。当我做广告时,Log cat 将其显示为输出:

09-14 17:06:02.516 23178-23178/adarshml.bleatherizer D/BluetoothAdapter: STATE_ON
09-14 17:06:02.521 23178-23190/adarshml.bleatherizer D/BluetoothLeAdvertiser: onClientRegistered() - status=0 clientIf=7
09-14 17:06:02.551 23178-23178/adarshml.bleatherizer D/BLE: Started Advertising

虽然发现这是 logcat:

09-14 17:08:03.519 23859-23859/adarshml.bleatherizer D/BluetoothAdapter: STATE_ON
09-14 17:08:03.524 23859-23871/adarshml.bleatherizer D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=6
09-14 17:08:06.851 23859-23859/adarshml.bleatherizer D/BluetoothAdapter: STATE_ON
09-14 17:08:13.538 23859-23859/adarshml.bleatherizer D/BluetoothAdapter: STATE_ON
09-14 17:08:13.538 23859-23859/adarshml.bleatherizer D/BluetoothLeScanner: could not find callback wrapper

我真的不知道我哪里出错了。我只需要从设备 1 到设备 2 的 BLE 广告

================================================ ================== 编辑: 经过更多研究,我意识到这不是进行该项目的正确方法。即使我不知道我做错了什么,我现在正在使用 AltBeacon Android 库。它也是开源行业标准。 到目前为止,新项目正在顺利起飞

https://altbeacon.github.io/android-beacon-library/

【问题讨论】:

  • 您的手机/平板电脑设置中的“定位服务”是打开还是关闭?只需要权限是不够的。
  • @Emil 是的。位置信息已开启
  • 您确定服务 uuid 正确吗?您能否确认该设备正在使用其他应用(如 lightblue)进行广告宣传?
  • @Zafrani 是的,UUID 是正确的。该设备正在投放广告。

标签: android bluetooth bluetooth-lowenergy


【解决方案1】:

经过更多研究,我意识到这不是开展该项目的正确方法。尽管我不知道自己做错了什么,但我现在正在使用 AltBeacon Android 库。它也是开源行业标准。新项目正在运行,并且顺利起飞。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多