Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
ELET4133: Embedded Systems Topic 17 More Bluetooth Agenda • • • • 9/27/2013 What is Bluetooth? General Terms Turning Bluetooth off/on from your APP Again, must be tested by an Android Device, not the emulator http://www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 2 Appreciation and Citation • Special Thanks to Professor Glenys Gustin, Associate Professor of CIS at Deleware County Community College – This presentation follows her three Youtube Lectures about Bluetooth – They can be viewed at: • http://www.youtube.com/watch?v=M5_EJ27xjMU&list=PLB4253C81CD49FF26 • http://www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 • http://www.youtube.com/watch?v=X-Z4TiJTtlY&list=PLB4253C81CD49FF26 9/27/2013 http://www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 3 Past • In the not-too-distant past computers used RS232 cables for serial communication between devices • Now, we mostly use USB when wired connections are necessary • Now we connect wirelessly 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 4 Wireless • Today, most communications are wireless – Bluetooth – WiFi • So, • What is Bluetooth Technology? • What are the general Terms? • How do you turn it off/on and use it? 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 5 Bluetooth Intro • To test Apps, a Bluetooth device is required – The emulator will not work • Bluetooth uses the SPP (or RFCOMM) – Bluetooth Serial Port Profile – RF (Radio Frequency) COMM (communication) – Simply known as the Bluetooth Transport Protocol • Provides serial data transfers via sockets 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 6 What is Bluetooth? • A wireless communications protocol • Constrained to short-range, line-of-site communications – Up to 50 meters – Doesn’t work well through walls – Used a lot for game technologies (Wii) • Became popular with hands-free devices • Enables peer-to-peer communications 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 7 What is Bluetooth? • Bluetooth APIs have been available since Android 2.0 SDK • Android applications that have Bluetooth hardware can: – Scan for other Bluetooth devices – Discover other Bluetooth devices – Establish RFCOMM connections between the two – Transfer data – Maintain point-to-point and multipoint connections 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 8 android.bluetooth API • Bluetooth APIs are part of the android.bluetooth package • Android permits only encrypted connections • Two devices must be bonded (paired) to transfer data between them • Once bonded you can connect later without security prompts 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 9 Bluetooth API Classes • BluetoothAdapter – Hardware on the device • BluetoothDevice – Remote Bluetooth device • BluetoothServerSocket – Listens for incoming connections (Master device) • BluetoothSocket – Remote device uses this to connect to the Master 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 10 Bluetooth Permissions • To use Bluetooth features in your application, you must add these permissions to the AndroidManifest.xml file for Bluetooth to work <manifest ... > <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> ... </manifest> 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 11 Communication Setup • To start Bluetooth communications we have four basic steps – The 4 steps are usually handled in a separate threads • So that the calling (also called blocking) functions do not make the App appear to hang 1. 2. 3. 4. 9/27/2013 Turn on Bluetooth for the device Find paired or available devices within range Connect devices Transfer data between the devices http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 12 Introduction to Threads 9/27/2013 13 Java Threads • A Thread is a public class that extends Object and implements Runnable • A Thread is a concurrent unit of execution Representation of the main program (Thread) running 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 14 Java Threads • A Thread is a public class that extends Object and implements Runnable • A Thread is a concurrent unit of execution Representation of the main program (Thread) running 9/27/2013 Represents a new thread http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 15 Java Threads • A Thread is a public class that extends Object and implements Runnable • A Thread is a concurrent unit of execution Representation of the main program (Thread) running Represents a new thread The main program is still running, but the new thread begins running simultaneously. If a method in the new thread hangs, stops, or just takes a long time, the main program continues running without problems 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 16 Java Threads • A Thread is a public class that extends Object and implements Runnable • A Thread is a concurrent unit of execution Representation of the main program (Thread) running Represents a new thread The new thread eventually finishes what it was designed to do and stops 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 17 Java Threads • A Thread is a public class that extends Object and implements Runnable • A Thread is a concurrent unit of execution Representation of the main program (Thread) running Represents a new thread You can have multiple threads, but the more threads you have, the more threads you have to keep track of and ensure close properly 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 18 Java Threads • A Thread: – It has its own call stack for methods being invoked, their arguments and local variables – Each application has at least one thread running when it is started, the main thread, in the main ThreadGroup – The runtime keeps its own threads in the system thread group 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 19 Java Threads • There are two ways to execute code in a new thread: – You can either subclass Thread and overriding its run() method – Construct a new Thread and pass a Runnable to the constructor 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 20 Program Preview (What we plan to do) 9/27/2013 21 Bluetooth On/Off • Before we get started, disable Bluetooth on your phone because this APP will control its state 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 22 Program Preview • The App we’re writing will show this screen: 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 23 Program Preview • The App we’re writing will show this screen: • When we press the connect button, the system will request persmission 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 24 Program Preview • The App we’re writing will show this screen: • When we press the connect button, the system will request persmission • If we select [Yes] the system will show us that it is turning on the Bluetooth 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 25 Program Preview • The App we’re writing will show this screen: • When we press the connect button, the system will request persmission • If we select [Yes] the system will show us that it is turning on the Bluetooth • When on, we will see this screen 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 26 Program Preview • The App we’re writing will show this screen: • When we select [Disconnect] we will see the Bluetooth icon disappear and a message appear • Then it will return to the first screen 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 27 Starting the Project 9/27/2013 28 Background • To Start: Begin a new project that has: – Main.xml • Has a text view • 2 buttons – One for Connect, one for Disconnect • Image view for the Bluetooth icon – Get an image and put it in the res/drawable folder – Set permissions in AndroidManifest.xml – Setup preliminary “stuff” in the java file 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 29 Java Setup • Setup Java Class such that – Set references for TextView, 2 Buttons, and ImageView – Develop the UI in the onCreate () method • Get references for TextView, Buttons, and ImageView • Setup the “setVisibility ()” method for each • Setup onClick () methods for the Connect and Disconnect Buttons (using AICs) 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 30 The Files: activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:id="@+id/textView1" android:layout_width="match_parent" All of the information for RelativeLayout android:layout_height="wrap_content" was set by default, by Eclipse, because a android:text="@string/toptext" /> new Android project was created. 9/27/2013 <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView1" android:layout_below="@+id/textView1" android:layout_marginTop="14dp" android:text="@string/Button1" /> http://www.youtube.com/watch?v=M5_EJ27xjMU&list=PLB4253C81CD49FF26 31 The Files: activity_main.xml The TextView, two Buttons, the ImageView, and the image were drug from the palette (or drawable folder) to the Android screen. Several attributes were specified so that the screen looked as shown, but the rest was specified by Eclipse, by default 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 32 The Files: activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > The items highlighted in red are the ones changed. <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/toptext" /> 9/27/2013 <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView1" android:layout_below="@+id/textView1" android:layout_marginTop="14dp" android:text="@string/Button1" /> http://www.youtube.com/watch?v=M5_EJ27xjMU&list=PLB4253C81CD49FF26 33 The Files: activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > The items highlighted in red are the ones changed. <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="wrap_content" The widths of the android:text="@string/toptext" /> TextView, and the Buttons were changed to <Button “match_parent” so that android:id="@+id/button1" they all were as wide as android:layout_width="match_parent" the screen itself android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView1" android:layout_below="@+id/textView1" android:layout_marginTop="14dp" 34 android:text="@string/Button1" /> 9/27/2013 http://www.youtube.com/watch?v=M5_EJ27xjMU&list=PLB4253C81CD49FF26 The Files: activity_main.xml <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button1" android:layout_below="@+id/button1" android:layout_marginTop="8dp" android:text="@string/Button2" /> The widths of the TextView, and the Buttons were changed to “match_parent” so that they all were as wide as the screen itself <ImageView android:id="@+id/imageView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button2" android:layout_alignRight="@+id/button2" android:layout_below="@+id/button2" android:layout_marginLeft="15dp" android:layout_marginTop="28dp" android:contentDescription="@string/descrip" android:src="@drawable/bluetooth2" /> </RelativeLayout> 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 35 The Files: activity_main.xml <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button1" android:layout_below="@+id/button1" android:layout_marginTop="8dp" android:text="@string/Button2" /> The widths of the TextView, and the Buttons were changed to “match_parent” so that they all were as wide as the screen itself <ImageView android:id="@+id/imageView2" android:layout_width="wrap_content" android:layout_height="wrap_content" The ImageView on the GUI android:layout_alignLeft="@+id/button2" was stretched manually, android:layout_alignRight="@+id/button2" so Eclipse chose to use android:layout_below="@+id/button2" alignLeft and alignRight android:layout_marginLeft="15dp" to set the width instead android:layout_marginTop="28dp" of the “match_parent” android:contentDescription="@string/descrip" android:src="@drawable/bluetooth2" /> </RelativeLayout> 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 36 The Files: activity_main.xml <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button1" android:layout_below="@+id/button1" android:layout_marginTop="8dp" android:text="@string/Button2" /> The “descrip” attribute and value “Bluetooth Icon” were <ImageView set to remove a warning – it android:id="@+id/imageView2" was not necessary android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button2" android:layout_alignRight="@+id/button2" android:layout_below="@+id/button2" android:layout_marginLeft="15dp" android:layout_marginTop="28dp" android:contentDescription="@string/descrip" android:src="@drawable/bluetooth2" /> </RelativeLayout> 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 37 The Files: activity_main.xml <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button1" android:layout_below="@+id/button1" android:layout_marginTop="8dp" android:text="@string/Button2" /> <ImageView android:id="@+id/imageView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button2" android:layout_alignRight="@+id/button2" android:layout_below="@+id/button2" android:layout_marginLeft="15dp" The image bluetooth2.jpg android:layout_marginTop="28dp" was placed in the actual android:contentDescription="@string/descrip" res/drawable-hdpi folder android:src="@drawable/bluetooth2" /> so that it was available to the project </RelativeLayout> 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 38 The Files: res/values/string.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string <string <string <string <string <string name="app_name">BluetoothControl</string> name="action_settings">Settings</string> name="toptext">Bluetooth Not Connected</string> name="descrip">Bluetooth Icon</string> name="Button1">Connect Bluetooth</string> name="Button2">Disconnect Bluetooth</string> </resources> Most of these were changed to match the names in activity_main.xml 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 39 The Files: res/values/string.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string <string <string <string <string <string name="app_name">BluetoothControl</string> name="action_settings">Settings</string> name="toptext">Bluetooth Not Connected</string> name="descrip">Bluetooth Icon</string> name="Button1">Connect Bluetooth</string> name="Button2">Disconnect Bluetooth</string> </resources> Most of these were changed to match the names in activity_main.xml The “descrip” attribute and value “Bluetooth Icon” were set to remove a warning – it was not necessary 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 40 MainActivity.java • Very little of the MainActivity.java file had been created by Eclipse by default • Lines create by Eclipse: – The package name – Basic imports statements • When an error occurred, press [CNTRL][SHIFT]+O – The class declaration – The default parts of the onCreate ( ) method – All highlighted in red on next page 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 41 src/packageName/MainActitivy.java package com.example.bluetoothcontrol; import import import import import import import import The lines in red were created by android.app.Activity; Eclipse by default. android.os.Bundle; android.view.Menu; android.view.View; android.view.View.OnClickListener; android.widget.Button; android.widget.ImageView; android.widget.TextView; public class MainActivity extends Activity { /** Called when the activity is first created */ public TextView statusUpdate; public Button connect; public Button disconnect; public ImageView logo; 9/27/2013 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setupUI(); } http://www.youtube.com/watch?v=M5_EJ27xjMU&list=PLB4253C81CD49FF26 42 src/packageName/MainActitivy.java package com.example.bluetoothcontrol; import import import import import import import import android.app.Activity; android.os.Bundle; android.view.Menu; android.view.View; android.view.View.OnClickListener; android.widget.Button; android.widget.ImageView; android.widget.TextView; public class MainActivity extends Activity { /** Called when the activity is first created */ public TextView statusUpdate; The UI layout file defined a public Button connect; TextView, two buttons, and an public Button disconnect; ImageView. References to those public ImageView logo; objects are needed in the java 9/27/2013 file so they or their contents @Override can be manipulated. So these protected void onCreate(Bundle savedInstanceState) lines were entered {manually super.onCreate(savedInstanceState); and are the references to setContentView(R.layout.activity_main); those objects setupUI(); } http://www.youtube.com/watch?v=M5_EJ27xjMU&list=PLB4253C81CD49FF26 43 src/packageName/MainActitivy.java package com.example.bluetoothcontrol; import import import import import import import import Errors were generated when the reference lines were typed in because these import statements had not been entered. android.app.Activity; android.os.Bundle; android.view.Menu; android.view.View; android.view.View.OnClickListener; By pressing [CNTRL][SHIFT]+O the correct import statements were android.widget.Button; entered automatically by Eclipse android.widget.ImageView; and the errors were corrected. android.widget.TextView; public class MainActivity extends Activity { /** Called when the activity is first created */ public TextView statusUpdate; The UI layout file defined a public Button connect; TextView, two buttons, and an public Button disconnect; ImageView. References to those public ImageView logo; objects are needed in the java 9/27/2013 file so they or their contents @Override can be manipulated. So these protected void onCreate(Bundle savedInstanceState) lines were entered {manually super.onCreate(savedInstanceState); and are the references to setContentView(R.layout.activity_main); those objects setupUI(); } http://www.youtube.com/watch?v=M5_EJ27xjMU&list=PLB4253C81CD49FF26 44 src/packageName/MainActitivy.java package com.example.bluetoothcontrol; import import import import import import import import android.app.Activity; android.os.Bundle; android.view.Menu; android.view.View; android.view.View.OnClickListener; android.widget.Button; android.widget.ImageView; android.widget.TextView; public class MainActivity extends Activity { /** Called when the activity is first created */ public TextView statusUpdate; public Button connect; These lines were created public Button disconnect; automatically by Eclipse. public ImageView logo; 9/27/2013 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setupUI(); } http://www.youtube.com/watch?v=M5_EJ27xjMU&list=PLB4253C81CD49FF26 45 src/packageName/MainActitivy.java package com.example.bluetoothcontrol; import import import import import import import import android.app.Activity; android.os.Bundle; android.view.Menu; android.view.View; android.view.View.OnClickListener; android.widget.Button; android.widget.ImageView; android.widget.TextView; public class MainActivity extends Activity { /** Called when the activity is first created */ public TextView statusUpdate; public Button connect; public Button disconnect; The rest of the UI setup files public ImageView logo; could be written where this line is, but the author chose @Override to jump to a new method, protected void onCreate(Bundle savedInstanceState) { setupUI(), to finish and super.onCreate(savedInstanceState); “encapsulate” the remainder of setContentView(R.layout.activity_main); this task. setupUI(); } 9/27/2013 http://www.youtube.com/watch?v=M5_EJ27xjMU&list=PLB4253C81CD49FF26 46 src/packageName/MainActitivy.java private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); /** set display view */ The setupUI() method finishes the task connect.setVisibility(View.GONE);of completing the UI. The method ends disconnect.setVisibility(View.GONE); on the next page logo.setVisibility(View.GONE); connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { } }); 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 47 src/packageName/MainActitivy.java private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); These statements get the objects /** set display view */ that were defined in the connect.setVisibility(View.GONE); activity_main.xml file and disconnect.setVisibility(View.GONE); referenced above and set with IDs logo.setVisibility(View.GONE); created by Eclipse and stored in the R.java file. Here, we setup connect.setOnClickListener(new OnClickListener() { identifiers for each object so @Override that they may be used and public void onClick(View v) { manipulated by the program. } }); 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 48 src/packageName/MainActitivy.java private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); /** set display view */ connect.setVisibility(View.GONE); disconnect.setVisibility(View.GONE); logo.setVisibility(View.GONE); The two buttons and the ImageView were just named (previous slide). These statements make sure that they are not visible at connect.setOnClickListener(new OnClickListener() { this time. @Override public void onClick(View v) { } }); 9/27/2013 GONE is a constant whose value means to make the View object invisible http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 49 src/packageName/MainActitivy.java private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); This line sets the /** set display view */ onClickListener for the connect connect.setVisibility(View.GONE); button. It will be handled by an disconnect.setVisibility(View.GONE); Annymous Inner Class, but it has logo.setVisibility(View.GONE); not been developed yet connect.setOnClickListener(new OnClickListener() @Override public void onClick(View v) { } }); 9/27/2013 { The AIC is everything between the enlarged purple parantheses. http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 50 src/packageName/MainActitivy.java disconnect.setOnClickListener(new OnClickListener () { @Override public void onClick(View v) { This line sets the } onClickListener for the disconnect button in the same }); way that was just done for the connect button. It will } //End setupUI() method be handled by an AIC, but, like before, it has not been @Override developed yet public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 51 src/packageName/MainActitivy.java disconnect.setOnClickListener(new OnClickListener () { @Override public void onClick(View v) { } }); } //End setupUI() method At this time, only the default for the Options Menu has been developed, and that was done automatically by Eclipse @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 52 Let’s Continue (still working on the java file) 9/27/2013 53 MainActivity.java package com.example.bluetoothcontrol; import android.app.Activity; First:create a reference to a BlueTooth Adapter. public class MainActivity extends Activity { /** Called when the activity is first created */ private BluetoothAdapter btAdapter; public public public public TextView statusUpdate; Button connect; Button disconnect; ImageView logo; “The BlueTooth Adapter class initializes the BT hardware on the device.” We use the getDefaultAdapter() method to retrieve information @Override about the BT interface protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setupUI(); } 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 54 src/packageName/MainActitivy.java private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); When the user clicks the /** set display view */ “Connect” button, we want to get connect.setVisibility(View.GONE); information about the BT hardware disconnect.setVisibility(View.GONE); on the device. So, in the AIC we logo.setVisibility(View.GONE); use the getDefaultAdapter () method. connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { btAdapter = BluetoothAdapter.getDefaultAdapter(); } }); 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 55 src/packageName/MainActitivy.java private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); /** set display view */ connect.setVisibility(View.GONE); disconnect.setVisibility(View.GONE); logo.setVisibility(View.GONE); 9/27/2013 Then we need some code to check to see if there is an adapter { connect.setOnClickListener(new OnClickListener() present. @Override public void onClick(View v) { btAdapter = BluetoothAdapter.getDefaultAdapter(); if (btAdapter.isEnabled()) { String address = btAdapter.getAddress(); String name = btAdapter.getName(); String statusText = name+":"+address; statusUpdate.setText(statusText); } else { statusUpdate.setText("Bluetooth is not on"); }); } www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 http:// 56 src/packageName/MainActitivy.java private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); /** set display view */ connect.setVisibility(View.GONE); disconnect.setVisibility(View.GONE); logo.setVisibility(View.GONE); If it is present and enabled, we build a string { identifier and connect.setOnClickListener(new OnClickListener() send it to the text filed on the @Override screen public void onClick(View v) { 9/27/2013 btAdapter = BluetoothAdapter.getDefaultAdapter(); if (btAdapter.isEnabled()) { String address = btAdapter.getAddress(); String name = btAdapter.getName(); String statusText = name+":"+address; statusUpdate.setText(statusText); } else { statusUpdate.setText("Bluetooth is not on"); }); } www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 http:// 57 src/packageName/MainActitivy.java private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); /** set display view */ connect.setVisibility(View.GONE); disconnect.setVisibility(View.GONE); logo.setVisibility(View.GONE); 9/27/2013 connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { If it is not present and enabled, btAdapter = BluetoothAdapter.getDefaultAdapter(); we send a string to the text if (btAdapter.isEnabled()) field { on the screen to let the String address = btAdapter.getAddress(); user know that String name = btAdapter.getName(); String statusText = name+":"+address; statusUpdate.setText(statusText); } else { statusUpdate.setText("Bluetooth is not on"); }); } www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 http:// 58 src/packageName/MainActitivy.java private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); /** set display view */ // connect.setVisibility(View.GONE); disconnect.setVisibility(View.GONE); logo.setVisibility(View.GONE); 9/27/2013 connect.setOnClickListener(new OnClickListener() If you want to{test it so far, you must comment this line and @Override public void onClick(View v) { plug in a real device btAdapter = BluetoothAdapter.getDefaultAdapter(); if (btAdapter.isEnabled()) { String address = btAdapter.getAddress(); String name = btAdapter.getName(); String statusText = name+":"+address; statusUpdate.setText(statusText); } else { statusUpdate.setText("Bluetooth is not on"); ); } http:// } www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 59 src/packageName/MainActitivy.java private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); /** set display view */ // connect.setVisibility(View.GONE); disconnect.setVisibility(View.GONE); logo.setVisibility(View.GONE); 9/27/2013 connect.setOnClickListener(new OnClickListener() If you comment{the line and try to emulate it, you will get an @Override public void onClick(View v) { error message because there is no real device present btAdapter = BluetoothAdapter.getDefaultAdapter(); if (btAdapter.isEnabled()) { String address = btAdapter.getAddress(); String name = btAdapter.getName(); String statusText = name+":"+address; statusUpdate.setText(statusText); } else { statusUpdate.setText("Bluetooth is not on"); ); } http:// } www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 60 src/packageName/MainActitivy.java • Before we go on: – Move this section of code to the setupUI() method btAdapter = BluetoothAdapter.getDefaultAdapter(); if (btAdapter.isEnabled()) { String address = btAdapter.getAddress(); String name = btAdapter.getName(); String statusText = name+":"+address; statusUpdate.setText(statusText); } else { connect.setVisibility(View.VISIBLE); statusUpdate.setText("Bluetooth is not on"); } – This was done because we really want to always check to see if the Bluetooth is enabled 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 61 src/packageName/MainActitivy.java • Before we go on: private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); /** set display view */ disconnect.setVisibility(View.GONE); logo.setVisibility(View.GONE); btAdapter = BluetoothAdapter.getDefaultAdapter(); if (btAdapter.isEnabled()) { So this is how your String address = btAdapter.getAddress(); setupUI() method String name = btAdapter.getName(); should look now String statusText = name+":"+address; (with that section statusUpdate.setText(statusText); of code moved) } else { connect.setVisibility(View.VISIBLE); statusUpdate.setText("Bluetooth is not on"); } } // End of setupUI () – The author of this lecture rearranged a section of code 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 62 Write the code necessary to connect to the BT when we click on [CONNECT] 9/27/2013 63 Connect to Bluetooth Adapter • Connectrate on just the Annonymous Inner Class for the Connect Button – What we have so far: connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { } }); – Add some lines 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 64 Connect to Bluetooth Adapter connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED; String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE; IntentFilter filter = new IntentFilter(actionStateChanged); //registerReceiver(bluetoothState, filter); startActivityForResult(new Intent (actionRequestEnable), 0); } }); This is a String for a Broadcast Action that will broadcast that the Bluetooth adapter has changed state: i.e., On or Off. So, we will have to implement (below) a broadcast receiver 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 65 Connect to Bluetooth Adapter connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED; String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE; IntentFilter filter = new IntentFilter(actionStateChanged); //registerReceiver(bluetoothState, filter); startActivityForResult(new Intent (actionRequestEnable), 0); } }); Creates a string for an activity: A pop up a dialog box that will ask the user if he wants to turn the bluetooth adapter on or not 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 66 Connect to Bluetooth Adapter connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED; String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE; IntentFilter filter = new IntentFilter(actionStateChanged); //registerReceiver(bluetoothState, filter); startActivityForResult(new Intent (actionRequestEnable), 0); } }); The Intent is what actually displays the ACTION_STATE_CHANGED string 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 67 Connect to Bluetooth Adapter connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED; String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE; IntentFilter filter = new IntentFilter(actionStateChanged); //registerReceiver(bluetoothState, filter); startActivityForResult(new Intent (actionRequestEnable), 0); } }); We have to register a Broadcast Receiver to accept the ACTION_STATE_CHANGED sting. But, until the broadcast receiver is actually created, this line will give an error 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 68 Connect to Bluetooth Adapter connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED; String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE; IntentFilter filter = new IntentFilter(actionStateChanged); //registerReceiver(bluetoothState, filter); startActivityForResult(new Intent (actionRequestEnable), 0); } }); Then, we start a new Intent (and wait for a result) so that the program will know what the user’s response was 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 69 Connect to Bluetooth Adapter connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED; String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE; IntentFilter filter = new IntentFilter(actionStateChanged); //registerReceiver(bluetoothState, filter); startActivityForResult(new Intent (actionRequestEnable), 0); } }); So, now we need to test all this, but the emulator will not show anything because there is no emulator Bluetooth device. So, now an actual Android Device must be plugged in so that the project can be tested. 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 70 Connect to Bluetooth Adapter • To test this, plug in the Android device and click on DDMS in the Eclipse IDE • Take a screen shot of the device – Ensure that Bluetooth is Off • The app is going to take care of turning it on 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 71 Connect to Bluetooth Adapter • Bluetooth is off 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 72 Connect to Bluetooth Adapter • Bluetooth is off • In the IDE, choose the Run MainActivity.java button to start the emulation 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 73 Connect to Bluetooth Adapter • TextView indicates that the “Bluetooth is not on” • Press the [Connect Bluetooth] button on the device 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 74 Connect to Bluetooth Adapter • Refresh the screen and you should see the dialog box • Press [Yes] 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 75 Connect to Bluetooth Adapter • You won’t see anything on the main screen 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 76 Connect to Bluetooth Adapter • But go back to system settings and you should see that Bluetooth is now on 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 77 Connect to Bluetooth Adapter connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED; String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE; IntentFilter filter = new IntentFilter(actionStateChanged); //registerReceiver(bluetoothState, filter); startActivityForResult(new Intent (actionRequestEnable), 0); } }); So, Bluetooth was turned on, but we were not notified of the change. That is the benefit of implementing a Broadcast Receiver 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 78 Implement the Broadcast Receiver 9/27/2013 79 The Broadcast Receiver connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED; String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE; IntentFilter filter = new IntentFilter(actionStateChanged); registerReceiver(bluetoothState, filter); startActivityForResult(new Intent (actionRequestEnable), 0); } }); First, uncomment the registerReceiver line 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 80 The Broadcast Receiver connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED; String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE; IntentFilter filter = new IntentFilter(actionStateChanged); registerReceiver(bluetoothState, filter); startActivityForResult(new Intent (actionRequestEnable), 0); } }); First, uncomment the registerReceiver line Then, enter the block of code for the Broadcast Receiver. Place it before the onCreate() method 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 81 The Broadcast Receiver (part 1) BroadcastReceiver bluetoothState = new BroadcastReceiver () { @Override public void onReceive (Context context, Intent intent) { String prevStateExtra = BluetoothAdapter.EXTRA_PREVIOUS_STATE; String stateExtra = BluetoothAdapter.EXTRA_STATE; int state = intent.getIntExtra(stateExtra, -1); //int prevState = intent.getIntExtra(prevStateExtra, -1); String toastText=""; switch (state) { case (BluetoothAdapter.STATE_TURNING_ON): { This is the first toastText="Bluetooth turning on"; part of the Toast.makeText(MainActivity.this, toastText, Broadcast Receiver Toast.LENGTH_SHORT).show(); (it wouldn’t all break; fit on one page) } case (BluetoothAdapter.STATE_ON): { toastText="Bluetooth On"; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); setupUI(); break; 9/27/2013 } http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 82 The Broadcast Receiver (part 1) BroadcastReceiver bluetoothState = new BroadcastReceiver () { @Override public void onReceive (Context context, Intent intent) { String prevStateExtra = BluetoothAdapter.EXTRA_PREVIOUS_STATE; String stateExtra = BluetoothAdapter.EXTRA_STATE; int state = intent.getIntExtra(stateExtra, -1); //int prevState = intent.getIntExtra(prevStateExtra, -1); String toastText=""; Creates a new switch (state) { case (BluetoothAdapter.STATE_TURNING_ON): BroadcastReceiver and its onReceive() method. { The onReceive() method toastText="Bluetooth turning on"; executes whenever a new Toast.makeText(MainActivity.this, toastText, broadcast message is Toast.LENGTH_SHORT).show(); sent out by the program break; } case (BluetoothAdapter.STATE_ON): { toastText="Bluetooth On"; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); setupUI(); break; 9/27/2013 } http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 83 The Broadcast Receiver (part 1) BroadcastReceiver bluetoothState = new BroadcastReceiver () { @Override public void onReceive (Context context, Intent intent) { String prevStateExtra = BluetoothAdapter.EXTRA_PREVIOUS_STATE; String stateExtra = BluetoothAdapter.EXTRA_STATE; int state = intent.getIntExtra(stateExtra, -1); //int prevState = intent.getIntExtra(prevStateExtra, -1); String toastText=""; switch (state) { case (BluetoothAdapter.STATE_TURNING_ON): Used as an int extra field in { ACTION_STATE_CHANGED toastText="Bluetooth turning on"; intents to request the previous Toast.makeText(MainActivity.this, toastText, power state Toast.LENGTH_SHORT).show(); break; Possible values are: STATE_OFF, } STATE_TURNING_ON, case (BluetoothAdapter.STATE_ON): STATE_ON, { STATE_TURNING_OFF toastText="Bluetooth On"; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); setupUI(); break; 9/27/2013 } http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 84 The Broadcast Receiver (part 1) BroadcastReceiver bluetoothState = new BroadcastReceiver () { @Override public void onReceive (Context context, Intent intent) { String prevStateExtra = BluetoothAdapter.EXTRA_PREVIOUS_STATE; String stateExtra = BluetoothAdapter.EXTRA_STATE; int state = intent.getIntExtra(stateExtra, -1); //int prevState = intent.getIntExtra(prevStateExtra, -1); String toastText=""; switch (state) { case (BluetoothAdapter.STATE_TURNING_ON): Declaring state and prevState { (not used yet, so it is toastText="Bluetooth turning on"; commented). The identifier Toast.makeText(MainActivity.this, toastText, state holds the current state of Toast.LENGTH_SHORT).show(); the bluetooth device and break; getIntExtra retreives that state } case (BluetoothAdapter.STATE_ON): { toastText="Bluetooth On"; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); setupUI(); break; 9/27/2013 } http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 85 The Broadcast Receiver (part 1) BroadcastReceiver bluetoothState = new BroadcastReceiver () { @Override public void onReceive (Context context, Intent intent) { String prevStateExtra = BluetoothAdapter.EXTRA_PREVIOUS_STATE; String stateExtra = BluetoothAdapter.EXTRA_STATE; int state = intent.getIntExtra(stateExtra, -1); //int prevState = intent.getIntExtra(prevStateExtra, -1); String toastText=""; switch (state) { case (BluetoothAdapter.STATE_TURNING_ON): { toastText="Bluetooth turning on"; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); Then, we are going to have a toast break; (a pop up message window that } will display the different states of case (BluetoothAdapter.STATE_ON): the bluetooth device as it turns on { and off toastText="Bluetooth On"; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); setupUI(); break; 9/27/2013 } http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 86 The Broadcast Receiver (part 1) BroadcastReceiver bluetoothState = new BroadcastReceiver () { @Override public void onReceive (Context context, Intent intent) { String prevStateExtra = BluetoothAdapter.EXTRA_PREVIOUS_STATE; String stateExtra = BluetoothAdapter.EXTRA_STATE; int state = intent.getIntExtra(stateExtra, -1); //int prevState = intent.getIntExtra(prevStateExtra, -1); String toastText=""; switch (state) { case (BluetoothAdapter.STATE_TURNING_ON): { toastText="Bluetooth turning on"; Toast.makeText(MainActivity.this, toastText, The switch-case block reads the Toast.LENGTH_SHORT).show(); current state of the device and break; then displays different messages } based on its value case (BluetoothAdapter.STATE_ON): { toastText="Bluetooth On"; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); setupUI(); break; 9/27/2013 } http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 87 The Broadcast Receiver (part 1) BroadcastReceiver bluetoothState = new BroadcastReceiver () { @Override public void onReceive (Context context, Intent intent) { String prevStateExtra = BluetoothAdapter.EXTRA_PREVIOUS_STATE; String stateExtra = BluetoothAdapter.EXTRA_STATE; int state = intent.getIntExtra(stateExtra, -1); //int prevState = intent.getIntExtra(prevStateExtra, -1); String toastText=""; switch (state) { case (BluetoothAdapter.STATE_TURNING_ON): { toastText="Bluetooth turning on"; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); break; The setupUI() is executed again for } either the Bluetooth ON or OFF case (BluetoothAdapter.STATE_ON): states, so that the main screen can { be redrawn properly toastText="Bluetooth On"; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); setupUI(); break; 9/27/2013 } http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 88 The Broadcast Receiver (part 2) case (BluetoothAdapter.STATE_TURNING_OFF): { toastText="Bluetooth turning on"; Toast.makeText(MainActivity.this, toastText,Toast.LENGTH_SHORT).show(); break; The switch-case block reads the } current state of the device and case (BluetoothAdapter.STATE_OFF): then displays different messages { based on its value toastText="Bluetooth Off"; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); setupUI(); break; } } } }; 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 89 The Broadcast Receiver (part 2) case (BluetoothAdapter.STATE_TURNING_OFF): { toastText="Bluetooth turning on"; Toast.makeText(MainActivity.this, toastText,Toast.LENGTH_SHORT).show(); break; } case (BluetoothAdapter.STATE_OFF): { toastText="Bluetooth Off"; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); setupUI(); The setupUI() is executed again so break; that the main screen can be } redrawn properly } } }; We still have one more thing to take care of. In the setupUI() method we had turned off the disconnect button and the image. We need to fix that 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 90 The Broadcast Receiver • Before we go on: private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); These are the lines /** set display view */ that need to be disconnect.setVisibility(View.GONE); edited logo.setVisibility(View.GONE); btAdapter = BluetoothAdapter.getDefaultAdapter(); if (btAdapter.isEnabled()) { String address = btAdapter.getAddress(); String name = btAdapter.getName(); String statusText = name+":"+address; statusUpdate.setText(statusText); } else { connect.setVisibility(View.VISIBLE); statusUpdate.setText("Bluetooth is not on"); } } // End of setupUI () – The author of this lecture rearranged a section of code 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 91 The Broadcast Receiver • Before we go on: private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); /** set display view */ btAdapter = BluetoothAdapter.getDefaultAdapter(); if (btAdapter.isEnabled()) { String address = btAdapter.getAddress(); String name = btAdapter.getName(); String statusText = name+":"+address; statusUpdate.setText(statusText); When the BT device disconnect.setVisibility(View.VISIBLE); is enable, we want logo.setVisibility(View.VISIBLE); to show the image connect.setVisibility(View.GONE); and the Disconnect } else { button connect.setVisibility(View.VISIBLE); statusUpdate.setText("Bluetooth is not on"); } } // End of setupUI () – The author of this lecture rearranged a section of code 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 92 The Broadcast Receiver • Before we go on: private void setupUI() { /** get objects, defined in activity_main.xml */ final TextView statusUpdate = (TextView)findViewById(R.id.textView1); final Button connect = (Button) findViewById(R.id.button1); final Button disconnect = (Button) findViewById(R.id.button2); final ImageView logo = (ImageView) findViewById(R.id.imageView2); /** set display view */ btAdapter = BluetoothAdapter.getDefaultAdapter(); if (btAdapter.isEnabled()) { String address = btAdapter.getAddress(); String name = btAdapter.getName(); String statusText = name+":"+address; statusUpdate.setText(statusText); disconnect.setVisibility(View.VISIBLE); And then, when the logo.setVisibility(View.VISIBLE); BT device is connect.setVisibility(View.GONE); disabled, we want } else { to turn off the connect.setVisibility(View.VISIBLE); image and show the disconnect.setVisibility(View.GONE); connect button logo.setVisibility(View.GONE); statusUpdate.setText("Bluetooth is not on"); } } // End of setupUI () – The author of this lecture rearranged a section of code 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 93 Emulate Again • First, turn off the Bluetooth Adapter and plug in the Android Device 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 94 Emulate Again • Start the Emulator and press the connect button 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 95 Emulate Again • Press Yes for permission to turn the Bluetooth on 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 96 Emulate Again • And the Bluetooth is turned on and this screen comes up • The toast message was too fast to catch • The disconnect button doesn’t do anything yet 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 97 Disable Bluetooth • We now have to setup the handler for the disconnect button • It is a lot simpler than everything we’ve done so far 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 98 Disable Bluetooth disconnect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { btAdapter.disable(); connect.setVisibility(View.VISIBLE); disconnect.setVisibility(View.GONE); logo.setVisibility(View.GONE); statusUpdate.setText("Bluetooth Off"); } }); All we have to do is disable the adapter, then turn off the disconnect button and the image, trun on the connect button, and print “Bluetooth Off” the TextView area of the screen 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 99 Discovering Bluetooth Devices 9/27/2013 100 Discovering Bluetooth Devices • Before the Bluetooth devices can establish a Bluetooth Socket to communicate, they must: – Discover each other – Create a bonded pair • Our Android device must be set to be discovered 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 101 Discovering Bluetooth Devices • Android devices have discoverability disabled by default • To trun on discoverability, the user must provide permission – Start a new Activity using • ACTION_REQUEST_DISCOVERABLE 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 102 Discovering Bluetooth Devices • After Bluetooth is activated this device must find available devices – Use the BluetoothAdapter’s startdiscovery() method – Requires registering a BroadcastReceiver to listen for ACTION_FOUND events • Tells the App when a new Bluetooth device has been discovered • Our current Broadcast Receiver only implemented an onReceive() method 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 103 Scanning • There are different ways of scanning for discoverability • To find which one is set, call getScanMode on the Bluetooth Adapter – Returns: • SCAN_MODE_CONNECTABLE_DISCOVERABLE – Discoverable for any device performing a discovery scan • SCAN_MODE_CONNECTABLE – Only devices that have previously been bonded can be found • SCAN_MODE_NONE – Discoverability is off 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 104 Pairing with Bonded Devices • Bonded devices are those that have been paired with the current device in the past • One connects as a server (our Android device) and the other as a client – Use the BluetoothSocket and BluetoothServerSocket classes – Use the getBondedDevices () method Set <BluetoothDevice> pairedDevices = btAdapter.getBondedDevice; 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 105 Pairing with Bonded Devices • To establish a connection with another device you must implement • Client-side Socket or • Server-side Socket – After the server and client are bonded • There is a connected Bluetooth socket for each device on the same RFCOMM – Radio Frequency Communication – Or Bluetooth Transport Protocol btAdapter.listenUsingRfcommWithServiceRecord(name, uuid); 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 106 Pairing with Bonded Devices • Bluetooth Service Discovery Protocol (SDP) – Enables the device to register services to the SDP database – Enables the device to query the database for available services – Use SDP on a device to find the UUID of the service with which you want to connect 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 107 UUID • Universally Unique Identifier – Used for identification purposes – 128 bit number presented in hex form • Example: 8b28e550-7fef-11e1-b0c4-0800200c9a66 – You can get one for your Apps at: • http://www.famkruithof.net/uuid/uuidgen • Go to this URL and a unique UUID will be generated for you – It is then hardcoded into the App 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 108 UUID • Universally Unique Identifier – Used for identification purposes – 128 bit number presented in hex form • Example: 8b28e550-7fef-11e1-b0c4-0800200c9a66 – You can get one for your Apps at: • http://www.famkruithof.net/uuid/uuidgen • Go to this URL and a unique UUID will be generated for you – It is then hardcoded into the App 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 109 Back to the connect button handler • Change the connect button’s onClickListener () method • The one we have already created, allowed the App to turn on the Bluetooth device • Now we want to enable the Bluetooth and perform discovering simultaneously • Go to the connect.onClickListener() method and comment everything there 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 110 Back to the connect button handler connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED; //String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE; //IntentFilter filter = new IntentFilter(actionStateChanged); //registerReceiver(bluetoothState, filter); //startActivityForResult(new Intent (actionRequestEnable), 0); String scanModeChanged = BluetoothAdapter.ACTION_SCAN_MODE_CHANGED; String beDiscoverable = BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE; IntentFilter filter = new IntentFilter(scanModeChanged); registerReceiver(bluetoothState, filter); startActivityForResult(new Intent (beDiscoverable), DISCOVERY_REQUEST); } So, we basically setup a few new Strings as }); we did before, a new Intent, and registered the BroadcastReceiver. The we started the new Activity, waiting for the result saying when the devices were connected 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 111 Back to the connect button handler connect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //String actionStateChanged = BluetoothAdapter.ACTION_STATE_CHANGED; //String actionRequestEnable = BluetoothAdapter.ACTION_REQUEST_ENABLE; //IntentFilter filter = new IntentFilter(actionStateChanged); //registerReceiver(bluetoothState, filter); //startActivityForResult(new Intent (actionRequestEnable), 0); String scanModeChanged = BluetoothAdapter.ACTION_SCAN_MODE_CHANGED; String beDiscoverable = BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE; IntentFilter filter = new IntentFilter(scanModeChanged); registerReceiver(bluetoothState, filter); startActivityForResult(new Intent (beDiscoverable), DISCOVERY_REQUEST); } }); DISCOVERY_REQUEST should give an error until you go to the top and define this constant public class MainActivity extends Activity { protected static final int DISCOVERY_REQUEST = 1; 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 112 onActivityResult() • We ended with a call to startActivityForResult (new Intent……); • Now, we need to develop a method to handle the result. • We call it onActivityResult() – Shown on the next page 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 113 onActivityResult() @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode = = DISCOVERY_REQUEST) { Toast.makeText(MainActivity.this, "Discovery in progress", Toast.LENGTH_SHORT); setupUI(); findDevices(); } } Basically, this method will determine if request code says that a discovery is in progress, and if so, show that message in a toast. Then it will call the setupUI() method again to refresh the screen. 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 114 findDevices() @Override private void findDevices(){ String lastUsedRemoteDevice = getLastUsedRemoteDevice(); if (lastUsedRemoteDevice != null) { toastText = "Checking for known paired devices, namely:” +lastUsedRemoteDevice; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); // see if this device is in a list currently visible devices Set <BluetoothDevice> pairedDevices = btAdapter.getBondedDevices(); for (BluetoothDevice pairedDevice : pairedDevices) { toastText = "Found device: "+pairedDevice.getName() + "@" + lastUsedRemoteDevice; Toast.makeText(MainActivity.this,toastText,Toast.LENGTH_SHORT).show(); remoteDevice = pairedDevice; } } } This method should generate a few errors due to methods that have not been declared yet 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 115 findDevices() @Override private void findDevices(){ String lastUsedRemoteDevice = getLastUsedRemoteDevice(); if (lastUsedRemoteDevice != null) { toastText = "Checking for known paired devices, namely:” +lastUsedRemoteDevice; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); // see if this device is in a list currently visible devices Set <BluetoothDevice> pairedDevices = btAdapter.getBondedDevices(); for (BluetoothDevice pairedDevice : pairedDevices) { toastText = "Found device: "+pairedDevice.getName() + "@" + lastUsedRemoteDevice; Toast.makeText(MainActivity.this,toastText,Toast.LENGTH_SHORT).show(); remoteDevice = pairedDevice; } To take care of most of these errors, type the } following with the other variable declarations } at the top of the file: public String toastText = ""; private BluetoothDevice remoteDevice; 9/27/2013 Takes care of all but one error http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 116 findDevices() • There are three more things to do • We have to declare the getLastUsedRemoteDevice() method • Next page • In the previous method, we defined instructions in case the lastUsedRemoteDevice was NOT null • We have to put in the instructions for what to do if it is null • We have to declare a new Broadcast Receiver called discoveryResult 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 117 getLastUsedRemoteDevices() private String getLastUsedRemoteDevice() { SharedPreferences prefs = getPreferences(MODE_PRIVATE); String result = prefs.getString("LAST_REMOTE_DEVICE_ADDRESS", null); return result; } Looking for previous devices that have been used with this before and returns their address 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 118 2nd if in the findDevices() method if (remoteDevice == null) { toastText="Starting discovery for remote devices...."; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); // Start Discovery if (btAdapter.startDiscovery()) { toastText="Discovery Thread started... Scanning for Devices"; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); registerReceiver(discoveryResult, new IntentFilter(BluetoothDevice.ACTION_FOUND)); } } This is the second “if” in case the remoteDevice is null: if the device had never connected to another Bluetooth device before 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 119 discoveryResult: BroadcastReceiver discoveryResult = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent){ String remoteDeviceName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME); BluetoothDevice remoteDevice; remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); toastText = "Discovered: " + remoteDeviceName; Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT).show(); //statusUpdate.setText(statusText); } }; Create a couple of strings. One is for the remoteDevice name. then we create a toast that will display the device name. At this time I have commented the last line that will update the main screens TextView 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 120 findDevices() • That takes care of most of it. • This App (so far) will enable/disable Bluetooth • Discover and connect to remote device • We still have to get a socket and transfer data between devices • Did that in the previous presentation • At this point, it just takes experience 9/27/2013 http:// www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 121 Summary • We discussed a lot!! – We discussed exactly what Bluetooth is: • Basically a wireless communications protocol • General Terms: • Bonded, paired, discover, scan, threads, etc • Turning Bluetooth off/on from your APP: • We looked very closely at methods to turn Bluetootj on/off, • Discover devices • Connect devices, etc 9/27/2013 http://www.youtube.com/watch?v=E6VlPklnQMY&list=PLB4253C81CD49FF26 122