Mobile Programming Lecture 9. Bound Services, Location, Sensors, IntentFilter

Similar documents
ELET4133: Embedded Systems. Topic 15 Sensors

register/unregister for Intent to be activated if device is within a specific distance of of given lat/long

Android Help. Section 8. Eric Xiao

Xin Pan. CSCI Fall

Android. Mobile operating system developed by Google A complete stack. Based on the Linux kernel Open source under the Apache 2 license

Upcoming Assignments Quiz today Web Ad due Monday, February 22 Lab 5 due Wednesday, February 24 Alpha Version due Friday, February 26

Android Apps Development for Mobile Game Lesson 5

Activities. Repo:

1. Location Services. 1.1 GPS Location. 1. Create the Android application with the following attributes. Application Name: MyLocation

CMSC436: Fall 2013 Week 3 Lab

Mobile Application (Design and) Development

CS 528 Mobile and Ubiquitous Computing Lecture 3b: Android Activity Lifecycle and Intents Emmanuel Agu

CS 193A. Multiple Activities and Intents

Mobile Programming Lecture 5. Composite Views, Activities, Intents and Filters

An Overview of the Android Programming

Understand applications and their components. activity service broadcast receiver content provider intent AndroidManifest.xml

Press project on the left toolbar if it doesn t show an overview of the app yet.

Designing Apps Using The WebView Control

Sensor & SensorManager SensorEvent & SensorEventListener Filtering sensor values Example applications

Android Security Lab WS 2013/14 Lab 2: Android Permission System

Getting Started ArcGIS Runtime SDK for Android. Andy

ANDROID APPS DEVELOPMENT FOR MOBILE AND TABLET DEVICE (LEVEL I)

filled by the user and display it by setting the value of view elements. Uses display.xml as layout file to display the result.

ANDROID APPS DEVELOPMENT FOR MOBILE AND TABLET DEVICE (LEVEL I)

Terms: MediaPlayer, VideoView, MediaController,

Android Fundamentals - Part 1

Spring Lecture 9 Lecturer: Omid Jafarinezhad

Lab 5 Periodic Task Scheduling

Mobile Development Lecture 8: Intents and Animation

Software Practice 3 Today s lecture Today s Task Porting Android App. in real device

CS 234/334 Lab 1: Android Jump Start

CS378 - Mobile Computing. Anatomy of an Android App and the App Lifecycle

Intents. 18 December 2018 Lecture Dec 2018 SE 435: Development in the Android Environment 1

Android for Ubiquitous Computing Researchers. Andrew Rice University of Cambridge 17-Sep-2011

Mobile Programming Lecture 3. Resources, Selection, Activities, Intents

Services. Marco Ronchetti Università degli Studi di Trento

Android Ecosystem and. Revised v4presenter. What s New

Topics Related. SensorManager & Sensor SensorEvent & SensorEventListener Filtering Sensor Values Example applications

Developing Android Applications

8/30/15 MOBILE COMPUTING. CSE 40814/60814 Fall How many of you. have implemented a command-line user interface?

Programming with Android: Intents. Luca Bedogni. Dipartimento di Scienze dell Informazione Università di Bologna

UNDERSTANDING ACTIVITIES

10.1 Introduction. Higher Level Processing. Word Recogniton Model. Text Output. Voice Signals. Spoken Words. Syntax, Semantics, Pragmatics

INTRODUCTION TO ANDROID

Exercise 1: First Android App

EMBEDDED SYSTEMS PROGRAMMING Android Services

Introduction to Android Multimedia

Overview of Activities

Application Fundamentals

Android Services & Local IPC: Overview of Programming Bound Services

EMBEDDED SYSTEMS PROGRAMMING Application Basics

Writing Efficient Drive Apps for Android. Claudio Cherubino / Alain Vongsouvanh Google Drive Developer Relations

Services Broadcast Receivers Permissions

Services are software components designed specifically to perform long background operations.

Services & Interprocess Communication (IPC) CS 282 Principles of Operating Systems II Systems Programming for Android

Minds-on: Android. Session 2

Android Activities. Akhilesh Tyagi

Services. service: A background task used by an app.

Vienos veiklos būsena. Theory

Voice Control SDK. Vuzix M100 Developer SDK. Developer Documentation. Ron DiNapoli Vuzix Corporation Created: July 22, 2015 Last Update: July 22, 2015

Internet of Things Sensors - Part 1 Location Services

CS 370 Android Basics D R. M I C H A E L J. R E A L E F A L L

Solving an Android Threading Problem

Multiple Activities. Many apps have multiple activities

Workshop. 1. Create a simple Intent (Page 1 2) Launch a Camera for Photo Taking

Using Libraries, Text-to-Speech, Camera. Lecture 12

Midterm Examination. CSCE 4623 (Fall 2017) October 20, 2017

Introduction To Android

Mobila applikationer och trådlösa nät

Have a development environment in 256 or 255 Be familiar with the application lifecycle

Real-Time Embedded Systems

Embedded Systems Programming - PA8001

Produced by. Design Patterns. MSc in Computer Science. Eamonn de Leastar

Android. Operating System and Architecture. Android. Screens. Main features

Mobile Programming Practice Background processing AsynTask Service Broadcast receiver Lab #5

Loca%on Support in Android. COMP 355 (Muppala) Location Services and Maps 1

Mobile Programming Lecture 2. Layouts, Widgets, Toasts, and Event Handling

Internal Services. CSE 5236: Mobile Application Development Instructor: Adam C. Champion, Ph.D. Course Coordinator: Dr.

App Development for Android. Prabhaker Matet

CS 4518 Mobile and Ubiquitous Computing Lecture 4: Data-Driven Views, Android Components & Android Activity Lifecycle Emmanuel Agu

Mobile Application Development Android

Using Intents to Launch Activities

Understanding Application

Android framework overview Activity lifecycle and states

Lab 1: Getting Started With Android Programming

Lifecycle Callbacks and Intents

Overview. Lecture: Implicit Calling via Share Implicit Receiving via Share Launch Telephone Launch Settings Homework

App Development for Smart Devices. Lec #8: Android Sensors

LifeStreet Media Android Publisher SDK Integration Guide

Android Programming Lecture 7 9/23/2011

LECTURE 12 BROADCAST RECEIVERS

LECTURE NOTES OF APPLICATION ACTIVITIES

Programming with Android: Activities and Intents. Dipartimento di Informatica Scienza e Ingegneria Università di Bologna

CS 4518 Mobile and Ubiquitous Computing Lecture 5: Rotating Device, Saving Data, Intents and Fragments Emmanuel Agu

Chapter 5 Defining the Manifest

Android Programmierung leichtgemacht. Lars Vogel

Islamic University of Gaza. Faculty of Engineering. Computer Engineering Department. Mobile Computing ECOM Eng. Wafaa Audah.

Create new Android project in Android Studio Add Button and TextView to layout Learn how to use buttons to call methods. Modify strings.

CS378 -Mobile Computing. Anatomy of and Android App and the App Lifecycle

Android Programming Lecture 2 9/7/2011

Transcription:

Mobile Programming Lecture 9 Bound Services, Location, Sensors, IntentFilter

Agenda Bound Services Location Sensors Starting an Activity for a Result Understanding Implicit Intents

Bound Service When you create a Bound Service, you must provide an IBinder that provides the programming interface that clients can use to interact with the Service There are 3 ways that you can provide this interface: 1. Extending the Binder class 2. Using a Messenger 3. Using AIDL

Bound Service

Bound Service - 1 extending Binder This is the preferred technique when your service is merely a background worker for your own application The only reason you would not create your interface this way is because your service is used by other applications or across separate processes

Bound Service - 1 extending Binder Here's how to set it up 1. In your service, create an instance of Binder that returns the current Service instance, which has public methods the client can call 2. Return this instance of Binder from the onbind() callback method 3. In the client, receive the Binder from the onserviceconnected() callback method and make calls to the bound service using the methods provided

Bound Service - 1 extending Binder See BoundServiceBinder Example ServiceConnection class monitors the connection between the client and the Service When a Service is bound, the binder returned is returned to the onserviceconnected() method of ServiceConnection

Bound Service - 2 using Messenger If you need your interface to work across different processes, you can create an interface for the service with a Messenger The service defines a Handler that responds to different types of Message objects Additionally, the client can define a Messenger of it's own so the service can send messages back. This is the simplest way to perform interprocess communication (IPC), because the Messenger queues all requests into a single thread so that you don't have to design your service to be thread-safe

Bound Service - 2 using Messenger Notice that the handlemessage() method in the Handler is where the service receives the incoming Message and decides what to do, based on the what member.

Bound Service - 2 using Messenger See BoundServiceMessenger Example

Bound Service - 3 using the AIDL Using AIDL is way too specific Has benefits over extending Binder Supports parcelable objects Can be accessed from different applications (API) Handles multithreading We won't cover this, but you can read more about it here

Location Providers To obtain user location, you can use GPS Most accurate But Consumes battery power fast Takes a while to determine location Network Location Provider

Location - LocationManager Requesting Location Updates To get the user s location, you need to use the LocationManager, which is a system service This returns a Location object, which can tell you Latitude Longitude Distance between two locations (comparing to another Location object) Accuracy of the Location in meters Direction of travel in degrees Speed of travel in meters per second The Location, however, does not give you any human readable address such as street name, state, or country

Location - Geocoder and Address Requesting Location Updates You can use the Location object to obtain a human-readable address by using a Geocoder Geocoder can give you a list of addresses (since it may not always be sure because of accuracy issues) Returns a List of Address objects, i.e. List<Address> Street name City State Country Zip Code

Location - Last Known Location Since GPS and Wifi location are not quite instantaneous, you can get the last known location until one of them becomes available

Location - Last Known Location final LocationManager lm = (LocationManager) getsystemservice(context.location_service); getbutton = (Button) findviewbyid(r.id.button1); tv = (TextView) findviewbyid(r.id.textview1); getbutton.setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { Location lastloc = lm.getlastknownlocation( LocationManager.NETWORK_PROVIDER); Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses; addresses = geo.getfromlocation(lastloc.getlatitude(), lastloc.getlongitude(), 1); ); if (addresses!= null) tv.settext(addresses.get(0).getaddressline(0));

Location - Last Known Location final LocationManager lm = (LocationManager) getbutton = (Button) findviewbyid(r.id.button1); tv = (TextView) findviewbyid(r.id.textview1); getbutton.setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { Location lastloc = lm.getlastknownlocation( getsystemservice(context.location_service); LocationManager.NETWORK_PROVIDER); Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses; addresses = geo.getfromlocation(lastloc.getlatitude(), Similar to getting the system service for the DownloadManager lastloc.getlongitude(), 1); ); if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0));

Location - Last Known Location final LocationManager lm = (LocationManager) getsystemservice(context.location_service); getbutton = (Button) findviewbyid(r.id.button1); tv = (TextView) findviewbyid(r.id.textview1); getbutton.setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { Location lastloc = lm.getlastknownlocation( LocationManager.NETWORK_PROVIDER); Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses; addresses = geo.getfromlocation(lastloc.getlatitude(), What was the last known location? lastloc.getlongitude(), 1); ); if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0));

Location - Last Known Location final LocationManager lm = (LocationManager) getsystemservice(context.location_service); getbutton = (Button) findviewbyid(r.id.button1); tv = (TextView) findviewbyid(r.id.textview1); getbutton.setonclicklistener(new View.OnClickListener() { We need to use @Override Geocoder to transform public void onclick(view v) longitude { and latitude to Location lastloc = lm.getlastknownlocation( an address LocationManager.NETWORK_PROVIDER); Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses; addresses = geo.getfromlocation(lastloc.getlatitude(), lastloc.getlongitude(), 1); ); if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0));

Location - Last Known Location final LocationManager lm = (LocationManager) getsystemservice(context.location_service); getbutton = (Button) findviewbyid(r.id.button1); tv = (TextView) findviewbyid(r.id.textview1); getbutton.setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { We will store said Location lastloc = lm.getlastknownlocation( address here LocationManager.NETWORK_PROVIDER); Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses; addresses = geo.getfromlocation(lastloc.getlatitude(), lastloc.getlongitude(), 1); ); if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0));

Location - Last Known Location final LocationManager lm = (LocationManager) getsystemservice(context.location_service); getbutton = (Button) findviewbyid(r.id.button1); tv = (TextView) findviewbyid(r.id.textview1); getbutton.setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { Let's get a List of Location lastloc = lm.getlastknownlocation( Addresses (although there may be only LocationManager.NETWORK_PROVIDER); 1 Geocoder geo = new Geocoder(getApplicationContext()); sometimes) List<Address> addresses; addresses = geo.getfromlocation(lastloc.getlatitude(), lastloc.getlongitude(), 1); ); if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0));

Location - Last Known Location final LocationManager lm = (LocationManager) getsystemservice(context.location_service); getbutton = (Button) findviewbyid(r.id.button1); tv = (TextView) findviewbyid(r.id.textview1); getbutton.setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { Location lastloc = lm.getlastknownlocation( Pass LocationManager.NETWORK_PROVIDER); the latitude... Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses; addresses = geo.getfromlocation(lastloc.getlatitude(), lastloc.getlongitude(), 1); ); if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0));

Location - Last Known Location final LocationManager lm = (LocationManager) getsystemservice(context.location_service); getbutton = (Button) findviewbyid(r.id.button1); tv = (TextView) findviewbyid(r.id.textview1); getbutton.setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { Location lastloc = lm.getlastknownlocation( LocationManager.NETWORK_PROVIDER); Geocoder geo = new Geocoder(getApplicationContext()); the longitude... List<Address> addresses; addresses = geo.getfromlocation(lastloc.getlatitude(), lastloc.getlongitude(), 1); ); if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0));

Location - Last Known Location final LocationManager lm = (LocationManager) getsystemservice(context.location_service); getbutton = (Button) findviewbyid(r.id.button1); tv = (TextView) findviewbyid(r.id.textview1); getbutton.setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { Location lastloc = lm.getlastknownlocation( LocationManager.NETWORK_PROVIDER); and the max number of Geocoder geo = new Geocoder(getApplicationContext()); addresses that you want to be returned List<Address> addresses; addresses = geo.getfromlocation(lastloc.getlatitude(), lastloc.getlongitude(), 1); ); if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0));

Location - Last Known Location final LocationManager lm = (LocationManager) getsystemservice(context.location_service); getbutton = (Button) findviewbyid(r.id.button1); tv = (TextView) findviewbyid(r.id.textview1); getbutton.setonclicklistener(new View.OnClickListener() { @Override public void onclick(view v) { Location lastloc = lm.getlastknownlocation( LocationManager.NETWORK_PROVIDER); Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses; addresses = geo.getfromlocation(lastloc.getlatitude(), Get the first line of the lastloc.getlongitude(), 1); first address in the list ); if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0));

Location - Last Known Location See LastKnownLocation Example

Location - Location Updates Requesting Location Updates To get actual location updates periodically, you should use a LocationListener At some point, you should stop requesting location updates, possibly when Activity loses focus You no longer need the location

Location - Location Updates final LocationManager lm = (LocationManager) getsystemservice( LOCATION_SERVICE); final LocationListener ll = new LocationListener() { @Override public void onstatuschanged(string provider, int status, Bundle extras) { @Override public void onproviderenabled(string provider) { @Override public void onproviderdisabled(string provider) { @Override public void onlocationchanged(location location) { Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses = null; addresses = geo.getfromlocation(location.getlatitude(), location.getlongitude(), 1); if (addresses!= null) tv.settext(addresses.get(0).getaddressline(0)); ; lm.removeupdates( this);

Location - Location Updates final LocationManager lm = (LocationManager) getsystemservice(location_service); final LocationListener ll = new LocationListener() { @Override public void onstatuschanged(string provider, int status, Bundle extras) { @Override public void onproviderenabled(string provider) { @Override public void onproviderdisabled(string provider) { We need to register a LocationListener if we want to get updates on the location periodically @Override public void onlocationchanged(location location) { Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses = null; addresses = geo.getfromlocation(location.getlatitude(), location.getlongitude(), 1); if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0)); ; lm.removeupdates(this);

Location - Location Updates final LocationManager lm = (LocationManager) getsystemservice(location_service); final LocationListener ll = new LocationListener() { @Override public void onstatuschanged(string provider, int status, Bundle extras) { @Override public void onproviderenabled(string provider) { @Override public void onproviderdisabled(string provider) { @Override public void onlocationchanged(location location) { Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses = null; addresses = geo.getfromlocation(location.getlatitude(), if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0)); We're forced to override these methods, although we don't use them location.getlongitude(), 1); ; lm.removeupdates(this);

Location - Location Updates final LocationManager lm = (LocationManager) getsystemservice(location_service); final LocationListener ll = new LocationListener() { @Override public void onstatuschanged(string provider, int status, Bundle extras) { @Override public void onproviderenabled(string provider) { @Override public void onproviderdisabled(string provider) { @Override public void onlocationchanged(location location) { Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses = null; addresses = geo.getfromlocation(location.getlatitude(), if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0)); In this callback method is where you code your response to a location change location.getlongitude(), 1); ; lm.removeupdates(this);

Location - Location Updates final LocationManager lm = (LocationManager) getsystemservice(location_service); final LocationListener ll = new LocationListener() { @Override public void onstatuschanged(string provider, int status, Bundle extras) { @Override public void onproviderenabled(string provider) { @Override public void onproviderdisabled(string provider) { Nothing new here... @Override public void onlocationchanged(location location) { Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses = null; addresses = geo.getfromlocation(location.getlatitude(), location.getlongitude(), 1); if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0)); ; lm.removeupdates(this);

Location - Location Updates final LocationManager lm = (LocationManager) getsystemservice(location_service); final LocationListener ll = new LocationListener() { @Override public void onstatuschanged(string provider, int status, Bundle extras) { @Override public void onproviderenabled(string provider) { @Override public void onproviderdisabled(string provider) { ; @Override public void onlocationchanged(location location) { Geocoder geo = new Geocoder(getApplicationContext()); List<Address> addresses = null; addresses = geo.getfromlocation(location.getlatitude(), if(addresses!= null) tv.settext(addresses.get(0).getaddressline(0)); lm.removeupdates(this); Let's save battery life and stop listening for updates, although you may choose to stop listening for updates at some other point if you want to location.getlongitude(), 1);

Location - Location Updates See LocationManager Example

Location - Proximity Alert Sometimes instead of retrieving the current location, you may want to know when the user arrives at a certain location For example, in turn-by-turn directions, you may want to know when the user is close to the next turning point You can use the addproximityalert() method of the LocationManager to accomplish this This registers a PendingIntent

Location - Proximity Alert @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); LocationManager lm = (LocationManager) getsystemservice(location_service); PendingIntent pi = creatependingresult(1, new Intent(), 0); Location loc = lm.getlastknownlocation(locationmanager.gps_provider); lm.addproximityalert(loc.getlatitude(), loc.getlongitude(), 10, -1, pi); Toast.makeText(this, "You're on the way", Toast.LENGTH_SHORT).show(); @Override public void onactivityresult(int reqcode, int resultcode, Intent data) { Toast.makeText(this, "You have arrived", Toast.LENGTH_SHORT).show();

Location - Proximity Alert @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); LocationManager lm = (LocationManager) getsystemservice(location_service); PendingIntent pi = creatependingresult(1, new Intent(), 0); We've used PendingIntent this way before when we talked about Services Location loc = lm.getlastknownlocation(locationmanager.gps_provider); lm.addproximityalert(loc.getlatitude(), loc.getlongitude(), 10, -1, pi); Toast.makeText(this, "You're on the way", Toast.LENGTH_SHORT).show(); @Override public void onactivityresult(int reqcode, int resultcode, Intent data) { Toast.makeText(this, "You have arrived", Toast.LENGTH_SHORT).show();

Location - Proximity Alert @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); LocationManager lm = (LocationManager) getsystemservice(location_service); Let's see how long it takes for the system to tell PendingIntent pi = creatependingresult(1, new Intent(), 0); us when we get back to our last known location Location loc = lm.getlastknownlocation(locationmanager.gps_provider); lm.addproximityalert(loc.getlatitude(), loc.getlongitude(), 10, -1, pi); Toast.makeText(this, "You're on the way", Toast.LENGTH_SHORT).show(); @Override public void onactivityresult(int reqcode, int resultcode, Intent data) { Toast.makeText(this, "You have arrived", Toast.LENGTH_SHORT).show();

Location - Proximity Alert @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); LocationManager lm = (LocationManager) getsystemservice(location_service); PendingIntent pi = creatependingresult(1, new Intent(), 0); Location loc = lm.getlastknownlocation(locationmanager.gps_provider); lm.addproximityalert(loc.getlatitude(), loc.getlongitude(), 10, -1, pi); Toast.makeText(this, "You're on the way", Toast.LENGTH_SHORT).show(); Whenever we get to that location, this callback method will handle the event @Override public void onactivityresult(int reqcode, int resultcode, Intent data) { Toast.makeText(this, "You have arrived", Toast.LENGTH_SHORT).show();

Location - Proximity Alert See LocationProximityAlert Example

Location - Permissions In order to receive location updates from NETWORK_PROVIDER or GPS_PROVIDER, you must request user permission by declaring one or both of the following permissions ACCESS_COARSE_LOCATION (Wifi location) ACCESS_FINE_LOCATION (GPS location)

Location - Mock Location You can test your location-based features by mocking location data in the Emulator http://developer.android.com/guide/topics/location/obtai ning-user-location.html#mockdata The Emulator uses the GPS provider Found under the Emulator Control View in Android Device Monitor, under the Emulator Control view You can open Android Device Monitor from Android Studio Tools > Android > Android Device Monitor

Sensor Accelerometer Gyroscope Light Orientation (DEPRECATED!) Proximity Pressure and more See SensorList Example

SensorManager SensorManager lets you access the device's sensors. Get an instance of this class by calling Context.getSystemService() with the argument SENSOR_SERVICE. Always make sure to disable sensors you don't need, especially when your activity is paused Failing to do so can drain the battery in just a few hours The system will not disable sensors automatically when the screen turns off.

SensorEvent The values for each sensor may change at some point Set up an Event Listener to take action when these change These values can be retrieved from a float values[] array, regardless of the type of sensor

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener { SensorManager msensormanager; Sensor mproximity; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout. main); msensormanager = (SensorManager)getSystemService( SENSOR_SERVICE); mproximity = msensormanager.getdefaultsensor(sensor. TYPE_PROXIMITY);...

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener { SensorManager Because we want msensormanager; to know when there's a SensorEvent, Sensor when values mproximity; of the Sensor change public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); msensormanager = (SensorManager)getSystemService(SENSOR_SERVICE); mproximity = msensormanager.getdefaultsensor(sensor.type_proximity);...

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener { SensorManager msensormanager; Sensor mproximity; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); Similar to how we got the Location service msensormanager = (SensorManager)getSystemService(SENSOR_SERVICE); mproximity = msensormanager.getdefaultsensor(sensor.type_proximity);...

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener { SensorManager msensormanager; Sensor mproximity; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); msensormanager = (SensorManager)getSystemService(SENSOR_SERVICE); mproximity = msensormanager.getdefaultsensor(sensor.type_proximity); Let's get a Sensor...

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener { SensorManager msensormanager; Sensor mproximity; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main);... msensormanager = (SensorManager)getSystemService(SENSOR_SERVICE); mproximity = msensormanager.getdefaultsensor( Sensor.TYPE_PROXIMITY); The Proximity Sensor specifically

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener { SensorManager msensormanager; Sensor mproximity; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); msensormanager = (SensorManager)getSystemService(SENSOR_SERVICE); mproximity = msensormanager.getdefaultsensor(sensor.type_proximity);... The rest of the code for this class on the next slide

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener {... oncreate() is here somewhere, on the protected previous void onresume() page { super.onresume(); msensormanager.registerlistener(this, mproximity, SensorManager.SENSOR_DELAY_NORMAL); protected void onpause() { super.onpause(); msensormanager.unregisterlistener(this); public void onsensorchanged(sensorevent event) { Toast.makeText(this, "Proximity = " + event.values[0], Toast.LENGTH_SHORT).show();

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener {... protected void onresume() { super.onresume(); msensormanager.registerlistener(this, mproximity, SensorManager.SENSOR_DELAY_NORMAL); protected void onpause() { Note that this is onresume() super.onpause(); msensormanager.unregisterlistener(this); public void onsensorchanged(sensorevent event) { Toast.makeText(this, "Proximity = " + event.values[0], Toast.LENGTH_SHORT).show();

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener {... protected void onresume() { super.onresume(); msensormanager.registerlistener(this, mproximity, We only want to listen when the Activity is visible in this case, so protected we do void this onpause() in onresume() { super.onpause(); msensormanager.unregisterlistener(this); SensorManager.SENSOR_DELAY_NORMAL); public void onsensorchanged(sensorevent event) { Toast.makeText(this, "Proximity = " + event.values[0], Toast.LENGTH_SHORT).show();

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener {... protected void onresume() { super.onresume(); msensormanager.registerlistener(this, mproximity, SensorManager.SENSOR_DELAY_NORMAL); We pass a Context... protected void onpause() { super.onpause(); msensormanager.unregisterlistener(this); public void onsensorchanged(sensorevent event) { Toast.makeText(this, "Proximity = " + event.values[0], Toast.LENGTH_SHORT).show();

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener {... protected void onresume() { super.onresume(); msensormanager.registerlistener(this, mproximity, SensorManager.SENSOR_DELAY_NORMAL); a Sensor... protected void onpause() { super.onpause(); msensormanager.unregisterlistener(this); public void onsensorchanged(sensorevent event) { Toast.makeText(this, "Proximity = " + event.values[0], Toast.LENGTH_SHORT).show();

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener {... protected void onresume() { super.onresume(); msensormanager.registerlistener(this, mproximity, protected void onpause() { super.onpause(); msensormanager.unregisterlistener(this); SensorManager.SENSOR_DELAY_NORMAL); and the rate we want sensor events to be delivered public void onsensorchanged(sensorevent event) { Toast.makeText(this, "Proximity = " + event.values[0], Toast.LENGTH_SHORT).show();

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener {... protected void onresume() { super.onresume(); msensormanager.registerlistener(this, mproximity, SensorManager.SENSOR_DELAY_NORMAL); protected void onpause() { super.onpause(); msensormanager.unregisterlistener(this); in onpause(), we want to stop listening for updates, preserving battery life public void onsensorchanged(sensorevent event) { Toast.makeText(this, "Proximity = " + event.values[0], Toast.LENGTH_SHORT).show();

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener {... protected void onresume() { super.onresume(); msensormanager.registerlistener(this, mproximity, SensorManager.SENSOR_DELAY_NORMAL); protected void onpause() { super.onpause(); msensormanager.unregisterlistener(this); This is where we take action when there is a change in Sensor values public void onsensorchanged(sensorevent event) { Toast.makeText(this, "Proximity = " + event.values[0], Toast.LENGTH_SHORT).show();

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener {... protected void onresume() { super.onresume(); msensormanager.registerlistener(this, mproximity, SensorManager.SENSOR_DELAY_NORMAL); protected void onpause() { super.onpause(); msensormanager.unregisterlistener(this); public void onsensorchanged(sensorevent event) { Toast.makeText(this, "Proximity = " + event.values[0], Toast.LENGTH_SHORT).show(); event.values[] array has important data about the sensor event

SensorEvent public class SensorExampleActivity extends Activity implements SensorEventListener {... protected void onresume() { super.onresume(); msensormanager.registerlistener(this, mproximity, SensorManager.SENSOR_DELAY_NORMAL); protected void onpause() { super.onpause(); msensormanager.unregisterlistener(this); Refer to this page for details for each type of Sensor public void onsensorchanged(sensorevent event) { Toast.makeText(this, "Proximity = " + event.values[0], Toast.LENGTH_SHORT).show();

SensorEvent See: ProximitySensor Example LightSensor Example The code change between these two examples is very small

Using Sensors to Create a NUI NUI = Natural User Interface Human Computer Interaction is moving further and further away from the mouse and keyboard. Being replaced by gestures on the device, air gestures, speech recognition, and kinetics. There are typically two phases to gesture recognition Data Gathering Gesture Detection

Touch Using Gesture Detection you can register to listen for touch events on the device. Long Press Double Tap Fling Pinch Multiple Finger gestures

Telepathy Can think of this gesture as an air gesture Passing your hand over the device without touching the screen Might think that this would require a front facing camera to process this gesture.. This would be an option but there is an easier way Use the Light Sensor to recognize the gesture And the Proximity Sensor to validate

Kinetics This is the term for gestures using the device itself Taking advantage of the accelerometer, gravity sensor, gyroscope, compass, etc ICS - Huge improvement for gyroscope Things to look out for Power consumption Sampling Rate Varies by phone and is in nanoseconds NOT milliseconds Also, it is not synced with system time! Event comes with timestamp There will always be static and random variation Accelerometer data

Microphone Using Speech is a no brainer for NUI http://developer.android.com/reference/android/spee ch/recognizerintent.html A more technical way of using the microphone requires signal processing Way, way, way outside the scope of this class

Making Sense of the Data Thresholds Time Check peaks Filter peaks that are too close Based on count Combine with sensor data to get heart rate, for example Statistics are your friend Since sensors spit out messy and noisy data Mean, median, mode, range, etc

Starting Activities & Getting Results If you created two Activities A and B, you can start B from A, and have B return some result to A instead of startactivity(intent) call startactivityforresult(intent, int)

Starting Activities & Getting Results private int MY_CODE = 29; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); public void startsecondactivity(view v) { Intent intent = new Intent(A.this, B.class); startactivityforresult(intent, MY_CODE);

Starting Activities & Getting Results private int MY_CODE = 29; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); This code is for Activity A public void startsecondactivity(view v) { Intent intent = new Intent(A.this, B.class); startactivityforresult(intent, MY_CODE);

Starting Activities & Getting Results private int MY_CODE = 29; Some number that you want to use to identify your request. #29 is nothing special here. @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); public void startsecondactivity(view v) { Intent intent = new Intent(A.this, B.class); startactivityforresult(intent, MY_CODE);

Starting Activities & Getting Results private int MY_CODE = 29; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); public void startsecondactivity(view v) { Intent intent = new Intent(A.this, B.class); startactivityforresult(intent, MY_CODE); I added a button to the XML and set the android:onclick attribute to this method

Starting Activities & Getting Results private int MY_CODE = 29; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); We have seen this before public void startsecondactivity(view v) { Intent intent = new Intent(A.this, B.class); startactivityforresult(intent, MY_CODE);

Starting Activities & Getting Results private int MY_CODE = 29; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); public void startsecondactivity(view v) { Intent intent = new Intent(A.this, B.class); startactivityforresult(intent, MY_CODE); Instead of startactivity(intent), we call startactivityforresult and give it the intent along with our "special" request code.

Starting Activities & Getting Results protected void onactivityresult(int requestcode, { int resultcode, Intent data) if(requestcode == MY_CODE) { if(resultcode == RESULT_OK) { // result is OK, add code here We also need to add this method to Activity A, to react to when the result has been returned from Activity B.

Starting Activities & Getting Results public class B extends Activity { @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.second); public void finishme(view v) { setresult(activity.result_ok, null); finish();

Starting Activities & Getting Results public class B extends Activity { @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.second); public void finishme(view v) { This code is for Activity B setresult(activity.result_ok, null); finish();

Starting Activities & Getting Results public class B extends Activity { @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.second); public void finishme(view v) { setresult(activity.result_ok, null); finish(); Assuming there's a Button with android:onclick="finishme"

Starting Activities & Getting Results public class B extends Activity { @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.second); public void finishme(view v) { setresult(activity.result_ok, null); finish(); Set the result of this Activity to OK. The second argument is an Intent, but we'll go in to this another time.

Starting Activities & Getting Results public class B extends Activity { @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.second); public void finishme(view v) { setresult(activity.result_ok, null); finish(); Finish this Activity B, which will lead to ondestroy() being called, and Activity A becoming active. onactivityresult() in A will then be called.

Starting Activities & Getting Results See StartActivityForResult Example

Starting Activities & Getting Results As another example, let's call upon an existing Android Activity for a result

Starting Activities & Getting Results static final int PICK_REQUEST = 1337; Here's our request code again @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); public void pickcontact(view v) { Intent intent = new Intent(Intent.ACTION_PICK, Phone.CONTENT_URI); startactivityforresult(intent, PICK_REQUEST); protected void onactivityresult(int requestcode, int resultcode, Intent data) { if (requestcode == PICK_REQUEST) { if (resultcode == RESULT_OK) { /* result is OK! */

Starting Activities & Getting Results static final int PICK_REQUEST = 1337; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); Tied to a Button with public void pickcontact(view v) { android:onclick="pickcontact" Intent intent = new Intent(Intent.ACTION_PICK, Phone.CONTENT_URI); startactivityforresult(intent, PICK_REQUEST); protected void onactivityresult(int requestcode, int resultcode, Intent data) { if (requestcode == PICK_REQUEST) { if (resultcode == RESULT_OK) { /* result is OK! */

Starting Activities & Getting Results static final int PICK_REQUEST = 1337; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); We use a different constructor for the Intent this time public void pickcontact(view v) { Intent intent = new Intent(Intent.ACTION_PICK, Phone.CONTENT_URI); startactivityforresult(intent, PICK_REQUEST); protected void onactivityresult(int requestcode, int resultcode, Intent data) { if (requestcode == PICK_REQUEST) { if (resultcode == RESULT_OK) { /* result is OK! */

Starting Activities & Getting Results static final int PICK_REQUEST = 1337; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); These two arguments must mean something together, they don't always do! public void pickcontact(view v) { Intent intent = new Intent(Intent.ACTION_PICK, Phone.CONTENT_URI); startactivityforresult(intent, PICK_REQUEST); protected void onactivityresult(int requestcode, int resultcode, Intent data) { if (requestcode == PICK_REQUEST) { if (resultcode == RESULT_OK) { /* result is OK! */

Starting Activities & Getting Results static final int PICK_REQUEST = 1337; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); There should be an Activity that recognizes this Intent public void pickcontact(view v) { Intent intent = new Intent(Intent.ACTION_PICK, Phone.CONTENT_URI); startactivityforresult(intent, PICK_REQUEST); protected void onactivityresult(int requestcode, int resultcode, Intent data) { if (requestcode == PICK_REQUEST) { if (resultcode == RESULT_OK) { /* result is OK! */

Starting Activities & Getting Results static final int PICK_REQUEST = 1337; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); If none exists, you will probably get Force Close public void pickcontact(view v) { Intent intent = new Intent(Intent.ACTION_PICK, Phone.CONTENT_URI); startactivityforresult(intent, PICK_REQUEST); protected void onactivityresult(int requestcode, int resultcode, Intent data) { if (requestcode == PICK_REQUEST) { if (resultcode == RESULT_OK) { /* result is OK! */

Starting Activities & Getting Results static final int PICK_REQUEST = 1337; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); public void pickcontact(view v) { Nothing new here Intent intent = new Intent(Intent.ACTION_PICK, Phone.CONTENT_URI); startactivityforresult(intent, PICK_REQUEST); protected void onactivityresult(int requestcode, int resultcode, Intent data) { if (requestcode == PICK_REQUEST) { if (resultcode == RESULT_OK) { /* result is OK! */

Starting Activities & Getting Results static final int PICK_REQUEST = 1337; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); public void pickcontact(view v) { That starts Activity B. When Intent intent = new Intent(Intent.ACTION_PICK, Phone.CONTENT_URI); Activity B has returned, the startactivityforresult(intent, result PICK_REQUEST); will be returned to this callback function protected void onactivityresult(int requestcode, int resultcode, Intent data) { if (requestcode == PICK_REQUEST) { if (resultcode == RESULT_OK) { /* result is OK! */

Starting Activities & Getting Results See PickContacts Example

Understanding Implicit Intents Implicit Intents Specify the action that should be performed and optionally the URI which should be used in conjunction with the action Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse( http://www.google.com )); The Android system searches for all the components that are registered to handle this specific action If the system only finds one component then it will launch that automatically Else it will show a dialog that will give the user the option of selecting the one they prefer If none is found, you may get an Exception

Understanding Implicit Intents How do you know which Intent Action to specify for a given Uri?

Understanding Implicit Intents There are three rules, all of which must be true for a given activity to be eligible for a given intent 1. The activity must support the specified action 2. The activity must support the stated MIME type (if supplied) 3. The activity must support all of the categories named in the intent The upshot is that you want to make your intents specific enough to find the right receiver(s), and no more specific than that.

Understanding Implicit Intents Let's take a look at what happens when when the Home key is pressed...

Understanding Implicit Intents Open LogCat Click the + button to add a new filter Enter the following Filter Name: ActivityManager Log Tag: ActivityManager Now press the Home key on your device For the Tag Column, look for ActivityManager For the Text Column, look for anything beginning with "Starting: Intent..." The last one should be the Intent that was used to launch the home screen Mouseover that row, and you should see values for the following act, which is the action - android.intent.action.main cat, which is the category - android.intent.category.home in this case, there is no data, but sometimes there is Note the action and category

Understanding Implicit Intents Can we create our own Home Screen app? Create a new project Open AndroidManifest.xml Add a new intent-filter to your Activity The action should match the one you found in LogCat So should the category In addition, add the DEFAULT category <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.home" /> <category android:name="android.intent.category.default" /> </intent-filter>

Understanding Implicit Intents Now press the Home key... For a nicer effect, make your Activity full-screen by adding this to the <activity> tag in the manifest file android:theme="@android:style/theme.notitlebar.fullscreen" JUST DO NOT TO MAKE YOUR NEW HOME SCREEN DEFAULT IF YOU ADD THE FULLSCREEN FEATURE

Understanding Implicit Intents See HomeScreen Example

Understanding Implicit Intents It's not too difficult to figure out the Java code for the same Intent: <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.home" /> <category android:name="android.intent.category.default" /> </intent-filter> or IntentFilter myfilter = new IntentFilter(Intent.ACTION_MAIN); myfilter.addcategory(intent.category_home);

Understanding Implicit Intents If you make your Intent Filters Too vague Too specific It won't match what you expect it to. Try to make your Intent Filters precise!

Understanding Implicit Intents Now that you know a little bit about Intents, try to figure this out. If you developed a Music Player, how would you go about allowing the user to choose your Music Player after clicking on a music file on his or her phone?

References The Busy Coder's Guide to Android Development - Mark Murphy Android Developers The Mobile Lab at Florida State University