Java tutorial
/* * Copyright (C) 2013 The Android Open Source Project * * 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.polkapolka.bluetooth.le; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.TaskStackBuilder; 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.Bundle; import android.os.IBinder; import android.support.v4.app.NotificationCompat; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.UUID; // mind3d libraries //import min3d.core.Object3dContainer; //import min3d.core.RendererActivity; //import min3d.parser.IParser; //import min3d.parser.Parser; /** * For a given BLE device, this Activity provides the user interface to connect, display data, * and display GATT services and characteristics supported by the device. The Activity * communicates with {@code BluetoothLeService}, which in turn interacts with the * Bluetooth LE API. */ public class DeviceControlActivity extends ActionBarActivity implements NavigationDrawerCallbacks { public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME"; public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS"; public static final int NOTIFICATION_DELAY = 30 * 1000; public final static UUID HM_RX_TX = UUID.fromString(SampleGattAttributes.HM_RX_TX); private final static String TAG = DeviceControlActivity.class.getSimpleName(); private final String LIST_NAME = "NAME"; private final String LIST_UUID = "UUID"; Button showNotificationBut; NotificationManager notificationManager; static int notifID = 33; private int[] RGBFrame = { 0, 0, 0 }; private TextView isSerial; private TextView Calibration_button_text; private TextView mConnectionState; private TextView mDataField; private SeekBar mRed, mGreen, mBlue; private String mDeviceName; private String mDeviceAddress; // private ExpandableListView mGattServicesList; private BluetoothLeService mBluetoothLeService; // Code to manage Service lifecycle. private final ServiceConnection mServiceConnection = new ServiceConnection() { /** * Fragment managing the behaviors, interactions and presentation of the navigation drawer. */ @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; } }; private boolean mConnected = false; // 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. displayGattServices(mBluetoothLeService.getSupportedGattServices()); } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { // call handler is now done in arduinoreceiver.java // try { // arduinoHandler.handleArduinoBytes(intent); // } catch (Exception e) { // System.out.println("Skipped incoming data, because of exception!"); // e.printStackTrace(); // } displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA)); } } }; private BluetoothGattCharacteristic characteristicTX; private BluetoothGattCharacteristic characteristicRX; // private ArduinoHandler arduinoHandler; private static long lastNotificationTime = 0; private NavigationDrawerFragment mNavigationDrawerFragment; private Toolbar mToolbar; 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; } private void clearUI() { mDataField.setText(R.string.no_data); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.gatt_services_characteristics); // mToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar); // setSupportActionBar(mToolbar); // // mNavigationDrawerFragment = (NavigationDrawerFragment) // getFragmentManager().findFragmentById(R.id.fragment_drawer); // // // Set up the drawer. // mNavigationDrawerFragment.setup(R.id.fragment_drawer, (DrawerLayout) findViewById(R.id.drawer), mToolbar); // showNotificationBut = (Button) findViewById(R.id.createNification); // arduinoHandler = new ArduinoHandler(this); // Button ActivityButtonUserActivity = (Button) findViewById(R.id.activityButtonUserActivity); // ActivityButtonUserActivity.setOnClickListener(new View.OnClickListener() { // @Override // public void onClick(View view) { // Intent intent = new Intent(view.getContext(), userActivity.class); // startActivityForResult(intent, 0); // } // }); Button ActivityButtonUserOverview = (Button) findViewById(R.id.activityButtonUserOverview); ActivityButtonUserOverview.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(view.getContext(), userOverview.class); startActivityForResult(intent, 0); } } ); final Button calibrationButton = (Button) findViewById(R.id.calibrationButton); calibrationButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // set boolean on true or false toggle if (ArduinoReceiver.arduinoHandler.isCalibrating == false) { ArduinoReceiver.arduinoHandler.isCalibrating = true; //change text of button depending on toggle state Calibration_button_text.setText(getString(R.string.StopCalibration)); System.out.println(ArduinoReceiver.arduinoHandler.isCalibrating); } else { ArduinoReceiver.arduinoHandler.isCalibrating = false; //change text of button depending on toggle state Calibration_button_text.setText(getString(R.string.calibrate_Now)); System.out.println(ArduinoReceiver.arduinoHandler.isCalibrating); } } }); final Intent intent = getIntent(); mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME); mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS); // Sets up UI references. ((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress); mConnectionState = (TextView) findViewById(R.id.connection_state); // is serial present? isSerial = (TextView) findViewById(R.id.isSerial); Calibration_button_text = (TextView) findViewById(R.id.calibrationButton); mDataField = (TextView) findViewById(R.id.data_value); mRed = (SeekBar) findViewById(R.id.seekRed); mGreen = (SeekBar) findViewById(R.id.seekRed); mBlue = (SeekBar) findViewById(R.id.seekRed); readSeek(mRed, 0); readSeek(mGreen, 1); readSeek(mBlue, 2); // 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); menu.findItem(R.id.menu_select_Activity).setVisible(true); menu.findItem(R.id.menu_select_overview).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 R.id.menu_select_Activity: Intent intent = new Intent(this, userActivity.class); startActivityForResult(intent, 0); return true; case R.id.menu_select_overview: Intent intent2 = new Intent(this, userOverview.class); startActivityForResult(intent2, 0); return true; case R.id.menu_select_notification: showNotificationInMenu(this); return true; case R.id.infoTips: Intent intent3 = new Intent(this, deskInfo.class); startActivityForResult(intent3, 0); 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() { mConnectionState.setText(resourceId); } }); } private void displayData(String data) { if (data != null) { mDataField.setText(data); } } // Demonstrates how to iterate through the supported GATT Services/Characteristics. // In this sample, we populate the data structure that is bound to the ExpandableListView // on the UI. private void displayGattServices(List<BluetoothGattService> gattServices) { if (gattServices == null) return; String uuid = null; String unknownServiceString = getResources().getString(R.string.unknown_service); ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>(); // Loops through available GATT Services. for (BluetoothGattService gattService : gattServices) { HashMap<String, String> currentServiceData = new HashMap<String, String>(); uuid = gattService.getUuid().toString(); currentServiceData.put(LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString)); // If the service exists for HM 10 Serial, say so. if (SampleGattAttributes.lookup(uuid, unknownServiceString) == "HM 10 Serial") { isSerial.setText(getString(R.string.verbinding_herkend)); } else { isSerial.setText("No, serial :-("); } currentServiceData.put(LIST_UUID, uuid); gattServiceData.add(currentServiceData); // get characteristic when UUID matches RX/TX UUID characteristicTX = gattService.getCharacteristic(BluetoothLeService.UUID_HM_RX_TX); characteristicRX = gattService.getCharacteristic(BluetoothLeService.UUID_HM_RX_TX); } } private void readSeek(SeekBar seekBar, final int pos) { seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { RGBFrame[pos] = progress; } @Override public void onStartTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } @Override public void onStopTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub makeChange(); } }); } // on change of bars write char private void makeChange() { String str = RGBFrame[0] + "," + RGBFrame[1] + "," + RGBFrame[2] + "\n"; Log.d(TAG, "Sending result=" + str); final byte[] tx = str.getBytes(); if (mConnected) { characteristicTX.setValue(tx); mBluetoothLeService.writeCharacteristic(characteristicTX); mBluetoothLeService.setCharacteristicNotification(characteristicRX, true); } } //shownotification in menu function public static void showNotificationInMenu(Context context) { // variables long currentTime = System.currentTimeMillis(); // guard: check if we should wait if (currentTime - lastNotificationTime < NOTIFICATION_DELAY) { return; } lastNotificationTime = currentTime; NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context) .setContentTitle(context.getString(R.string.NotifationTitle)) .setContentText(context.getString(R.string.NotificationSubtitle)) .setTicker(context.getString(R.string.BadPostureTicker)).setSmallIcon(R.drawable.icon); // Define that we have the intention of opening MoreInfoNotification Intent moreInfoIntent = new Intent(context, userActivity.class); // Used to stack tasks across activites so we go to the proper place when back is clicked TaskStackBuilder tStackBuilder = TaskStackBuilder.create(context); // Add all parents of this activity to the stack tStackBuilder.addParentStack(DeviceControlActivity.class); // Add our new Intent to the stack tStackBuilder.addNextIntent(moreInfoIntent); // default_all -> vibrate light and sound DEFAULT_VIBRATE -> only vibration even with sound on. notificationBuilder.setDefaults(Notification.DEFAULT_ALL); notificationBuilder.setAutoCancel(true); // Define an Intent and an action to perform with it by another application // FLAG_UPDATE_CURRENT : If the intent exists keep it but update it if needed PendingIntent pendingIntent = tStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); // Defines the Intent to fire when the notification is clicked notificationBuilder.setContentIntent(pendingIntent); // Gets a NotificationManager which is used to notify the user of the background event NotificationManager notificationManager; notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); // Post the notification notificationManager.notify(notifID, notificationBuilder.build()); } //show notification button function public void showNotification(View view) { NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setContentTitle(getString(R.string.NotifationTitle)) .setContentText(getString(R.string.NotificationSubtitle)) .setTicker(getString(R.string.NotificationTicker)).setSmallIcon(R.drawable.icon); // Define that we have the intention of opening MoreInfoNotification Intent moreInfoIntent = new Intent(this, userActivity.class); // Used to stack tasks across activites so we go to the proper place when back is clicked TaskStackBuilder tStackBuilder = TaskStackBuilder.create(this); // Add all parents of this activity to the stack tStackBuilder.addParentStack(DeviceControlActivity.class); // Add our new Intent to the stack tStackBuilder.addNextIntent(moreInfoIntent); notificationBuilder.setDefaults(Notification.DEFAULT_ALL); notificationBuilder.setAutoCancel(true); // Define an Intent and an action to perform with it by another application // FLAG_UPDATE_CURRENT : If the intent exists keep it but update it if needed PendingIntent pendingIntent = tStackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); // Defines the Intent to fire when the notification is clicked notificationBuilder.setContentIntent(pendingIntent); // Gets a NotificationManager which is used to notify the user of the background event notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // Post the notification notificationManager.notify(notifID, notificationBuilder.build()); } @Override public void onNavigationDrawerItemSelected(int position) { // update the main content by replacing fragments Toast.makeText(this, getString(R.string.MenuItemSelectedToastMessage) + position, Toast.LENGTH_SHORT) .show(); } @Override public void onBackPressed() { // do nothing. We want to force user to stay in this activity and not drop out. } }