8 changed files with 345 additions and 40 deletions
@ -0,0 +1,209 @@ |
|||
package fr.centralesupelec.students.clientble; |
|||
|
|||
import android.app.Activity; |
|||
import android.bluetooth.BluetoothGattCharacteristic; |
|||
import android.bluetooth.BluetoothGattService; |
|||
import android.content.BroadcastReceiver; |
|||
import android.content.ComponentName; |
|||
import android.content.Context; |
|||
import android.content.Intent; |
|||
import android.content.IntentFilter; |
|||
import android.content.ServiceConnection; |
|||
import android.os.IBinder; |
|||
import android.os.Bundle; |
|||
import android.util.Log; |
|||
import android.view.Menu; |
|||
import android.view.MenuItem; |
|||
import android.widget.TextView; |
|||
|
|||
public class SimpleDetailActivity extends Activity { |
|||
private final static String TAG = SimpleDetailActivity.class.getSimpleName(); |
|||
|
|||
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME"; |
|||
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS"; |
|||
|
|||
private TextView mDeviceAddressView; |
|||
private TextView mConnectionStateView; |
|||
private TextView mSensorValueView; |
|||
|
|||
private String mDeviceName; |
|||
private String mDeviceAddress; |
|||
|
|||
|
|||
private BluetoothLeService mBluetoothLeService; |
|||
private boolean mConnected = false; |
|||
private BluetoothGattCharacteristic mSensorValueCharac; |
|||
|
|||
|
|||
// Code to manage Service lifecycle.
|
|||
private final ServiceConnection mServiceConnection = new ServiceConnection() { |
|||
|
|||
@Override |
|||
public void onServiceConnected(ComponentName componentName, IBinder service) { |
|||
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService(); |
|||
if (!mBluetoothLeService.initialize()) { |
|||
Log.e(TAG, "Unable to initialize Bluetooth"); |
|||
finish(); |
|||
} |
|||
// Automatically connects to the device upon successful start-up initialization.
|
|||
mBluetoothLeService.connect(mDeviceAddress); |
|||
} |
|||
|
|||
@Override |
|||
public void onServiceDisconnected(ComponentName componentName) { |
|||
mBluetoothLeService = null; |
|||
} |
|||
}; |
|||
|
|||
// Handles various events fired by the Service.
|
|||
// ACTION_GATT_CONNECTED: connected to a GATT server.
|
|||
// ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
|
|||
// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.
|
|||
// ACTION_DATA_AVAILABLE: received data from the device. This can be a result of read
|
|||
// or notification operations.
|
|||
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() { |
|||
@Override |
|||
public void onReceive(Context context, Intent intent) { |
|||
final String action = intent.getAction(); |
|||
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) { |
|||
mConnected = true; |
|||
updateConnectionState(R.string.connected); |
|||
invalidateOptionsMenu(); |
|||
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { |
|||
mConnected = false; |
|||
updateConnectionState(R.string.disconnected); |
|||
invalidateOptionsMenu(); |
|||
clearUI(); |
|||
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { |
|||
// Show all the supported services and characteristics on the user interface.
|
|||
Log.d(TAG, "ACTION_GATT_SERVICES_DISCOVERED reçu."); |
|||
displayValues(); |
|||
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { |
|||
Log.d(TAG, "ACTION_DATA_AVAILABLE reçu."); |
|||
final String data = intent.getStringExtra(BluetoothLeService.EXTRA_DATA); |
|||
Log.d(TAG, data); |
|||
displayData(data); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
private void clearUI() { |
|||
mSensorValueView.setText(R.string.no_data); |
|||
} |
|||
|
|||
@Override |
|||
protected void onCreate(Bundle savedInstanceState) { |
|||
super.onCreate(savedInstanceState); |
|||
setContentView(R.layout.simple_detail_layout); |
|||
|
|||
final Intent intent = getIntent(); |
|||
|
|||
mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME); |
|||
|
|||
mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS); |
|||
mDeviceAddressView = (TextView) findViewById(R.id.device_address); |
|||
mDeviceAddressView.setText(mDeviceAddress); |
|||
|
|||
mConnectionStateView = (TextView) findViewById(R.id.connection_state); |
|||
|
|||
mSensorValueView = (TextView) findViewById(R.id.sensor_value); |
|||
|
|||
getActionBar().setTitle(mDeviceName); |
|||
getActionBar().setDisplayHomeAsUpEnabled(true); |
|||
Intent gattServiceIntent = new Intent(this, BluetoothLeService.class); |
|||
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE); |
|||
} |
|||
|
|||
|
|||
@Override |
|||
protected void onResume() { |
|||
super.onResume(); |
|||
registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter()); |
|||
if (mBluetoothLeService != null) { |
|||
final boolean result = mBluetoothLeService.connect(mDeviceAddress); |
|||
Log.d(TAG, "Connect request result=" + result); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
protected void onPause() { |
|||
super.onPause(); |
|||
unregisterReceiver(mGattUpdateReceiver); |
|||
} |
|||
|
|||
@Override |
|||
protected void onDestroy() { |
|||
super.onDestroy(); |
|||
unbindService(mServiceConnection); |
|||
mBluetoothLeService = null; |
|||
} |
|||
|
|||
@Override |
|||
public boolean onCreateOptionsMenu(Menu menu) { |
|||
getMenuInflater().inflate(R.menu.gatt_services, menu); |
|||
if (mConnected) { |
|||
menu.findItem(R.id.menu_connect).setVisible(false); |
|||
menu.findItem(R.id.menu_disconnect).setVisible(true); |
|||
} else { |
|||
menu.findItem(R.id.menu_connect).setVisible(true); |
|||
menu.findItem(R.id.menu_disconnect).setVisible(false); |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public boolean onOptionsItemSelected(MenuItem item) { |
|||
switch(item.getItemId()) { |
|||
case R.id.menu_connect: |
|||
mBluetoothLeService.connect(mDeviceAddress); |
|||
return true; |
|||
case R.id.menu_disconnect: |
|||
mBluetoothLeService.disconnect(); |
|||
return true; |
|||
case android.R.id.home: |
|||
onBackPressed(); |
|||
return true; |
|||
} |
|||
return super.onOptionsItemSelected(item); |
|||
} |
|||
|
|||
private void updateConnectionState(final int resourceId) { |
|||
runOnUiThread(new Runnable() { |
|||
@Override |
|||
public void run() { |
|||
mConnectionStateView.setText(resourceId); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
private void displayData(String data) { |
|||
if (data != null) { |
|||
mSensorValueView.setText(data); |
|||
} |
|||
} |
|||
|
|||
private void displayValues() { |
|||
BluetoothGattService privateService = mBluetoothLeService.getPrivateService(); |
|||
if (privateService == null) { |
|||
Log.w(TAG, "Service Gatt privé non détecté."); |
|||
return; |
|||
} |
|||
mSensorValueCharac = |
|||
privateService.getCharacteristic(SampleGattAttributes.SENSOR_CHARACTERISTIC_UUID); |
|||
final int charaProp = mSensorValueCharac.getProperties(); |
|||
mBluetoothLeService.readCharacteristic(mSensorValueCharac); |
|||
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { |
|||
Log.d(TAG, "Demande de notification."); |
|||
mBluetoothLeService.setCharacteristicNotification(mSensorValueCharac, true); |
|||
} |
|||
} |
|||
|
|||
private static IntentFilter makeGattUpdateIntentFilter() { |
|||
final IntentFilter intentFilter = new IntentFilter(); |
|||
intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED); |
|||
intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); |
|||
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); |
|||
intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE); |
|||
return intentFilter; |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:orientation="vertical" android:layout_width="match_parent" |
|||
android:layout_height="match_parent"> |
|||
<LinearLayout android:orientation="horizontal" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:layout_margin="10dp"> |
|||
<TextView android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:text="@string/label_device_address" |
|||
android:textSize="18sp"/> |
|||
<Space android:layout_width="5dp" |
|||
android:layout_height="wrap_content"/> |
|||
<TextView android:id="@+id/device_address" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:textSize="18sp"/> |
|||
</LinearLayout> |
|||
<LinearLayout android:orientation="horizontal" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:layout_margin="10dp"> |
|||
<TextView android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:text="@string/label_state" |
|||
android:textSize="18sp"/> |
|||
<Space android:layout_width="5dp" |
|||
android:layout_height="wrap_content"/> |
|||
<TextView android:id="@+id/connection_state" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:text="@string/disconnected" |
|||
android:textSize="18sp"/> |
|||
</LinearLayout> |
|||
<LinearLayout android:orientation="horizontal" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:layout_margin="10dp"> |
|||
|
|||
<TextView |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:text="@string/label_data" |
|||
android:textSize="18sp" /> |
|||
<Space android:layout_width="5dp" |
|||
android:layout_height="wrap_content"/> |
|||
|
|||
<TextView |
|||
android:id="@+id/sensor_value" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:textSize="18sp" /> |
|||
</LinearLayout> |
|||
</LinearLayout> |
|||
Loading…
Reference in new issue