SlideShare a Scribd company logo
Build your own remote
control
Who am I?
● Jesus Gumiel
○ @jegumi
● Android developer
○ Telefonica R +D (TU Me, TU Go)
○ The Guardian
○ Sky (Now TV, Sky Store)
● Entrepreneur
○ Footballtracker → http://www.football-tracker.com
Some context
● Hackday at Now TV
○ Develop something for Now TV
● What can I do?
○ Only 4 hours of development
○ Android of course
○ It must be cool to show and easy to understand
○ It must be something interesting to develop
○ It must be useful
The target
Control Now Tv box with a Moto 360
Build your own remote control. Droidcon greece 2016
Types of wearables app
Synced Notifications
Notifications on handhelds
can automatically sync to
wearables, so design them
with both devices in mind.
Voice Actions
Register your app to
handle voice actions, like
"Ok Google, take a note,"
for a hands-free
experience.
Build Wearable Apps
Create custom
experiences with
activities, services,
sensors, and much more
with the Android SDK.
Send Data
Send data and actions
between handhelds and
wearables with data
replication APIs and
RPCs
Common mistake
Try to replicate the functionality of your handset on a wearable
The future – Android Wear 2.0
 Standalone apps are the biggest change for the Wear ecosystem to date. Starting
this autumn, you won't need your phone nearby to use apps on your Android Wear
device. Rather, it will be able to communicate through Bluetooth, Wi-Fi or cellular
instead of depending on a tethered phone or cloud syncing, using a Multi-APK
delivery method.
 2.0 won't be available for every Wear smartwatch. Older devices such as the original
Moto 360 and the LG G Watch will miss out.
Debugging Bluetooth
1. Enable Debugging over Bluetooth on the Android Wear companion app. You
should see a tiny status summary appear under the option:
Host: disconnected
Target: connected
2. Connect the handheld to your machine over USB and run:
adb forward tcp:4444 localabstract:/adb-hub
adb connect localhost:4444
3. In the Android Wear companion app, you should see the status change to:
Host: connected
Target: connected
Wearable app architecture
Create a wearable project
WEARABLE
Wearable layout (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent”>
Wearable layout (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WatchViewStub
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/watch_view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:rectLayout="@layout/rect_activity_main"
app:roundLayout="@layout/round_activity_main"
tools:context=".MainActivity"
tools:deviceIds="wear"/>
Wearable layout (round_activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<GridLayout 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:background="@color/round_bg"
android:columnCount="3”
tools:context=".MainActivity"
tools:deviceIds="wear_round">
Wearable layout (activity_main.xml) – Post API 23
1. layout-notround/activity_main.xml - layout for square watches
- values-round/dimens.xml
2. layout-round/activity_main.xml - layout for round watches
- values/dimens.xml
Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFields();
setUpCommunication();
}
Init fields
private void initFields() {
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
……..
}
}
}
Connect with the device
private void setUpCommunication() {
mClient = new GoogleApiClient.Builder(this).addApi(Wearable.API).build();
new Thread(new Runnable() {
@Override
public void run() {
mClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
NodeApi.GetConnectedNodesResult result =
Wearable.NodeApi.getConnectedNodes(mClient).await();
List<Node> nodes = result.getNodes();
if (!nodes.isEmpty()) {
mNodeId = nodes.get(0).getId();
}
mClient.disconnect();
}
}).start();
}
Communicate with the device
private void sendMessageToDevice(final int message) {
if (mNodeId != null) {
new Thread(new Runnable() {
@Override
public void run() {
mClient.blockingConnect(CONNECTION_TIME_OUT_MS,
TimeUnit.MILLISECONDS);
Wearable.MessageApi.sendMessage(mClient, mNodeId, String.valueOf(message),
null);
mClient.disconnect();
}
}).start();
}
}
MOBILE
Declare the listener in the Manifest
<service
android:name="com.bskyb.nowtv.ui.ListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
</service>
Declare the listener in the Manifest
<service
android:name="com.bskyb.nowtv.ui.ListenerService" >
<intent-filter>
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED"
/>
<data android:scheme="wear" android:host="*" android:pathPrefix="/prefix" />
</intent-filter>
</service>
Listener to receive messages
public class ListenerService extends WearableListenerService {
@Override
public void onMessageReceived(MessageEvent messageEvent) {
String command = messageEvent.getPath();
RemoteHelper.sendMessageToBox(this, command );
}
Sending command to Box
public static void sendMessageToBox(Context context, String command) {
RequestQueue queue = Volley.newRequestQueue(context);
StringRequest stringRequest = new StringRequest(Request.Method.POST, getRemoteUrl(context, command),
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.i(TAG, "onResponse: " + response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "onErrorResponse: ", error);
}
});
queue.add(stringRequest);
}
Packaging your app
- Permissions on the handheld manifest
- Handled and wearable app with same package and version name
- Add gradle dependency
dependencies {
wearApp project(':wear’)
}
- Click Build > Generate Signed APK
- Android Studio exports the signed handheld app with the wearable app embedded in
it automatically into your project's root folder.
https://github.com/jegumi/londroid2016
Show me the code

More Related Content

PPTX
Londroid meetup
PDF
UVic Startup Slam September 2014 (Kano Apps)
PDF
WTF is 360 Video?, Digiday WTF VR, May 11th, 2016
PPTX
Mobile Enablement And Intelligence
PDF
Novidades do Google IO 2015
PDF
Designing Mobile Apps with HTML5 & CSS3
PPTX
The new new mobile web
PDF
Desarrollo de app móviles con tecnlogías web
Londroid meetup
UVic Startup Slam September 2014 (Kano Apps)
WTF is 360 Video?, Digiday WTF VR, May 11th, 2016
Mobile Enablement And Intelligence
Novidades do Google IO 2015
Designing Mobile Apps with HTML5 & CSS3
The new new mobile web
Desarrollo de app móviles con tecnlogías web

What's hot (20)

PPT
android marshmallow
PPTX
Apprupt Overview
PDF
"Mobile Apps, beyond downloads, what’s next?" by Philippe Dumont
PDF
"Native App & Hybrid App, what is at stake?" by Olivier Berni
PDF
Benefits of Enplug for Customers
PPT
EventPilot Conference Apps - Getting Started: Mobile App Graphics
PDF
Complete iOS Toolkit
PDF
The Publisher's Response, Digiday WTF VR, May 11th, 2016
PPTX
Android marshmallow 6.0
PPTX
Cen Pho Camp Mobile App Preso
PDF
Start Building App Without Code
PPTX
Free Apps VS Paid Apps - Houssem Eddine Lassoued
PDF
Ionic, ce n'est pas que de l'UI, meetup PhoneGap le 25-05-2015
PDF
API Design and Enterprise Mobile Apps
PPTX
Trends in mobile technology for the event market FEO 2015
PDF
Developing for Windows Phone: A Guide for iOS Developers
PPT
The Fine Print of iOS Development
PDF
How an mHealth App Gets Made
PDF
Do relogio ao carro
PPTX
React native automation testing
android marshmallow
Apprupt Overview
"Mobile Apps, beyond downloads, what’s next?" by Philippe Dumont
"Native App & Hybrid App, what is at stake?" by Olivier Berni
Benefits of Enplug for Customers
EventPilot Conference Apps - Getting Started: Mobile App Graphics
Complete iOS Toolkit
The Publisher's Response, Digiday WTF VR, May 11th, 2016
Android marshmallow 6.0
Cen Pho Camp Mobile App Preso
Start Building App Without Code
Free Apps VS Paid Apps - Houssem Eddine Lassoued
Ionic, ce n'est pas que de l'UI, meetup PhoneGap le 25-05-2015
API Design and Enterprise Mobile Apps
Trends in mobile technology for the event market FEO 2015
Developing for Windows Phone: A Guide for iOS Developers
The Fine Print of iOS Development
How an mHealth App Gets Made
Do relogio ao carro
React native automation testing
Ad

Similar to Build your own remote control. Droidcon greece 2016 (20)

PPTX
Android Wearable App Development - 1
PDF
Android interview questions
PDF
Android Interview Questions
PDF
Getting Started with Android - OSSPAC 2009
PDF
Android studio
PPTX
Lecture 12 - Maps, AR_VR_aaaaHardware.pptx
PPTX
Chapter 1- Mobile Application Development Introduction-java.pptx
PDF
Android Minnebar
ODP
Java Meetup - 12-03-15 - Android Development Workshop
PDF
HTML5 App Skills for Android Developers
DOCX
Android Lab Mannual 18SUITSP5.docx
PDF
Dreamweaver CS6, jQuery, PhoneGap, mobile design
PDF
Android Intro
PDF
March 2014 Meetup - Nokia X Tech Session
PDF
H2O Wave Course Starter - Presentation Slides
PPT
Android Wearable App
PPTX
Lecture 01: Introduction into Android.pptx
KEY
Intro to PhoneGap
PDF
Trilha Android - Android Evolved
PDF
Mobile application and Game development
Android Wearable App Development - 1
Android interview questions
Android Interview Questions
Getting Started with Android - OSSPAC 2009
Android studio
Lecture 12 - Maps, AR_VR_aaaaHardware.pptx
Chapter 1- Mobile Application Development Introduction-java.pptx
Android Minnebar
Java Meetup - 12-03-15 - Android Development Workshop
HTML5 App Skills for Android Developers
Android Lab Mannual 18SUITSP5.docx
Dreamweaver CS6, jQuery, PhoneGap, mobile design
Android Intro
March 2014 Meetup - Nokia X Tech Session
H2O Wave Course Starter - Presentation Slides
Android Wearable App
Lecture 01: Introduction into Android.pptx
Intro to PhoneGap
Trilha Android - Android Evolved
Mobile application and Game development
Ad

Recently uploaded (20)

PPTX
Benefits of Physical activity for teenagers.pptx
PDF
A Late Bloomer's Guide to GenAI: Ethics, Bias, and Effective Prompting - Boha...
PDF
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
PDF
Hindi spoken digit analysis for native and non-native speakers
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PDF
A novel scalable deep ensemble learning framework for big data classification...
DOCX
search engine optimization ppt fir known well about this
PPT
Geologic Time for studying geology for geologist
PDF
Taming the Chaos: How to Turn Unstructured Data into Decisions
PPT
What is a Computer? Input Devices /output devices
PDF
How ambidextrous entrepreneurial leaders react to the artificial intelligence...
PPTX
observCloud-Native Containerability and monitoring.pptx
PDF
STKI Israel Market Study 2025 version august
PDF
Enhancing emotion recognition model for a student engagement use case through...
PDF
Developing a website for English-speaking practice to English as a foreign la...
PDF
CloudStack 4.21: First Look Webinar slides
PDF
A comparative study of natural language inference in Swahili using monolingua...
PDF
Five Habits of High-Impact Board Members
PDF
Architecture types and enterprise applications.pdf
PDF
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
Benefits of Physical activity for teenagers.pptx
A Late Bloomer's Guide to GenAI: Ethics, Bias, and Effective Prompting - Boha...
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
Hindi spoken digit analysis for native and non-native speakers
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
A novel scalable deep ensemble learning framework for big data classification...
search engine optimization ppt fir known well about this
Geologic Time for studying geology for geologist
Taming the Chaos: How to Turn Unstructured Data into Decisions
What is a Computer? Input Devices /output devices
How ambidextrous entrepreneurial leaders react to the artificial intelligence...
observCloud-Native Containerability and monitoring.pptx
STKI Israel Market Study 2025 version august
Enhancing emotion recognition model for a student engagement use case through...
Developing a website for English-speaking practice to English as a foreign la...
CloudStack 4.21: First Look Webinar slides
A comparative study of natural language inference in Swahili using monolingua...
Five Habits of High-Impact Board Members
Architecture types and enterprise applications.pdf
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game

Build your own remote control. Droidcon greece 2016

  • 1. Build your own remote control
  • 2. Who am I? ● Jesus Gumiel ○ @jegumi ● Android developer ○ Telefonica R +D (TU Me, TU Go) ○ The Guardian ○ Sky (Now TV, Sky Store) ● Entrepreneur ○ Footballtracker → http://www.football-tracker.com
  • 3. Some context ● Hackday at Now TV ○ Develop something for Now TV ● What can I do? ○ Only 4 hours of development ○ Android of course ○ It must be cool to show and easy to understand ○ It must be something interesting to develop ○ It must be useful
  • 4. The target Control Now Tv box with a Moto 360
  • 6. Types of wearables app Synced Notifications Notifications on handhelds can automatically sync to wearables, so design them with both devices in mind. Voice Actions Register your app to handle voice actions, like "Ok Google, take a note," for a hands-free experience. Build Wearable Apps Create custom experiences with activities, services, sensors, and much more with the Android SDK. Send Data Send data and actions between handhelds and wearables with data replication APIs and RPCs
  • 7. Common mistake Try to replicate the functionality of your handset on a wearable
  • 8. The future – Android Wear 2.0  Standalone apps are the biggest change for the Wear ecosystem to date. Starting this autumn, you won't need your phone nearby to use apps on your Android Wear device. Rather, it will be able to communicate through Bluetooth, Wi-Fi or cellular instead of depending on a tethered phone or cloud syncing, using a Multi-APK delivery method.  2.0 won't be available for every Wear smartwatch. Older devices such as the original Moto 360 and the LG G Watch will miss out.
  • 9. Debugging Bluetooth 1. Enable Debugging over Bluetooth on the Android Wear companion app. You should see a tiny status summary appear under the option: Host: disconnected Target: connected 2. Connect the handheld to your machine over USB and run: adb forward tcp:4444 localabstract:/adb-hub adb connect localhost:4444 3. In the Android Wear companion app, you should see the status change to: Host: connected Target: connected
  • 11. Create a wearable project
  • 13. Wearable layout (activity_main.xml) <?xml version="1.0" encoding="utf-8"?> <android.support.wearable.view.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent”>
  • 14. Wearable layout (activity_main.xml) <?xml version="1.0" encoding="utf-8"?> <android.support.wearable.view.WatchViewStub xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/watch_view_stub" android:layout_width="match_parent" android:layout_height="match_parent" app:rectLayout="@layout/rect_activity_main" app:roundLayout="@layout/round_activity_main" tools:context=".MainActivity" tools:deviceIds="wear"/>
  • 15. Wearable layout (round_activity_main.xml) <?xml version="1.0" encoding="utf-8"?> <GridLayout 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:background="@color/round_bg" android:columnCount="3” tools:context=".MainActivity" tools:deviceIds="wear_round">
  • 16. Wearable layout (activity_main.xml) – Post API 23 1. layout-notround/activity_main.xml - layout for square watches - values-round/dimens.xml 2. layout-round/activity_main.xml - layout for round watches - values/dimens.xml
  • 17. Activity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initFields(); setUpCommunication(); }
  • 18. Init fields private void initFields() { final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub); stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() { @Override public void onLayoutInflated(WatchViewStub stub) { …….. } } }
  • 19. Connect with the device private void setUpCommunication() { mClient = new GoogleApiClient.Builder(this).addApi(Wearable.API).build(); new Thread(new Runnable() { @Override public void run() { mClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS); NodeApi.GetConnectedNodesResult result = Wearable.NodeApi.getConnectedNodes(mClient).await(); List<Node> nodes = result.getNodes(); if (!nodes.isEmpty()) { mNodeId = nodes.get(0).getId(); } mClient.disconnect(); } }).start(); }
  • 20. Communicate with the device private void sendMessageToDevice(final int message) { if (mNodeId != null) { new Thread(new Runnable() { @Override public void run() { mClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS); Wearable.MessageApi.sendMessage(mClient, mNodeId, String.valueOf(message), null); mClient.disconnect(); } }).start(); } }
  • 22. Declare the listener in the Manifest <service android:name="com.bskyb.nowtv.ui.ListenerService" > <intent-filter> <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> </intent-filter> </service>
  • 23. Declare the listener in the Manifest <service android:name="com.bskyb.nowtv.ui.ListenerService" > <intent-filter> <action android:name="com.google.android.gms.wearable.DATA_CHANGED" /> <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" /> <data android:scheme="wear" android:host="*" android:pathPrefix="/prefix" /> </intent-filter> </service>
  • 24. Listener to receive messages public class ListenerService extends WearableListenerService { @Override public void onMessageReceived(MessageEvent messageEvent) { String command = messageEvent.getPath(); RemoteHelper.sendMessageToBox(this, command ); }
  • 25. Sending command to Box public static void sendMessageToBox(Context context, String command) { RequestQueue queue = Volley.newRequestQueue(context); StringRequest stringRequest = new StringRequest(Request.Method.POST, getRemoteUrl(context, command), new Response.Listener<String>() { @Override public void onResponse(String response) { Log.i(TAG, "onResponse: " + response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e(TAG, "onErrorResponse: ", error); } }); queue.add(stringRequest); }
  • 26. Packaging your app - Permissions on the handheld manifest - Handled and wearable app with same package and version name - Add gradle dependency dependencies { wearApp project(':wear’) } - Click Build > Generate Signed APK - Android Studio exports the signed handheld app with the wearable app embedded in it automatically into your project's root folder.

Editor's Notes

  • #7: Remote procedure calls
  • #14: You could use a box inset layout that create a square on the center of the screen and avoid issues with edges
  • #15: A WatchViewStub allows for the use of different sub-layouts depending on the shape of the device screen as reported by onApplyWindowInsets. If the call is not delivered by initial measurement the container will be assumed rectangular.
  • #17: A WatchViewStub allows for the use of different sub-layouts depending on the shape of the device screen as reported by onApplyWindowInsets. If the call is not delivered by initial measurement the container will be assumed rectangular.
  • #19: If you need to know in code what’s the shape of the device mainView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() @Override public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) { if (insets.isRound()) { Log.d("ViewService", "Round"); } else { Log.d("ViewService", "Square"); } return insets; } });
  • #26: https://developer.android.com/training/wearables/apps/packaging.html Click Build > Generate Signed APK... and follow the on-screen instructions to specify your release keystore and sign your app. Android Studio exports the signed handheld app with the wearable app embedded in it automatically into your project's root folder. Alternatively, you can sign both apps from the command line using the Gradle wrapper. Both apps must be signed to have the automatic pushing of the wearable app work.