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

时间:2015-05-28 08:18:35

标签: bluetooth bluetooth-lowenergy android-fragmentactivity

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

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

最好的方法是什么? 谢谢

2 个答案:

答案 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)

是的,在您的所有课程/片段/活动中使用相同的服务。致电bindServiceServiceConnection以获得服务实例。