【发布时间】: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 库。它也是开源行业标准。 到目前为止,新项目正在顺利起飞
【问题讨论】:
-
您的手机/平板电脑设置中的“定位服务”是打开还是关闭?只需要权限是不够的。
-
@Emil 是的。位置信息已开启
-
您确定服务 uuid 正确吗?您能否确认该设备正在使用其他应用(如 lightblue)进行广告宣传?
-
@Zafrani 是的,UUID 是正确的。该设备正在投放广告。
标签: android bluetooth bluetooth-lowenergy