package cn.com.heaton.blelibrary.ble.request; import android.annotation.TargetApi; import android.bluetooth.BluetoothAdapter; import android.bluetooth.le.AdvertiseCallback; import android.bluetooth.le.AdvertiseData; import android.bluetooth.le.AdvertiseSettings; import android.bluetooth.le.BluetoothLeAdvertiser; import android.os.Build; import android.os.Handler; import android.support.annotation.RequiresApi; import cn.com.heaton.blelibrary.ble.BleLog; import cn.com.heaton.blelibrary.ble.model.BleDevice; import cn.com.heaton.blelibrary.ble.BleHandler; import cn.com.heaton.blelibrary.ble.utils.ThreadUtils; import cn.com.heaton.blelibrary.ble.annotation.Implement; import cn.com.heaton.blelibrary.ble.exception.AdvertiserUnsupportException; /** * TODO 2020/02/01 * description $desc$ * created by jerry on 2019/02/21. */ @Implement(AdvertiserRequest.class) @TargetApi(Build.VERSION_CODES.LOLLIPOP) public class AdvertiserRequest<T extends BleDevice> { private static final String TAG = "AdvertiserRequest"; private Handler mHandler = BleHandler.of(); private BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); private BluetoothLeAdvertiser mAdvertiser; private AdvertiseSettings myAdvertiseSettings; private AdvertiseData myAdvertiseData; private void setAdvertiserSettings(){ mAdvertiser = bluetoothAdapter.getBluetoothLeAdvertiser(); if (mAdvertiser == null) { try { throw new AdvertiserUnsupportException("Device does not support Avertise!"); } catch (AdvertiserUnsupportException e) { e.printStackTrace(); } } //设置频率: ADVERTISE_MODE_LOW_LATENCY 100ms ADVERTISE_MODE_LOW_POWER 1s ADVERTISE_MODE_BALANCED 250ms myAdvertiseSettings = new AdvertiseSettings.Builder() .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)//设置广播间隔100ms .setConnectable(true) .setTimeout(0) .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH) .build(); } public void startAdvertising(final byte[] payload, final AdvertiseSettings advertiseSettings){ if (bluetoothAdapter.isEnabled()){ mHandler.removeCallbacks(stopAvertiseRunnable); if(mAdvertiser != null){ ThreadUtils.asyn(new Runnable() { @Override public void run() { mAdvertiser.stopAdvertising(mAdvertiseCallback); myAdvertiseData = new AdvertiseData.Builder() .addManufacturerData(65520, payload) .setIncludeDeviceName(true) .build(); mAdvertiser.startAdvertising(advertiseSettings, myAdvertiseData, mAdvertiseCallback); } }); } } } public void startAdvertising(byte[] payload) { setAdvertiserSettings(); startAdvertising(payload, myAdvertiseSettings); } public void stopAdvertising() { if (bluetoothAdapter.isEnabled()){ if(mAdvertiser != null){ ThreadUtils.asyn(new Runnable() { @Override public void run() { BleLog.d(TAG, "stopAdvertising: 停止广播"); mAdvertiser.stopAdvertising(mAdvertiseCallback); } }); } } } public void stopAdvertising(Long delay){ mHandler.postDelayed(stopAvertiseRunnable, delay); } private Runnable stopAvertiseRunnable = new Runnable() { @Override public void run() { stopAdvertising(); } }; @TargetApi(Build.VERSION_CODES.LOLLIPOP) private AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() { @Override public void onStartSuccess(AdvertiseSettings settingsInEffect) { super.onStartSuccess(settingsInEffect); BleLog.d(TAG, "onStartSuccess: 开启广播成功"); } @Override public void onStartFailure(int errorCode) { super.onStartFailure(errorCode); if (errorCode == ADVERTISE_FAILED_DATA_TOO_LARGE) { BleLog.e(TAG, "Failed to start advertising as the advertise data to be broadcasted is larger than 31 bytes."); } else if (errorCode == ADVERTISE_FAILED_TOO_MANY_ADVERTISERS) { BleLog.e(TAG, "Failed to start advertising because no advertising instance is available."); } else if (errorCode == ADVERTISE_FAILED_ALREADY_STARTED) { BleLog.e(TAG, "Failed to start advertising as the advertising is already started"); } else if (errorCode == ADVERTISE_FAILED_INTERNAL_ERROR) { BleLog.e(TAG, "Operation failed due to an internal error"); } else if (errorCode == ADVERTISE_FAILED_FEATURE_UNSUPPORTED) { BleLog.e(TAG, "This feature is not supported on this platform"); } } }; }