Я следую этому уроку:
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
Я действительно не уверен, где я иду не так. Мне просто нужна реклама BLE с устройства 1 на устройство 2
=============================================== =================
Редактировать:
После дополнительных исследований я понял, что это неправильный путь к проекту. Несмотря на то, что я не знаю, что я сделал неправильно, я сейчас работаю с библиотекой AltBeacon Android. Это также отраслевой стандарт с открытым исходным кодом.
Новый проект работает без сбоев до сих пор
https://altbeacon.github.io/android-beacon-library/