Bluetooth 通过许多活动和片段管理蓝牙低能耗

Bluetooth 通过许多活动和片段管理蓝牙低能耗,bluetooth,bluetooth-lowenergy,android-fragmentactivity,Bluetooth,Bluetooth Lowenergy,Android Fragmentactivity,我开发了一个管理连接的应用程序,所有连接都由一个活动控制。 但今天,我要在我的应用程序中添加活动和片段 因此,我有一个对象(根据Android开发者的BLE教程),名为BluetoothLeService,并管理连接等。。。 我需要在所有活动/片段中重用此对象,而无需重复登录过程 最好的方法是什么? 谢谢是的,请使用您所有课程/片段/活动中的相同服务。调用bindService和ServiceConnection来创建服务实例。我有一个前台活动(有几个片段)和一个后台服务 活动(应用程序运行时)

我开发了一个管理连接的应用程序,所有连接都由一个活动控制。 但今天,我要在我的应用程序中添加活动和片段

因此,我有一个对象(根据Android开发者的BLE教程),名为
BluetoothLeService
,并管理连接等。。。 我需要在所有活动/片段中重用此对象,而无需重复登录过程

最好的方法是什么?
谢谢

是的,请使用您所有课程/片段/活动中的相同服务。调用
bindService
ServiceConnection
来创建服务实例。

我有一个前台活动(有几个片段)和一个后台服务

活动(应用程序运行时)连接到服务,如中所述

该服务始终运行(也在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);
    }
}
公共类对象{
私有静态对象身份;
私有上下文;
私有HashSet mListeners=新HashSet();
专用处理器和读卡器;
private int mRssiInt=CommonConstants.RSSI_int_默认值;
private int mAverage=CommonConstants.AVERAGE\u默认值;
private ArrayList mRssiValues=new ArrayList();
私人蓝牙适配器mBluetoothAdapter;
私人蓝牙总协定;
私人蓝牙服务;
私人蓝牙服务mTxPowerService;
私人BluetoothGattService多媒体服务;
私有BluetoothGattCharacteristic mImmediateAlertChar;
公共接口侦听器{
公共无效设备基金(蓝牙设备,int rssi);
公共void updateRssi(蓝牙设备,int-rssi);
公共无效服务READY();
公共设备失效();
公共无效设置状态(字符串str);
}
公共静态BleObject getInstance(上下文){
if(sInstance==null)
sInstance=新对象(上下文);
回归承诺;
}
私有对象(上下文){
mContext=上下文;
mRssiReader=新处理程序();
}
公共void addListener(BLEStener listener){
添加(侦听器);
}
公共void RemovelListener(BLEStener listener){
删除(侦听器);
}
//在使用BleObject之前,应始终调用此方法
公共布尔init(){
BluetoothManager BluetoothManager=(BluetoothManager)mContext.getSystemService(Context.BLUETOOTH\u服务);
mBluetoothAdapter=bluetoothManager.getAdapter();
if(mBluetoothAdapter==null)
返回false;
返回mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE\u BLUETOOTH\u LE);
}    
公共布尔值isEnabled(){
返回mBluetoothAdapter.isEnabled();
}
私有BluetoothAdapter.LeScanCallback mScanCallback=新建BluetoothAdapter.LeScanCallback(){
@凌驾
public void onLeScan(最终蓝牙设备,最终整数rssi,字节[]扫描记录){
如果(设备==null)
返回;
字符串地址=device.getAddress();
if(!BluetoothAdapter.checkBluetoothAddress(地址))
返回;
for(BleListener侦听器:mlListeners){
DeviceFund(设备,rssi);
}
}
};
私有最终BluetoothGattCallback mGattCallback=新BluetoothGattCallback(){
@凌驾
连接状态更改的公共无效(蓝牙gatt gatt、int状态、int新闻状态){
if(newState==BluetoothProfile.STATE\u CONNECTED){
logd(“onConnectionStateChange STATE_CONNECTED:+gatt.getDevice().getAddress());
关贸总协定。发现服务();
readPeriodicalyRssi();
if(gatt!=null&&gatt.getDevice()!=null){
for(BleListener侦听器:mlListeners){
setState(mContext.getString(R.string.connected_to)+gatt.getDevice().getAddress());
}
}
}else if(newState==BluetoothProfile.STATE\u已断开连接){
logd(“onConnectionStateChange STATE_DISCONNECTED”);
断开连接();
for(BleListener侦听器:mlListeners){
setState(mContext.getString(R.string.not_connected));
}
}
}
@凌驾
公共无效onReadRemoteRssi(蓝牙gatt gatt、int rssi、int状态){
如果(状态!=蓝牙GATT.GATT\U成功)
返回;
如果(gatt==null)
返回;
BluetoothDevice=gatt.getDevice();
如果(设备==null)
返回;
//logd(“onReadRemoteRssi:+rssi”);
//添加新值并根据需要修剪列表
mRssiValues.add(rssi);
while(mRssiValues.size()>mAverage)
mRssiValues.remove(0);
//计算列表上的平均值
整数平均值=0;
for(整数rssiValue:mRssiValues){
平均值+=rssiValue;
}
average/=mRssiValues.size();
for(BleListener侦听器:mlListeners){
updateRssi(设备,平均值);
}
}
@凌驾
特征读取的公共无效(蓝牙gatt、蓝牙gatt特征ch、int状态){
如果(gatt==null)
返回;
BluetoothDevice=gatt.getDevice();
如果(设备==null)
返回;
logd(“onCharacteristicRead:+设备+”,状态:+状态);
如果(状态==蓝牙GATT.GATT\U成功)