The document provides an overview of advanced Android Wear development techniques including:
1) Customizing notifications by creating a custom activity displayed as a notification, handling notification data changes, and building notifications with custom backgrounds.
2) Advanced UI techniques such as disabling swipe to dismiss, adding long press to dismiss interactions, and using round and rectangular layouts.
3) Transferring bitmap images between handheld and wearable devices using assets, Volley, Picasso, and data syncing APIs.
4) Techniques for voice input using the speech recognizer, networking on Wear using libraries, and avoiding data caching issues.
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);
}
17. MyClass.java
// Create a WearableExtender to add functionality
// for wearables
NotificationCompat.WearableExtender wearableExtender =
new NotificationCompat.WearableExtender()
.setHintHideIcon(true)
.setBackground(mBitmap);
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
’’
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);
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