Back to project page Bluebit.
The source code is released under:
Apache License
If you think the Android project Bluebit listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
// vim: et sw=4 sts=4 tabstop=4 /*/* ww w . j av a 2s . c o m*/ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.issc.impl; import com.issc.Bluebit; import com.issc.gatt.Gatt; import com.issc.gatt.GattAdapter; import com.issc.gatt.Gatt.Listener; import com.issc.gatt.GattCharacteristic; import com.issc.gatt.GattDescriptor; import com.issc.gatt.GattService; import com.issc.impl.aosp.AospGattAdapter; import com.issc.impl.test.FakeGattAdapter; import com.issc.util.Log; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.UUID; import android.app.Service; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; /** * This class is a wrapper that handles Gatt related operations. * * Upper layer just use this service so that they do not have to * deal with Gatt by themself. */ public class LeService extends Service { private IBinder mBinder; private boolean mGattReady = false; private GattAdapter mGattAdapter = null; private Gatt mGatt = null; private Gatt.Listener mCallback; private List<Listener> mListeners; private Object mLock; @Override public void onCreate() { super.onCreate(); mLock = new Object(); mCallback = new TheCallback(); mListeners = new ArrayList<Listener>(); mBinder = new LocalBinder(); } @Override public void onDestroy() { super.onDestroy(); releaseGatt(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { boolean fake = intent.getBooleanExtra(Bluebit.USE_FAKE, false); if (fake) { Log.d("Use FakeGattAdapter for testing"); mGattAdapter = new FakeGattAdapter(this, mCallback); } else { Log.d("Use AospGattAdapter"); mGattAdapter = new AospGattAdapter(this, mCallback); } return Service.START_STICKY; } @Override public IBinder onBind(Intent intent) { return mBinder; } public void addListener(Listener l) { synchronized(mLock) { mListeners.add(l); } } public boolean rmListener(Listener l) { synchronized(mLock) { return mListeners.remove(l); } } private void releaseGatt() { synchronized(mLock) { mGattReady = false; if (mGatt != null) { mGatt.disconnect(); mGatt.close(); } mGatt = null; } } /** * Invoke this method to initialize Gatt before using Gatt. * * FIXME: right now we support connect to just 1 device. */ public Gatt connectGatt(Context ctx, boolean auto, BluetoothDevice dev) { if (mGatt != null) { closeGatt(dev); } mGatt = mGattAdapter.connectGatt(ctx, auto, mCallback, dev); return mGatt; } public void closeGatt(BluetoothDevice device) { /* In general, there should be an activity that close an Gatt when * onDestroy. However, if user press-back-key too fast, this Service will * release Gatt before destroying the activity, therefore Gatt might be null * when activity do closing Gatt.*/ if (mGatt != null) { mGatt.close(); mGatt = null; } } public boolean startScan(GattAdapter.LeScanCallback clbk) { return mGattAdapter.startLeScan(clbk); } public void stopScan(GattAdapter.LeScanCallback clbk) { mGattAdapter.stopLeScan(clbk); } public boolean connect(BluetoothDevice device, boolean auto) { return mGatt.connect(); } public void disconnect(BluetoothDevice device) { /* In general, there should be an activity that disconnect from an Gatt when * onDestroy. However, if user press-back-key too fast, this Service will * release Gatt before destroying the activity, therefore Gatt might be null * when activity do disconnecting.*/ if (mGatt != null) { mGatt.disconnect(); } } public List<BluetoothDevice> getConnectedDevices() { return mGattAdapter.getConnectedDevices(); } public boolean discoverServices(BluetoothDevice device) { return mGatt.discoverServices(); } public int getConnectionState(BluetoothDevice device) { return mGattAdapter.getConnectionState(device); } public GattService getService(BluetoothDevice device, UUID uuid) { return mGatt.getService(uuid); } public List<GattService> getServices(BluetoothDevice device) { return mGatt.getServices(); } public boolean readCharacteristic(GattCharacteristic chr) { return mGatt.readCharacteristic(chr); } public boolean writeCharacteristic(GattCharacteristic chr) { return mGatt.writeCharacteristic(chr); } public boolean readDescriptor(GattDescriptor dsc) { return mGatt.readDescriptor(dsc); } public boolean writeDescriptor(GattDescriptor dsc) { return mGatt.writeDescriptor(dsc); } public boolean setCharacteristicNotification(GattCharacteristic chr, boolean enable) { return mGatt.setCharacteristicNotification(chr, enable); } /* This is the only one callback that register to GATT. It dispatch each * of returen value to listeners. */ class TheCallback implements Gatt.Listener { @Override public void onCharacteristicChanged(Gatt gatt, GattCharacteristic chrc) { synchronized(mListeners) { Iterator<Listener> it = mListeners.iterator(); while(it.hasNext()) { it.next().onCharacteristicChanged(gatt, chrc); } } } @Override public void onCharacteristicRead(Gatt gatt, GattCharacteristic chrc, int status) { synchronized(mListeners) { Iterator<Listener> it = mListeners.iterator(); while(it.hasNext()) { it.next().onCharacteristicRead(gatt, chrc, status); } } } @Override public void onCharacteristicWrite(Gatt gatt, GattCharacteristic chrc, int status) { synchronized(mListeners) { Iterator<Listener> it = mListeners.iterator(); while(it.hasNext()) { it.next().onCharacteristicWrite(gatt, chrc, status); } } } @Override public void onConnectionStateChange(Gatt gatt, int status, int newState) { synchronized(mListeners) { Iterator<Listener> it = mListeners.iterator(); while(it.hasNext()) { it.next().onConnectionStateChange(gatt, status, newState); } } } @Override public void onDescriptorRead(Gatt gatt, GattDescriptor descriptor, int status) { synchronized(mListeners) { Iterator<Listener> it = mListeners.iterator(); while(it.hasNext()) { it.next().onDescriptorRead(gatt, descriptor, status); } } } @Override public void onDescriptorWrite(Gatt gatt, GattDescriptor descriptor, int status) { synchronized(mListeners) { Iterator<Listener> it = mListeners.iterator(); while(it.hasNext()) { it.next().onDescriptorWrite(gatt, descriptor, status); } } } @Override public void onReadRemoteRssi(Gatt gatt, int rssi, int status) { synchronized(mListeners) { Iterator<Listener> it = mListeners.iterator(); while(it.hasNext()) { it.next().onReadRemoteRssi(gatt, rssi, status); } } } @Override public void onServicesDiscovered(Gatt gatt, int status) { synchronized(mListeners) { Iterator<Listener> it = mListeners.iterator(); while(it.hasNext()) { it.next().onServicesDiscovered(gatt, status); } } } } public class LocalBinder extends Binder { public LeService getService() { return LeService.this; } } }