SlideShare ist ein Scribd-Unternehmen logo
1 von 62
Downloaden Sie, um offline zu lesen
Slightly Advanced 
Android Wear ;-) 
+AlfredoMorresi 
@rainbowbreeze
UX basics
Design for Wear IS NOT 
design for a small phone
5 seconds or less per interaction
Design for big gestures
Think about stream cards first
Do one thing, really fast 
Design for the corner of the eye 
Don’t be a constant shoulder 
tapper
Activity Lifecycle
Voice Capabilities
AndroidManifest.xml 
<activity android:name="MyNoteActivity"> 
<intent-filter> 
<action android:name="android.intent.action.SEND" /> 
<category android:name="com.google.android.voicesearch.SELF_NOTE" /> 
</intent-filter> 
</activity>
AndroidManifest.xml 
<application> 
<activity 
android:name="StartRunActivity" 
android:label="MyRunningApp"> 
<intent-filter> 
<action android:name="android.intent.action.MAIN" /> 
<category android:name="android.intent.category.LAUNCHER" /> 
</intent-filter> 
</activity> 
</application>
MyActivity.java 
private static final int SPEECH_REQUEST_CODE = 0; 
// Create an intent that can start the Speech Recognizer activity 
private void displaySpeechRecognizer() { 
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); 
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, 
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); 
// Start the activity, the intent will be populated with the speech text 
startActivityForResult(intent, SPEECH_REQUEST_CODE); 
}
MyActivity.java 
// This callback is invoked when the Speech Recognizer returns. 
// This is where you process the intent and extract the speech text from 
the intent. 
@Override 
protected void onActivityResult(int requestCode, int resultCode, 
Intent data) { 
if (requestCode == SPEECH_REQUEST_CODE && resultCode == RESULT_OK) { 
List<String> results = data.getStringArrayListExtra( 
RecognizerIntent.EXTRA_RESULTS); 
String spokenText = results.get(0); 
// Do something with spokenText 
} 
super.onActivityResult(requestCode, resultCode, data); 
}
Notifications background
Background 
400x400 
640x400 (parallax scrolling)
res/drawable-nodpi 
(background) 
res/drawable-hdpi 
(all the other icons)
MyClass.java 
// Create a WearableExtender to add functionality 
// for wearables 
NotificationCompat.WearableExtender wearableExtender = 
new NotificationCompat.WearableExtender() 
.setHintHideIcon(true) 
.setBackground(mBitmap);
Data APIs
WearableListenerService 
(background) 
DataApi.DataListener 
(for Activity)
Avoid DataAPI caching 
PutDataMapRequest putDataMapRequest = 
PutDataMapRequest.create(Constant.LANDING_SITE_RESPONSE); 
DataMap dataMap = putDataMapRequest.getDataMap(); 
dataMap.putInt(Constant.KEY_MISSION_NUMBER, 123); 
dataMap.putString(Constant.KEY_LANDING_SITE_NAME, "..."); 
dataMap.putLong(Constant.KEY_TIMESTAMP, new Date().getTime()); 
PutDataRequest request = putDataMapRequest.asPutDataRequest(); 
PendingResult<DataApi.DataItemResult> pendingResult = 
Wearable.DataApi.putDataItem(mDataClient, request); 
DataApi.DataItemResult result = pendingResult.await();
Mariuxtheone / Teleport 
Data Sync & Messaging Library for Android Wear
Networking on Wear
HttpUrlConnect IS NOT 
available 
Doh!
Transferring bitmaps 
(handheld side)
String url = "..."; 
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
try { 
byte[] byteChunk = new byte[1024]; 
int n; 
InputStream in = new java.net.URL(url).openStream(); 
while ( (n = in.read(byteChunk)) > 0 ) { 
outputStream.write(byteChunk, 0, n); 
} 
// Check for bitmap correctness … 
Asset asset = Asset.createFromBytes(outputStream.toByteArray()); 
}
PutDataMapRequest dataMap = PutDataMapRequest.create("/image"); 
dataMap.getDataMap().putAsset("profileImage", asset) 
dataMap.getDataMap().putLong("timestamp", new Date().getTime()); 
PutDataRequest request = dataMap.asPutDataRequest(); 
PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi 
.putDataItem(mDataClient, request); 
DataApi.DataItemResult result = pendingResult.await(); 
// result.getDataItem().getUri());
private boolean isDataAValidBitmap(byte[] data) 
Bitmap checkBitmap = BitmapFactory.decodeByteArray( 
data, 0, data.length); 
// Checks bitmap for null or sizes with .getWidth() 
return null != checkBitmap; 
}
// From Bitmap to asset 
private static Asset createAssetFromBitmap(Bitmap bitmap) { 
final ByteArrayOutputStream bs = 
new ByteArrayOutputStream(); 
// Resize or apply other transformations... 
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bs); 
return Asset.createFromBytes(bs.toByteArray()); 
}
From resources 
Bitmap bitmap = BitmapFactory. 
decodeResource( 
getResources(), 
R.drawable.image);
Using Volley 
String url = "..."; 
ImageRequest request = new ImageRequest(url, 
new Response.Listener() { 
@Override 
public void onResponse(Bitmap bitmap) { 
// Your Android Wear code here 
} 
}, 0, 0, null, 
new Response.ErrorListener() { 
public void onErrorResponse(VolleyError error) { 
// Manages loading errors 
} 
}); 
// Access the RequestQueue through your singleton class. 
MySingleton.getInstance(this).addToRequestQueue(request);
Using Picasso 
Picasso.with(context) 
.load(url) 
.resize(50, 50) 
.transform(myTransformation) 
.into(myTarget) 
// Put transferring logic inside MyTarget class
Transferring bitmaps 
(Wear side)
@Override 
public void onDataChanged(DataEventBuffer dataEvents) { 
for (DataEvent event : dataEvents) { 
if (event.getType() == DataEvent.TYPE_CHANGED && 
event.getDataItem().getUri().getPath().equals("/image")) { 
DataMapItem dataMapItem = 
DataMapItem.fromDataItem(event.getDataItem()); 
Asset profileAsset = 
dataMapItem.getDataMap().getAsset("profileImage"); 
Bitmap bitmap = loadBitmapFromAsset(profileAsset); 
// Do something with the bitmap 
} 
} 
}
public Bitmap loadBitmapFromAsset(Asset asset) { 
if (asset == null) { 
throw new IllegalArgumentException("Asset must be non-null"); 
} 
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(context) 
.addApi(Wearable.API) 
.build(); 
ConnectionResult result = 
mGoogleApiClient.blockingConnect(TIMEOUT_MS, TimeUnit.MILLISECONDS); 
if (!result.isSuccess()) { 
return null; 
}
// convert asset into a file descriptor and block until it's ready 
InputStream assetInputStream = Wearable.DataApi.getFdForAsset( 
mGoogleApiClient, asset).await().getInputStream(); 
mGoogleApiClient.disconnect(); 
if (assetInputStream == null) { 
Log.w(TAG, "Requested an unknown Asset."); 
return null; 
} 
// decode the stream into a bitmap 
return BitmapFactory.decodeStream(assetInputStream); 
}
“ 
takahirom / WearHttp 
The mark of a great man is one who knows when to 
set aside the important things in order to accomplish 
the vital ones. Brandon Sanderson 
’’
Advanced UI
Custom Notifications
Create custom activity 
Display it as notification
AndroidManifest.xml 
<activity 
android:name="com.example.NotificationActivity" 
android:exported="true" 
android:allowEmbedded="true" 
android:taskAffinity="" 
android:theme="@android:style/Theme.DeviceDefault.Light" 
/>
NotificationActivity.java 
public class NotificationActivity extends Activity { 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_notification); 
mImageView = (ImageView) findViewById(R.id.image_view); 
mTextView = (TextView) findViewById(R.id.text_view); 
Intent intent = getIntent(); 
if (intent != null) { 
mTextView.setText(intent.getStringExtra(EXTRA_TITLE)); 
final Asset asset = intent.getParcelableExtra(EXTRA_IMAGE); 
loadBitmapFromAsset(this, asset, mImageView); // do async! 
} 
}
AndroidManifest.xml 
<service android:name=".OngoingNotificationListenerService"> 
<intent-filter> 
<action 
android:name="com.google.android.gms.wearable.BIND_LISTENER" 
/> 
</intent-filter> 
</service>
OngoingNotificationListenerService.java 
public class OngoingNotificationListenerService extends WearableListenerService { 
private GoogleApiClient mGoogleApiClient; 
@Override 
public void onCreate() { 
super.onCreate(); 
mGoogleApiClient = new GoogleApiClient.Builder(this) 
.addApi(Wearable.API) 
.build(); 
mGoogleApiClient.connect(); 
}
OngoingNotificationListenerService.java 
@Override 
public void onDataChanged(DataEventBuffer dataEvents) { 
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents); 
dataEvents.close(); 
if (!mGoogleApiClient.isConnected()) { 
ConnectionResult connectionResult = mGoogleApiClient 
.blockingConnect(30, TimeUnit.SECONDS); 
if (!connectionResult.isSuccess()) { 
Log.e(TAG, "Service failed to connect to GoogleApiClient."); 
return; 
} 
}
OngoingNotificationListenerService.java 
for (DataEvent event : events) { 
if (event.getType() == DataEvent.TYPE_CHANGED) { 
String path = event.getDataItem().getUri().getPath(); 
if (PATH.equals(path)) { 
// Get the data out of the event 
DataMapItem dataMapItem = 
DataMapItem.fromDataItem(event.getDataItem()); 
final String title = dataMapItem.getDataMap().getString(KEY_TITLE); 
Asset asset = dataMapItem.getDataMap().getAsset(KEY_IMAGE);
OngoingNotificationListenerService.java 
// Build the intent to display our custom notification 
Intent notificationIntent = 
new Intent(this, NotificationActivity.class); 
notificationIntent.putExtra( 
NotificationActivity.EXTRA_TITLE, title); 
notificationIntent.putExtra( 
NotificationActivity.EXTRA_IMAGE, asset); 
PendingIntent notificationPendingIntent = PendingIntent.getActivity( 
this, 
0, 
notificationIntent, 
PendingIntent.FLAG_UPDATE_CURRENT);
OngoingNotificationListenerService.java 
// Create the ongoing notification 
Notification.Builder notificationBuilder = 
new Notification.Builder(this) 
.setSmallIcon(R.drawable.ic_launcher) 
.setLargeIcon(BitmapFactory.decodeResource( 
getResources(), R.drawable.ic_launcher)) 
.setOngoing(true) 
.extend(new Notification.WearableExtender() 
.setDisplayIntent(notificationPendingIntent) 
.setBackground(myCustomBackground));
OngoingNotificationListenerService.java 
// Build the notification and show it 
NotificationManager notificationManager = 
(NotificationManager)getSystemService(NOTIFICATION_SERVICE); 
notificationManager.notify( 
NOTIFICATION_ID, notificationBuilder.build()); 
} else { 
Log.d(TAG, "Unrecognized path: " + path); 
} 
} 
} 
}
Disable swipe to dismiss
AndroidManifest.xml 
<application 
android:icon="@drawable/ic_launcher" 
android:label="@string/app_name" 
android:theme="@style/AppTheme" >
Styles.xml 
<resources> 
<style 
name="AppTheme" 
parent="@android:style/Theme.DeviceDefault.Light" 
> 
<item name="android:windowSwipeToDismiss">false</item> 
</style> 
</resources>
Long press to dismiss
public class ApolloDiceActivity extends Activity implements View. 
OnTouchListener, View.OnLongClickListener { 
private DismissOverlayView mDismissOverlayView; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
// ... 
RelativeLayout parentFrame = (RelativeLayout) 
findViewById(R.id.parent_frame); 
// Add DismissOverlayView to cover the whole screen 
mDismissOverlayView = new DismissOverlayView(this); 
parentFrame.addView(mDismissOverlayView,new RelativeLayout. 
LayoutParams( 
RelativeLayout.LayoutParams.MATCH_PARENT, 
RelativeLayout.LayoutParams.MATCH_PARENT)); 
parentFrame.setOnLongClickListener(this);
// Shows the default dismiss overlay 
public boolean onLongClick(View v) { 
mDismissOverlayView.show(); 
return true; 
} 
// Set onTouch to return false so it doesn’t 
// intercept the LongClick event: 
public boolean onTouch(View v, MotionEvent event) { 
//... 
return false; 
}
Round and Rect layout
res/layout/activity_match_timer.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_match_timer" 
app:roundLayout="@layout/round_activity_match_timer" 
tools:context=".MatchTimerNotificationActivity" 
tools:deviceIds="wear" />
res/layout/rect_activity_match_timer.xml 
<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/timer" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context=".MatchTimerNotificationActivity" 
tools:deviceIds="wear_square"> 
<TextView 
android:id="@+id/elapsed"
MatchTimerNotificationActivity.java 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_match_timer); 
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub); 
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() 
{ 
@Override 
public void onLayoutInflated(WatchViewStub stub) { 
elapsed = (TextView) stub.findViewById(R.id.elapsed); 
// ... 
} 
}); 
}
Complex examples
How We Customized Google Apps for Android Wear
What’s next? 
Getting Started with Android Wear 
developer.android.com/wear 
Developers Italia 
developersitalia.blogspot.com
Thank you! 
+AlfredoMorresi 
@rainbowbreeze 
Credits: 
Hoi Lam: http://viewbeyond.blogspot.co.uk 
Styling Android: http://blog.stylingandroid.com 
Images: all images are under CC licence

Weitere ähnliche Inhalte

Was ist angesagt?

Before there was Hoop Dreams, there was McDonald's: Strange and Beautiful
Before there was Hoop Dreams, there was McDonald's: Strange and BeautifulBefore there was Hoop Dreams, there was McDonald's: Strange and Beautiful
Before there was Hoop Dreams, there was McDonald's: Strange and Beautifulchicagonewsonlineradio
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android WearPeter Friese
 
Android App Development - 05 Action bar
Android App Development - 05 Action barAndroid App Development - 05 Action bar
Android App Development - 05 Action barDiego Grancini
 
What's New in Android
What's New in AndroidWhat's New in Android
What's New in AndroidRobert Cooper
 
Mad Max is back, plus the rest of our new reviews and notable screenings
Mad Max is back, plus the rest of our new reviews and notable screeningsMad Max is back, plus the rest of our new reviews and notable screenings
Mad Max is back, plus the rest of our new reviews and notable screeningschicagonewsonlineradio
 
Google Fit, Android Wear & Xamarin
Google Fit, Android Wear & XamarinGoogle Fit, Android Wear & Xamarin
Google Fit, Android Wear & XamarinPeter Friese
 
Adaptive UI - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ -
Adaptive UI  - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ - Adaptive UI  - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ -
Adaptive UI - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ - Yuji Hato
 
The rise and fall of a techno DJ, plus more new reviews and notable screenings
The rise and fall of a techno DJ, plus more new reviews and notable screeningsThe rise and fall of a techno DJ, plus more new reviews and notable screenings
The rise and fall of a techno DJ, plus more new reviews and notable screeningschicagonewsyesterday
 
Rushed to Victory Gardens' stage, An Issue of Blood is more effusion than play
Rushed to Victory Gardens' stage, An Issue of Blood is more effusion than playRushed to Victory Gardens' stage, An Issue of Blood is more effusion than play
Rushed to Victory Gardens' stage, An Issue of Blood is more effusion than playchicagonewsyesterday
 
Adopting 3D Touch in your apps
Adopting 3D Touch in your appsAdopting 3D Touch in your apps
Adopting 3D Touch in your appsJuan C Catalan
 
Google Play Services Rock
Google Play Services RockGoogle Play Services Rock
Google Play Services RockPeter Friese
 
Getting Ready For Android Wear
Getting Ready For Android WearGetting Ready For Android Wear
Getting Ready For Android WearRaveesh Bhalla
 
State management in android applications
State management in android applicationsState management in android applications
State management in android applicationsGabor Varadi
 
3D Touch: Preparando sua app para o futuro do iOS
3D Touch: Preparando sua app para o futuro do iOS3D Touch: Preparando sua app para o futuro do iOS
3D Touch: Preparando sua app para o futuro do iOSRodrigo Borges
 

Was ist angesagt? (20)

Before there was Hoop Dreams, there was McDonald's: Strange and Beautiful
Before there was Hoop Dreams, there was McDonald's: Strange and BeautifulBefore there was Hoop Dreams, there was McDonald's: Strange and Beautiful
Before there was Hoop Dreams, there was McDonald's: Strange and Beautiful
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android Wear
 
Android App Development - 05 Action bar
Android App Development - 05 Action barAndroid App Development - 05 Action bar
Android App Development - 05 Action bar
 
What's New in Android
What's New in AndroidWhat's New in Android
What's New in Android
 
Mad Max is back, plus the rest of our new reviews and notable screenings
Mad Max is back, plus the rest of our new reviews and notable screeningsMad Max is back, plus the rest of our new reviews and notable screenings
Mad Max is back, plus the rest of our new reviews and notable screenings
 
Action bar
Action barAction bar
Action bar
 
Google Fit, Android Wear & Xamarin
Google Fit, Android Wear & XamarinGoogle Fit, Android Wear & Xamarin
Google Fit, Android Wear & Xamarin
 
Android wearpp
Android wearppAndroid wearpp
Android wearpp
 
Adaptive UI - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ -
Adaptive UI  - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ - Adaptive UI  - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ -
Adaptive UI - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ -
 
The rise and fall of a techno DJ, plus more new reviews and notable screenings
The rise and fall of a techno DJ, plus more new reviews and notable screeningsThe rise and fall of a techno DJ, plus more new reviews and notable screenings
The rise and fall of a techno DJ, plus more new reviews and notable screenings
 
Rushed to Victory Gardens' stage, An Issue of Blood is more effusion than play
Rushed to Victory Gardens' stage, An Issue of Blood is more effusion than playRushed to Victory Gardens' stage, An Issue of Blood is more effusion than play
Rushed to Victory Gardens' stage, An Issue of Blood is more effusion than play
 
Introduction toandroid
Introduction toandroidIntroduction toandroid
Introduction toandroid
 
Adopting 3D Touch in your apps
Adopting 3D Touch in your appsAdopting 3D Touch in your apps
Adopting 3D Touch in your apps
 
Google Play Services Rock
Google Play Services RockGoogle Play Services Rock
Google Play Services Rock
 
Action Bar in Android
Action Bar in AndroidAction Bar in Android
Action Bar in Android
 
package org dev
package org devpackage org dev
package org dev
 
Getting Ready For Android Wear
Getting Ready For Android WearGetting Ready For Android Wear
Getting Ready For Android Wear
 
State management in android applications
State management in android applicationsState management in android applications
State management in android applications
 
3D Touch: Preparando sua app para o futuro do iOS
3D Touch: Preparando sua app para o futuro do iOS3D Touch: Preparando sua app para o futuro do iOS
3D Touch: Preparando sua app para o futuro do iOS
 
Android basic 2 UI Design
Android basic 2 UI DesignAndroid basic 2 UI Design
Android basic 2 UI Design
 

Ähnlich wie Slightly Advanced Android Wear ;)

GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...
GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...
GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...mharkus
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developersPavel Lahoda
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon Berlin
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basicsAnton Narusberg
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android WearPeter Friese
 
Capture image on eye blink
Capture image on eye blinkCapture image on eye blink
Capture image on eye blinkInnovationM
 
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...Bruno Salvatore Belluccia
 
android level 3
android level 3android level 3
android level 3DevMix
 
STYLISH FLOOR
STYLISH FLOORSTYLISH FLOOR
STYLISH FLOORABU HASAN
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Robert DeLuca
 
After max+phonegap
After max+phonegapAfter max+phonegap
After max+phonegapyangdj
 
混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaveryangdj
 
Mobile Software Engineering Crash Course - C04 Android Cont.
Mobile Software Engineering Crash Course - C04 Android Cont.Mobile Software Engineering Crash Course - C04 Android Cont.
Mobile Software Engineering Crash Course - C04 Android Cont.Mohammad Shaker
 
04 activities - Android
04   activities - Android04   activities - Android
04 activities - AndroidWingston
 

Ähnlich wie Slightly Advanced Android Wear ;) (20)

GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...
GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...
GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...
 
Android 3
Android 3Android 3
Android 3
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developers
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahoda
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
 
Android For All The Things
Android For All The ThingsAndroid For All The Things
Android For All The Things
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android Wear
 
Android Froyo
Android FroyoAndroid Froyo
Android Froyo
 
Capture image on eye blink
Capture image on eye blinkCapture image on eye blink
Capture image on eye blink
 
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
 
android level 3
android level 3android level 3
android level 3
 
STYLISH FLOOR
STYLISH FLOORSTYLISH FLOOR
STYLISH FLOOR
 
Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React Crossing platforms with JavaScript & React
Crossing platforms with JavaScript & React
 
After max+phonegap
After max+phonegapAfter max+phonegap
After max+phonegap
 
混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver混搭移动开发:PhoneGap+JQurey+Dreamweaver
混搭移动开发:PhoneGap+JQurey+Dreamweaver
 
Androidppt 1
Androidppt 1Androidppt 1
Androidppt 1
 
Mobile Software Engineering Crash Course - C04 Android Cont.
Mobile Software Engineering Crash Course - C04 Android Cont.Mobile Software Engineering Crash Course - C04 Android Cont.
Mobile Software Engineering Crash Course - C04 Android Cont.
 
04 activities - Android
04   activities - Android04   activities - Android
04 activities - Android
 

Mehr von Alfredo Morresi

Android Survival Guide - Two years of software development
Android Survival Guide - Two years of software developmentAndroid Survival Guide - Two years of software development
Android Survival Guide - Two years of software developmentAlfredo Morresi
 
Testing in Android: automatici, di integrazione, TDD e scenari avanzati
Testing in Android: automatici, di integrazione, TDD e scenari avanzatiTesting in Android: automatici, di integrazione, TDD e scenari avanzati
Testing in Android: automatici, di integrazione, TDD e scenari avanzatiAlfredo Morresi
 
Advanced Android Development
Advanced Android DevelopmentAdvanced Android Development
Advanced Android DevelopmentAlfredo Morresi
 
Mobile platforms development overview
Mobile platforms development overviewMobile platforms development overview
Mobile platforms development overviewAlfredo Morresi
 
Nativa Android Applications development
Nativa Android Applications developmentNativa Android Applications development
Nativa Android Applications developmentAlfredo Morresi
 
Funambol Code Sniper - Avatargrabber
Funambol Code Sniper - AvatargrabberFunambol Code Sniper - Avatargrabber
Funambol Code Sniper - AvatargrabberAlfredo Morresi
 
Mobile security & privacy - Paranoia in movimento
Mobile security & privacy - Paranoia in movimentoMobile security & privacy - Paranoia in movimento
Mobile security & privacy - Paranoia in movimentoAlfredo Morresi
 
Tesi cartoni animati e modelli culturali
Tesi cartoni animati e modelli culturaliTesi cartoni animati e modelli culturali
Tesi cartoni animati e modelli culturaliAlfredo Morresi
 
(in)Sicurezze delle reti wireless 802.11b
(in)Sicurezze delle reti wireless 802.11b(in)Sicurezze delle reti wireless 802.11b
(in)Sicurezze delle reti wireless 802.11bAlfredo Morresi
 
BlueSecurity: quando il dente fa male!
BlueSecurity: quando il dente fa male!BlueSecurity: quando il dente fa male!
BlueSecurity: quando il dente fa male!Alfredo Morresi
 
2(.0) passi nel mondo mobile - Alfredo Morresi
2(.0) passi nel mondo mobile - Alfredo Morresi2(.0) passi nel mondo mobile - Alfredo Morresi
2(.0) passi nel mondo mobile - Alfredo MorresiAlfredo Morresi
 
QR code - Alfredo Morresi
QR code - Alfredo MorresiQR code - Alfredo Morresi
QR code - Alfredo MorresiAlfredo Morresi
 

Mehr von Alfredo Morresi (13)

Android Survival Guide - Two years of software development
Android Survival Guide - Two years of software developmentAndroid Survival Guide - Two years of software development
Android Survival Guide - Two years of software development
 
Testing in Android: automatici, di integrazione, TDD e scenari avanzati
Testing in Android: automatici, di integrazione, TDD e scenari avanzatiTesting in Android: automatici, di integrazione, TDD e scenari avanzati
Testing in Android: automatici, di integrazione, TDD e scenari avanzati
 
Advanced Android Development
Advanced Android DevelopmentAdvanced Android Development
Advanced Android Development
 
Mobile platforms development overview
Mobile platforms development overviewMobile platforms development overview
Mobile platforms development overview
 
Nativa Android Applications development
Nativa Android Applications developmentNativa Android Applications development
Nativa Android Applications development
 
Refactoring 2 The Max
Refactoring 2 The MaxRefactoring 2 The Max
Refactoring 2 The Max
 
Funambol Code Sniper - Avatargrabber
Funambol Code Sniper - AvatargrabberFunambol Code Sniper - Avatargrabber
Funambol Code Sniper - Avatargrabber
 
Mobile security & privacy - Paranoia in movimento
Mobile security & privacy - Paranoia in movimentoMobile security & privacy - Paranoia in movimento
Mobile security & privacy - Paranoia in movimento
 
Tesi cartoni animati e modelli culturali
Tesi cartoni animati e modelli culturaliTesi cartoni animati e modelli culturali
Tesi cartoni animati e modelli culturali
 
(in)Sicurezze delle reti wireless 802.11b
(in)Sicurezze delle reti wireless 802.11b(in)Sicurezze delle reti wireless 802.11b
(in)Sicurezze delle reti wireless 802.11b
 
BlueSecurity: quando il dente fa male!
BlueSecurity: quando il dente fa male!BlueSecurity: quando il dente fa male!
BlueSecurity: quando il dente fa male!
 
2(.0) passi nel mondo mobile - Alfredo Morresi
2(.0) passi nel mondo mobile - Alfredo Morresi2(.0) passi nel mondo mobile - Alfredo Morresi
2(.0) passi nel mondo mobile - Alfredo Morresi
 
QR code - Alfredo Morresi
QR code - Alfredo MorresiQR code - Alfredo Morresi
QR code - Alfredo Morresi
 

Kürzlich hochgeladen

Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 

Kürzlich hochgeladen (20)

Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 

Slightly Advanced Android Wear ;)

  • 1. Slightly Advanced Android Wear ;-) +AlfredoMorresi @rainbowbreeze
  • 3. Design for Wear IS NOT design for a small phone
  • 4. 5 seconds or less per interaction
  • 5. Design for big gestures
  • 6. Think about stream cards first
  • 7. Do one thing, really fast Design for the corner of the eye Don’t be a constant shoulder tapper
  • 10. AndroidManifest.xml <activity android:name="MyNoteActivity"> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="com.google.android.voicesearch.SELF_NOTE" /> </intent-filter> </activity>
  • 11. AndroidManifest.xml <application> <activity android:name="StartRunActivity" android:label="MyRunningApp"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
  • 12. MyActivity.java private static final int SPEECH_REQUEST_CODE = 0; // Create an intent that can start the Speech Recognizer activity private void displaySpeechRecognizer() { Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); // Start the activity, the intent will be populated with the speech text startActivityForResult(intent, SPEECH_REQUEST_CODE); }
  • 13. MyActivity.java // This callback is invoked when the Speech Recognizer returns. // This is where you process the intent and extract the speech text from the intent. @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == SPEECH_REQUEST_CODE && resultCode == RESULT_OK) { List<String> results = data.getStringArrayListExtra( RecognizerIntent.EXTRA_RESULTS); String spokenText = results.get(0); // Do something with spokenText } super.onActivityResult(requestCode, resultCode, data); }
  • 15. Background 400x400 640x400 (parallax scrolling)
  • 17. MyClass.java // Create a WearableExtender to add functionality // for wearables NotificationCompat.WearableExtender wearableExtender = new NotificationCompat.WearableExtender() .setHintHideIcon(true) .setBackground(mBitmap);
  • 20. Avoid DataAPI caching PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(Constant.LANDING_SITE_RESPONSE); DataMap dataMap = putDataMapRequest.getDataMap(); dataMap.putInt(Constant.KEY_MISSION_NUMBER, 123); dataMap.putString(Constant.KEY_LANDING_SITE_NAME, "..."); dataMap.putLong(Constant.KEY_TIMESTAMP, new Date().getTime()); PutDataRequest request = putDataMapRequest.asPutDataRequest(); PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi.putDataItem(mDataClient, request); DataApi.DataItemResult result = pendingResult.await();
  • 21. Mariuxtheone / Teleport Data Sync & Messaging Library for Android Wear
  • 23. HttpUrlConnect IS NOT available Doh!
  • 25. String url = "..."; ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { byte[] byteChunk = new byte[1024]; int n; InputStream in = new java.net.URL(url).openStream(); while ( (n = in.read(byteChunk)) > 0 ) { outputStream.write(byteChunk, 0, n); } // Check for bitmap correctness … Asset asset = Asset.createFromBytes(outputStream.toByteArray()); }
  • 26. PutDataMapRequest dataMap = PutDataMapRequest.create("/image"); dataMap.getDataMap().putAsset("profileImage", asset) dataMap.getDataMap().putLong("timestamp", new Date().getTime()); PutDataRequest request = dataMap.asPutDataRequest(); PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi .putDataItem(mDataClient, request); DataApi.DataItemResult result = pendingResult.await(); // result.getDataItem().getUri());
  • 27. private boolean isDataAValidBitmap(byte[] data) Bitmap checkBitmap = BitmapFactory.decodeByteArray( data, 0, data.length); // Checks bitmap for null or sizes with .getWidth() return null != checkBitmap; }
  • 28. // From Bitmap to asset private static Asset createAssetFromBitmap(Bitmap bitmap) { final ByteArrayOutputStream bs = new ByteArrayOutputStream(); // Resize or apply other transformations... bitmap.compress(Bitmap.CompressFormat.PNG, 100, bs); return Asset.createFromBytes(bs.toByteArray()); }
  • 29. From resources Bitmap bitmap = BitmapFactory. decodeResource( getResources(), R.drawable.image);
  • 30. Using Volley String url = "..."; ImageRequest request = new ImageRequest(url, new Response.Listener() { @Override public void onResponse(Bitmap bitmap) { // Your Android Wear code here } }, 0, 0, null, new Response.ErrorListener() { public void onErrorResponse(VolleyError error) { // Manages loading errors } }); // Access the RequestQueue through your singleton class. MySingleton.getInstance(this).addToRequestQueue(request);
  • 31. Using Picasso Picasso.with(context) .load(url) .resize(50, 50) .transform(myTransformation) .into(myTarget) // Put transferring logic inside MyTarget class
  • 33. @Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent event : dataEvents) { if (event.getType() == DataEvent.TYPE_CHANGED && event.getDataItem().getUri().getPath().equals("/image")) { DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem()); Asset profileAsset = dataMapItem.getDataMap().getAsset("profileImage"); Bitmap bitmap = loadBitmapFromAsset(profileAsset); // Do something with the bitmap } } }
  • 34. public Bitmap loadBitmapFromAsset(Asset asset) { if (asset == null) { throw new IllegalArgumentException("Asset must be non-null"); } GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(context) .addApi(Wearable.API) .build(); ConnectionResult result = mGoogleApiClient.blockingConnect(TIMEOUT_MS, TimeUnit.MILLISECONDS); if (!result.isSuccess()) { return null; }
  • 35. // convert asset into a file descriptor and block until it's ready InputStream assetInputStream = Wearable.DataApi.getFdForAsset( mGoogleApiClient, asset).await().getInputStream(); mGoogleApiClient.disconnect(); if (assetInputStream == null) { Log.w(TAG, "Requested an unknown Asset."); return null; } // decode the stream into a bitmap return BitmapFactory.decodeStream(assetInputStream); }
  • 36. “ takahirom / WearHttp The mark of a great man is one who knows when to set aside the important things in order to accomplish the vital ones. Brandon Sanderson ’’
  • 39. Create custom activity Display it as notification
  • 40. AndroidManifest.xml <activity android:name="com.example.NotificationActivity" android:exported="true" android:allowEmbedded="true" android:taskAffinity="" android:theme="@android:style/Theme.DeviceDefault.Light" />
  • 41. NotificationActivity.java public class NotificationActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_notification); mImageView = (ImageView) findViewById(R.id.image_view); mTextView = (TextView) findViewById(R.id.text_view); Intent intent = getIntent(); if (intent != null) { mTextView.setText(intent.getStringExtra(EXTRA_TITLE)); final Asset asset = intent.getParcelableExtra(EXTRA_IMAGE); loadBitmapFromAsset(this, asset, mImageView); // do async! } }
  • 42. AndroidManifest.xml <service android:name=".OngoingNotificationListenerService"> <intent-filter> <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> </intent-filter> </service>
  • 43. OngoingNotificationListenerService.java public class OngoingNotificationListenerService extends WearableListenerService { private GoogleApiClient mGoogleApiClient; @Override public void onCreate() { super.onCreate(); mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Wearable.API) .build(); mGoogleApiClient.connect(); }
  • 44. OngoingNotificationListenerService.java @Override public void onDataChanged(DataEventBuffer dataEvents) { final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents); dataEvents.close(); if (!mGoogleApiClient.isConnected()) { ConnectionResult connectionResult = mGoogleApiClient .blockingConnect(30, TimeUnit.SECONDS); if (!connectionResult.isSuccess()) { Log.e(TAG, "Service failed to connect to GoogleApiClient."); return; } }
  • 45. OngoingNotificationListenerService.java for (DataEvent event : events) { if (event.getType() == DataEvent.TYPE_CHANGED) { String path = event.getDataItem().getUri().getPath(); if (PATH.equals(path)) { // Get the data out of the event DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem()); final String title = dataMapItem.getDataMap().getString(KEY_TITLE); Asset asset = dataMapItem.getDataMap().getAsset(KEY_IMAGE);
  • 46. OngoingNotificationListenerService.java // Build the intent to display our custom notification Intent notificationIntent = new Intent(this, NotificationActivity.class); notificationIntent.putExtra( NotificationActivity.EXTRA_TITLE, title); notificationIntent.putExtra( NotificationActivity.EXTRA_IMAGE, asset); PendingIntent notificationPendingIntent = PendingIntent.getActivity( this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
  • 47. OngoingNotificationListenerService.java // Create the ongoing notification Notification.Builder notificationBuilder = new Notification.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setLargeIcon(BitmapFactory.decodeResource( getResources(), R.drawable.ic_launcher)) .setOngoing(true) .extend(new Notification.WearableExtender() .setDisplayIntent(notificationPendingIntent) .setBackground(myCustomBackground));
  • 48. OngoingNotificationListenerService.java // Build the notification and show it NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); notificationManager.notify( NOTIFICATION_ID, notificationBuilder.build()); } else { Log.d(TAG, "Unrecognized path: " + path); } } } }
  • 49. Disable swipe to dismiss
  • 50. AndroidManifest.xml <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" >
  • 51. Styles.xml <resources> <style name="AppTheme" parent="@android:style/Theme.DeviceDefault.Light" > <item name="android:windowSwipeToDismiss">false</item> </style> </resources>
  • 52. Long press to dismiss
  • 53. public class ApolloDiceActivity extends Activity implements View. OnTouchListener, View.OnLongClickListener { private DismissOverlayView mDismissOverlayView; @Override protected void onCreate(Bundle savedInstanceState) { // ... RelativeLayout parentFrame = (RelativeLayout) findViewById(R.id.parent_frame); // Add DismissOverlayView to cover the whole screen mDismissOverlayView = new DismissOverlayView(this); parentFrame.addView(mDismissOverlayView,new RelativeLayout. LayoutParams( RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT)); parentFrame.setOnLongClickListener(this);
  • 54. // Shows the default dismiss overlay public boolean onLongClick(View v) { mDismissOverlayView.show(); return true; } // Set onTouch to return false so it doesn’t // intercept the LongClick event: public boolean onTouch(View v, MotionEvent event) { //... return false; }
  • 55. Round and Rect layout
  • 56. res/layout/activity_match_timer.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_match_timer" app:roundLayout="@layout/round_activity_match_timer" tools:context=".MatchTimerNotificationActivity" tools:deviceIds="wear" />
  • 57. res/layout/rect_activity_match_timer.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/timer" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MatchTimerNotificationActivity" tools:deviceIds="wear_square"> <TextView android:id="@+id/elapsed"
  • 58. MatchTimerNotificationActivity.java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_match_timer); final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub); stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() { @Override public void onLayoutInflated(WatchViewStub stub) { elapsed = (TextView) stub.findViewById(R.id.elapsed); // ... } }); }
  • 60. How We Customized Google Apps for Android Wear
  • 61. What’s next? Getting Started with Android Wear developer.android.com/wear Developers Italia developersitalia.blogspot.com
  • 62. Thank you! +AlfredoMorresi @rainbowbreeze Credits: Hoi Lam: http://viewbeyond.blogspot.co.uk Styling Android: http://blog.stylingandroid.com Images: all images are under CC licence