我开发了一个管理连接BLE的应用程序,所有这些都由一个活动控制。 但今天,我会在我的应用程序中添加活动和片段。
所以,我有一个对象(根据Android开发人员的BLE教程),名为BluetoothLeService
并管理连接等...
我需要在所有活动/片段中重用这个对象,而不重复登录过程..
最好的方法是什么? 谢谢
答案 0 :(得分:1)
我有一个前台活动(有几个碎片)和一个后台服务。
活动(运行应用程序时)按Lars Vogel tutorial。
中所述连接到服务服务始终运行(也在Android设备启动时启动)并使用此单例类进行BLE操作:
public class BleObject {
private static BleObject sInstance;
private Context mContext;
private HashSet<BleListener> mListeners = new HashSet<BleListener>();
private Handler mRssiReader;
private int mRssiInt = CommonConstants.RSSI_INT_DEFAULT;
private int mAverage = CommonConstants.AVERAGE_DEFAULT;
private ArrayList<Integer> mRssiValues = new ArrayList<Integer>();
private BluetoothAdapter mBluetoothAdapter;
private BluetoothGatt mBluetoothGatt;
private BluetoothGattService mLinkLossService;
private BluetoothGattService mTxPowerService;
private BluetoothGattService mImmediateAlertService;
private BluetoothGattCharacteristic mImmediateAlertChar;
public interface BleListener {
public void deviceFound(BluetoothDevice device, int rssi);
public void updateRssi(BluetoothDevice device, int rssi);
public void servicesReady();
public void deviceGone();
public void setState(String str);
}
public static BleObject getInstance(Context context) {
if (sInstance == null)
sInstance = new BleObject(context);
return sInstance;
}
private BleObject(Context context) {
mContext = context;
mRssiReader = new Handler();
}
public void addListener(BleListener listener) {
mListeners.add(listener);
}
public void removeListener(BleListener listener) {
mListeners.remove(listener);
}
// this method should always be called before using BleObject
public boolean init() {
BluetoothManager bluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter == null)
return false;
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
}
public boolean isEnabled() {
return mBluetoothAdapter.isEnabled();
}
private BluetoothAdapter.LeScanCallback mScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
if (device == null)
return;
String address = device.getAddress();
if (!BluetoothAdapter.checkBluetoothAddress(address))
return;
for (BleListener listener: mListeners) {
listener.deviceFound(device, rssi);
}
}
};
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
CommonConstants.logd("onConnectionStateChange STATE_CONNECTED: " + gatt.getDevice().getAddress());
gatt.discoverServices();
readPeriodicalyRssi();
if (gatt != null && gatt.getDevice() != null) {
for (BleListener listener: mListeners) {
listener.setState(mContext.getString(R.string.connected_to) + gatt.getDevice().getAddress());
}
}
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
CommonConstants.logd("onConnectionStateChange STATE_DISCONNECTED");
disconnect();
for (BleListener listener: mListeners) {
listener.setState(mContext.getString(R.string.not_connected));
}
}
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
if (status != BluetoothGatt.GATT_SUCCESS)
return;
if (gatt == null)
return;
BluetoothDevice device = gatt.getDevice();
if (device == null)
return;
//CommonConstants.logd("onReadRemoteRssi: " + rssi);
// add new value and trim the list if needed
mRssiValues.add(rssi);
while(mRssiValues.size() > mAverage)
mRssiValues.remove(0);
// calculate average value over the list
Integer average = 0;
for (Integer rssiValue: mRssiValues) {
average += rssiValue;
}
average /= mRssiValues.size();
for (BleListener listener: mListeners) {
listener.updateRssi(device, average);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic ch, int status) {
if (gatt == null)
return;
BluetoothDevice device = gatt.getDevice();
if (device == null)
return;
CommonConstants.logd("onCharacteristicRead: " + device + ", status: " + status);
if (status == BluetoothGatt.GATT_SUCCESS) {
CommonConstants.logd("onCharacteristicRead: " + ch);
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic ch, int status) {
if (gatt == null)
return;
BluetoothDevice device = gatt.getDevice();
if (device == null)
return;
CommonConstants.logd("onCharacteristicWrite: " + device + ", status: " + status);
if (status == BluetoothGatt.GATT_SUCCESS) {
CommonConstants.logd("onCharacteristicWrite: " + ch);
}
};
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (gatt == null)
return;
BluetoothDevice device = gatt.getDevice();
if (device == null)
return;
CommonConstants.logd("onServicesDiscovered: " + device + ", status: " + status);
if (status != BluetoothGatt.GATT_SUCCESS) {
CommonConstants.loge("Can not retrieve services from " + device.getAddress());
disconnect();
return;
}
mImmediateAlertService = gatt.getService(CommonConstants.IMMEDIATE_ALERT_SERVICE);
mLinkLossService = gatt.getService(CommonConstants.LINK_LOSS_SERVICE);
mTxPowerService = gatt.getService(CommonConstants.TX_POWER_SERVICE);
if (mImmediateAlertService == null) {
CommonConstants.loge("Can not retrieve IMMEDIATE_ALERT service from " + device.getAddress());
disconnect();
return;
}
if (mLinkLossService == null) {
CommonConstants.loge("Can not retrieve LINK_LOSS service from " + device.getAddress());
disconnect();
return;
}
if (mTxPowerService == null) {
CommonConstants.loge("Can not retrieve TX_POWER service from " + device.getAddress());
disconnect();
return;
}
mImmediateAlertChar = new BluetoothGattCharacteristic(CommonConstants.ALERT_LEVEL,
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE,
BluetoothGattCharacteristic.PERMISSION_WRITE);
if (!mImmediateAlertService.addCharacteristic(mImmediateAlertChar)) {
CommonConstants.loge("Can not add IMMEDIATE_ALERT char for " + device.getAddress());
disconnect();
return;
}
if (gatt.getDevice().createBond()) {
CommonConstants.logd("onServicesDiscovered creating bond: OK");
} else {
CommonConstants.logd("onServicesDiscovered creating bond: NOT OK");
}
for (BleListener listener: mListeners) {
listener.servicesReady();
}
}
};
private Runnable mRssiRunnable = new Runnable() {
@Override
public void run() {
if (mBluetoothGatt == null)
return;
mBluetoothGatt.readRemoteRssi();
readPeriodicalyRssi();
}
};
private void readPeriodicalyRssi() {
//CommonConstants.logd("readPeriodicalyRssi");
mRssiReader.postDelayed(mRssiRunnable, mRssiInt);
}
@SuppressWarnings("deprecation")
public void startScanning() {
CommonConstants.logd("startScanning");
mBluetoothAdapter.startLeScan(mScanCallback);
String str = mContext.getString(R.string.scan_started);
for (BleListener listener: mListeners) {
listener.setState(str);
}
}
@SuppressWarnings("deprecation")
public void startScanning(String address) {
CommonConstants.logd("startScanning");
mBluetoothAdapter.startLeScan(mScanCallback);
String str = mContext.getString(R.string.scan_for_started) + address;
for (BleListener listener: mListeners) {
listener.setState(str);
}
}
@SuppressWarnings("deprecation")
public void stopScanning() {
CommonConstants.logd("stopScanning");
mBluetoothAdapter.stopLeScan(mScanCallback);
String str = mContext.getString(R.string.scan_stopped);
for (BleListener listener: mListeners) {
listener.setState(str);
}
}
public void connect(String address) {
connect(mBluetoothAdapter.getRemoteDevice(address));
}
public void connect(final BluetoothDevice device) {
CommonConstants.logd("connect: " + device.getAddress() + ", mBluetoothGatt: " + mBluetoothGatt);
Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
mBluetoothGatt = device.connectGatt(mContext, true, mGattCallback);
}
});
}
public void disconnect() {
CommonConstants.logd("disconnect");
try {
mBluetoothGatt.disconnect();
} catch (Exception e) {
CommonConstants.logd("disconnect ignoring: " + e);
}
try {
mBluetoothGatt.close();
} catch (Exception e) {
CommonConstants.logd("disconnect ignoring: " + e);
}
mBluetoothGatt = null;
mLinkLossService = null;
mTxPowerService = null;
mImmediateAlertService = null;
mImmediateAlertChar = null;
for (BleListener listener: mListeners) {
listener.deviceGone();
}
}
public boolean setAlertLevel(int level) {
CommonConstants.logd("setAlertLevel: " + level);
if (mBluetoothGatt == null ||
mImmediateAlertService == null ||
mImmediateAlertChar == null)
return false;
if (!mImmediateAlertChar.setValue(level,
CommonConstants.ALERT_LEVEL_CHARACTERISTIC_FORMAT_TYPE,
CommonConstants.ALERT_LEVEL_CHARACTERISTIC_OFFSET)) {
CommonConstants.loge("Can not set local ALERT_LEVEL char");
return false;
}
if (!mBluetoothGatt.writeCharacteristic(mImmediateAlertChar)) {
CommonConstants.loge("Can not write ALERT_LEVEL char");
}
return true;
}
public void setRssiInt(int rssiInt) {
mRssiInt = Math.max(rssiInt, CommonConstants.RSSI_INT_MIN);
}
public void setAverage(int average) {
mAverage = Math.max(average, CommonConstants.AVERAGE_MIN);
}
}
答案 1 :(得分:0)
是的,在您的所有课程/片段/活动中使用相同的服务。致电bindService
和ServiceConnection
以获得服务实例。