Move part of Wear project
Adds missing Copyright header to Shared/src/main/res/values/strings.xml files.
Change-Id: Ic6c2590a8d064b6690f8590eb73039faeb8f0cbb
diff --git a/wearable/wear/AgendaData/Application/.gitignore b/wearable/wear/AgendaData/Application/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/AgendaData/Application/proguard-project.txt b/wearable/wear/AgendaData/Application/proguard-project.txt
new file mode 100644
index 0000000..0d8f171
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/proguard-project.txt
@@ -0,0 +1,20 @@
+ To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/wearable/wear/AgendaData/Application/src/main/AndroidManifest.xml b/wearable/wear/AgendaData/Application/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..b5bebc3
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/src/main/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.agendadata">
+
+ <uses-sdk android:minSdkVersion="19"
+ android:targetSdkVersion="19" />
+
+ <uses-permission android:name="android.permission.READ_CALENDAR" />
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@android:style/Theme.Holo.Light"
+ >
+
+ <meta-data
+ android:name="com.google.android.gms.version"
+ android:value="@integer/google_play_services_version" />
+
+ <activity
+ android:name="com.example.android.agendadata.MainActivity"
+ android:label="@string/app_name"
+ android:configChanges="keyboardHidden|orientation|screenSize">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+
+ <service android:name="com.example.android.agendadata.CalendarQueryService"/>
+ </application>
+</manifest>
diff --git a/wearable/wear/AgendaData/Application/src/main/java/com/example/android/agendadata/CalendarQueryService.java b/wearable/wear/AgendaData/Application/src/main/java/com/example/android/agendadata/CalendarQueryService.java
new file mode 100644
index 0000000..fe7fa27
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/src/main/java/com/example/android/agendadata/CalendarQueryService.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.agendadata;
+
+
+import static com.example.android.agendadata.Constants.TAG;
+import static com.example.android.agendadata.Constants.CONNECTION_TIME_OUT_MS;
+import static com.example.android.agendadata.Constants.CAL_DATA_ITEM_PATH_PREFIX;
+import static com.example.android.agendadata.Constants.ALL_DAY;
+import static com.example.android.agendadata.Constants.BEGIN;
+import static com.example.android.agendadata.Constants.DATA_ITEM_URI;
+import static com.example.android.agendadata.Constants.DESCRIPTION;
+import static com.example.android.agendadata.Constants.END;
+import static com.example.android.agendadata.Constants.EVENT_ID;
+import static com.example.android.agendadata.Constants.ID;
+import static com.example.android.agendadata.Constants.PROFILE_PIC;
+import static com.example.android.agendadata.Constants.TITLE;
+
+import android.app.IntentService;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.CalendarContract;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.text.format.Time;
+import android.util.Log;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
+import com.google.android.gms.wearable.Asset;
+import com.google.android.gms.wearable.DataMap;
+import com.google.android.gms.wearable.PutDataMapRequest;
+import com.google.android.gms.wearable.Wearable;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Queries calendar events using Android Calendar Provider API and creates a data item for each
+ * event.
+ */
+public class CalendarQueryService extends IntentService
+ implements ConnectionCallbacks, OnConnectionFailedListener {
+
+ private static final String[] INSTANCE_PROJECTION = {
+ CalendarContract.Instances._ID,
+ CalendarContract.Instances.EVENT_ID,
+ CalendarContract.Instances.TITLE,
+ CalendarContract.Instances.BEGIN,
+ CalendarContract.Instances.END,
+ CalendarContract.Instances.ALL_DAY,
+ CalendarContract.Instances.DESCRIPTION,
+ CalendarContract.Instances.ORGANIZER
+ };
+
+ private static final String[] CONTACT_PROJECTION = new String[] { Data._ID, Data.CONTACT_ID };
+ private static final String CONTACT_SELECTION = Email.ADDRESS + " = ?";
+
+ private GoogleApiClient mGoogleApiClient;
+
+ public CalendarQueryService() {
+ super(CalendarQueryService.class.getSimpleName());
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mGoogleApiClient = new GoogleApiClient.Builder(this)
+ .addApi(Wearable.API)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .build();
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ mGoogleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
+ // Query calendar events in the next 24 hours.
+ Time time = new Time();
+ time.setToNow();
+ long beginTime = time.toMillis(true);
+ time.monthDay++;
+ time.normalize(true);
+ long endTime = time.normalize(true);
+
+ List<Event> events = queryEvents(this, beginTime, endTime);
+ for (Event event : events) {
+ final PutDataMapRequest putDataMapRequest = event.toPutDataMapRequest();
+ if (mGoogleApiClient.isConnected()) {
+ Wearable.DataApi.putDataItem(
+ mGoogleApiClient, putDataMapRequest.asPutDataRequest()).await();
+ } else {
+ Log.e(TAG, "Failed to send data item: " + putDataMapRequest
+ + " - Client disconnected from Google Play Services");
+ }
+ }
+ mGoogleApiClient.disconnect();
+ }
+
+ private static String makeDataItemPath(long eventId, long beginTime) {
+ return CAL_DATA_ITEM_PATH_PREFIX + eventId + "/" + beginTime;
+ }
+
+ private static List<Event> queryEvents(Context context, long beginTime, long endTime) {
+ ContentResolver contentResolver = context.getContentResolver();
+ Uri.Builder builder = CalendarContract.Instances.CONTENT_URI.buildUpon();
+ ContentUris.appendId(builder, beginTime);
+ ContentUris.appendId(builder, endTime);
+
+ Cursor cursor = contentResolver.query(builder.build(), INSTANCE_PROJECTION,
+ null /* selection */, null /* selectionArgs */, null /* sortOrder */);
+ try {
+ int idIdx = cursor.getColumnIndex(CalendarContract.Instances._ID);
+ int eventIdIdx = cursor.getColumnIndex(CalendarContract.Instances.EVENT_ID);
+ int titleIdx = cursor.getColumnIndex(CalendarContract.Instances.TITLE);
+ int beginIdx = cursor.getColumnIndex(CalendarContract.Instances.BEGIN);
+ int endIdx = cursor.getColumnIndex(CalendarContract.Instances.END);
+ int allDayIdx = cursor.getColumnIndex(CalendarContract.Instances.ALL_DAY);
+ int descIdx = cursor.getColumnIndex(CalendarContract.Instances.DESCRIPTION);
+ int ownerEmailIdx = cursor.getColumnIndex(CalendarContract.Instances.ORGANIZER);
+
+ List<Event> events = new ArrayList<Event>(cursor.getCount());
+ while (cursor.moveToNext()) {
+ Event event = new Event();
+ event.id = cursor.getLong(idIdx);
+ event.eventId = cursor.getLong(eventIdIdx);
+ event.title = cursor.getString(titleIdx);
+ event.begin = cursor.getLong(beginIdx);
+ event.end = cursor.getLong(endIdx);
+ event.allDay = cursor.getInt(allDayIdx) != 0;
+ event.description = cursor.getString(descIdx);
+ String ownerEmail = cursor.getString(ownerEmailIdx);
+ Cursor contactCursor = contentResolver.query(Data.CONTENT_URI,
+ CONTACT_PROJECTION, CONTACT_SELECTION, new String[] {ownerEmail}, null);
+ int ownerIdIdx = contactCursor.getColumnIndex(Data.CONTACT_ID);
+ long ownerId = -1;
+ if (contactCursor.moveToFirst()) {
+ ownerId = contactCursor.getLong(ownerIdIdx);
+ }
+ contactCursor.close();
+ // Use event organizer's profile picture as the notification background.
+ event.ownerProfilePic = getProfilePicture(contentResolver, context, ownerId);
+ events.add(event);
+ }
+ return events;
+ } finally {
+ cursor.close();
+ }
+ }
+
+ @Override
+ public void onConnected(Bundle connectionHint) {
+ }
+
+ @Override
+ public void onConnectionSuspended(int cause) {
+ }
+
+ @Override
+ public void onConnectionFailed(ConnectionResult result) {
+ }
+
+ private static Asset getDefaultProfile(Resources res) {
+ Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.nobody);
+ return Asset.createFromBytes(toByteArray(bitmap));
+ }
+
+ private static Asset getProfilePicture(ContentResolver contentResolver, Context context,
+ long contactId) {
+ if (contactId != -1) {
+ // Try to retrieve the profile picture for the given contact.
+ Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
+ InputStream inputStream = Contacts.openContactPhotoInputStream(contentResolver,
+ contactUri, true /*preferHighres*/);
+
+ if (null != inputStream) {
+ try {
+ Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
+ if (bitmap != null) {
+ return Asset.createFromBytes(toByteArray(bitmap));
+ } else {
+ Log.e(TAG, "Cannot decode profile picture for contact " + contactId);
+ }
+ } finally {
+ closeQuietly(inputStream);
+ }
+ }
+ }
+ // Use a default background image if the user has no profile picture or there was an error.
+ return getDefaultProfile(context.getResources());
+ }
+
+ private static byte[] toByteArray(Bitmap bitmap) {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
+ byte[] byteArray = stream.toByteArray();
+ closeQuietly(stream);
+ return byteArray;
+ }
+
+ private static void closeQuietly(Closeable closeable) {
+ try {
+ closeable.close();
+ } catch (IOException e) {
+ Log.e(TAG, "IOException while closing closeable.", e);
+ }
+ }
+
+ private static class Event {
+
+ public long id;
+ public long eventId;
+ public String title;
+ public long begin;
+ public long end;
+ public boolean allDay;
+ public String description;
+ public Asset ownerProfilePic;
+
+ public PutDataMapRequest toPutDataMapRequest(){
+ final PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(
+ makeDataItemPath(eventId, begin));
+ DataMap data = putDataMapRequest.getDataMap();
+ data.putString(DATA_ITEM_URI, putDataMapRequest.getUri().toString());
+ data.putLong(ID, id);
+ data.putLong(EVENT_ID, eventId);
+ data.putString(TITLE, title);
+ data.putLong(BEGIN, begin);
+ data.putLong(END, end);
+ data.putBoolean(ALL_DAY, allDay);
+ data.putString(DESCRIPTION, description);
+ data.putAsset(PROFILE_PIC, ownerProfilePic);
+
+ return putDataMapRequest;
+ }
+ }
+}
diff --git a/wearable/wear/AgendaData/Application/src/main/java/com/example/android/agendadata/Constants.java b/wearable/wear/AgendaData/Application/src/main/java/com/example/android/agendadata/Constants.java
new file mode 100644
index 0000000..d66e7ca
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/src/main/java/com/example/android/agendadata/Constants.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.agendadata;
+
+/** Constants used in companion app. */
+public final class Constants {
+ private Constants() {
+ }
+
+ public static final String TAG = "AgendaDataSample";
+
+ public static final String CAL_DATA_ITEM_PATH_PREFIX = "/event";
+ // Timeout for making a connection to GoogleApiClient (in milliseconds).
+ public static final long CONNECTION_TIME_OUT_MS = 100;
+
+ public static final String EVENT_ID = "event_id";
+ public static final String ID = "id";
+ public static final String TITLE = "title";
+ public static final String DESCRIPTION = "description";
+ public static final String BEGIN = "begin";
+ public static final String END = "end";
+ public static final String DATA_ITEM_URI = "data_item_uri";
+ public static final String ALL_DAY = "all_day";
+ public static final String PROFILE_PIC = "profile_pic";
+}
diff --git a/wearable/wear/AgendaData/Application/src/main/java/com/example/android/agendadata/MainActivity.java b/wearable/wear/AgendaData/Application/src/main/java/com/example/android/agendadata/MainActivity.java
new file mode 100644
index 0000000..e999fde
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/src/main/java/com/example/android/agendadata/MainActivity.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.agendadata;
+
+import static com.example.android.agendadata.Constants.TAG;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
+import com.google.android.gms.common.api.ResultCallback;
+import com.google.android.gms.common.data.FreezableUtils;
+import com.google.android.gms.wearable.DataApi;
+import com.google.android.gms.wearable.DataItem;
+import com.google.android.gms.wearable.DataItemBuffer;
+import com.google.android.gms.wearable.Node;
+import com.google.android.gms.wearable.NodeApi;
+import com.google.android.gms.wearable.Wearable;
+
+import java.util.List;
+
+public class MainActivity extends Activity implements NodeApi.NodeListener, ConnectionCallbacks,
+ OnConnectionFailedListener {
+
+ /** Request code for launching the Intent to resolve Google Play services errors. */
+ private static final int REQUEST_RESOLVE_ERROR = 1000;
+
+ private GoogleApiClient mGoogleApiClient;
+ private boolean mResolvingError = false;
+
+ private TextView mLogTextView;
+ ScrollView mScroller;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main);
+ mLogTextView = (TextView) findViewById(R.id.log);
+ mScroller = (ScrollView) findViewById(R.id.scroller);
+ mGoogleApiClient = new GoogleApiClient.Builder(this)
+ .addApi(Wearable.API)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .build();
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ if (!mResolvingError) {
+ mGoogleApiClient.connect();
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ if (mGoogleApiClient.isConnected()) {
+ Wearable.NodeApi.removeListener(mGoogleApiClient, this);
+ }
+ mGoogleApiClient.disconnect();
+ super.onStop();
+ }
+
+ public void onGetEventsClicked(View v) {
+ startService(new Intent(this, CalendarQueryService.class));
+ }
+
+ public void onDeleteEventsClicked(View v) {
+ if (mGoogleApiClient.isConnected()) {
+ Wearable.DataApi.getDataItems(mGoogleApiClient)
+ .setResultCallback(new ResultCallback<DataItemBuffer>() {
+ @Override
+ public void onResult(DataItemBuffer result) {
+ if (result.getStatus().isSuccess()) {
+ deleteDataItems(result);
+ } else {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "onDeleteEventsClicked(): failed to get Data Items");
+ }
+ }
+ result.close();
+ }
+ });
+ } else {
+ Log.e(TAG, "Failed to delete data items"
+ + " - Client disconnected from Google Play Services");
+ }
+ }
+
+ private void deleteDataItems(DataItemBuffer dataItems) {
+ if (mGoogleApiClient.isConnected()) {
+ // Store the DataItem URIs in a List and close the buffer. Then use these URIs
+ // to delete the DataItems.
+ final List<DataItem> dataItemList = FreezableUtils.freezeIterable(dataItems);
+ dataItems.close();
+ for (final DataItem dataItem : dataItemList) {
+ final Uri dataItemUri = dataItem.getUri();
+ // In a real calendar application, this might delete the corresponding calendar
+ // event from the calendar data provider. In this sample, we simply delete the
+ // DataItem, but leave the phone's calendar data intact.
+ Wearable.DataApi.deleteDataItems(mGoogleApiClient, dataItemUri)
+ .setResultCallback(new ResultCallback<DataApi.DeleteDataItemsResult>() {
+ @Override
+ public void onResult(DataApi.DeleteDataItemsResult deleteResult) {
+ if (deleteResult.getStatus().isSuccess()) {
+ appendLog("Successfully deleted data item: " + dataItemUri);
+ } else {
+ appendLog("Failed to delete data item:" + dataItemUri);
+ }
+ }
+ });
+ }
+ } else {
+ Log.e(TAG, "Failed to delete data items"
+ + " - Client disconnected from Google Play Services");
+ }
+ }
+
+ private void appendLog(final String s) {
+ mLogTextView.post(new Runnable() {
+ @Override
+ public void run() {
+ mLogTextView.append(s);
+ mLogTextView.append("\n");
+ mScroller.fullScroll(View.FOCUS_DOWN);
+ }
+ });
+ }
+
+ @Override
+ public void onPeerConnected(Node peer) {
+ appendLog("Device connected");
+ }
+
+ @Override
+ public void onPeerDisconnected(Node peer) {
+ appendLog("Device disconnected");
+ }
+
+ @Override
+ public void onConnected(Bundle connectionHint) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Connected to Google Api Service");
+ }
+ mResolvingError = false;
+ Wearable.NodeApi.addListener(mGoogleApiClient, this);
+ }
+
+ @Override
+ public void onConnectionSuspended(int cause) {
+ // Ignore
+ }
+
+ @Override
+ public void onConnectionFailed(ConnectionResult result) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Disconnected from Google Api Service");
+ }
+ if (null != Wearable.NodeApi) {
+ Wearable.NodeApi.removeListener(mGoogleApiClient, this);
+ }
+ if (mResolvingError) {
+ // Already attempting to resolve an error.
+ return;
+ } else if (result.hasResolution()) {
+ try {
+ mResolvingError = true;
+ result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
+ } catch (IntentSender.SendIntentException e) {
+ // There was an error with the resolution intent. Try again.
+ mGoogleApiClient.connect();
+ }
+ } else {
+ mResolvingError = false;
+ }
+ }
+}
diff --git a/wearable/wear/AgendaData/Application/src/main/res/drawable-hdpi/ic_launcher.png b/wearable/wear/AgendaData/Application/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..0564717
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Application/src/main/res/drawable-mdpi/ic_launcher.png b/wearable/wear/AgendaData/Application/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..0f40347
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Application/src/main/res/drawable-nodpi/nobody.png b/wearable/wear/AgendaData/Application/src/main/res/drawable-nodpi/nobody.png
new file mode 100644
index 0000000..5a33d60
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/src/main/res/drawable-nodpi/nobody.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/wearable/wear/AgendaData/Application/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..d7705cf
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/wearable/wear/AgendaData/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..f07299f
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Application/src/main/res/layout/main.xml b/wearable/wear/AgendaData/Application/src/main/res/layout/main.xml
new file mode 100644
index 0000000..8e82cdd
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/src/main/res/layout/main.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <Button
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/get_events"
+ android:onClick="onGetEventsClicked"/>
+ <Button
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/delete_events"
+ android:onClick="onDeleteEventsClicked"/>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:textAppearanceLarge"
+ android:layout_marginTop="6dp"
+ android:padding="6dp"
+ android:text="@string/log"
+ android:textAllCaps="true"
+ android:textColor="@android:color/white"
+ android:background="@android:color/black"/>
+
+ <ScrollView
+ android:id="@+id/scroller"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:id="@+id/log"
+ android:fontFamily="courier"
+ android:textColor="@android:color/white"
+ android:background="@android:color/black"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ </ScrollView>
+</LinearLayout>
diff --git a/wearable/wear/AgendaData/Application/src/main/res/values/strings.xml b/wearable/wear/AgendaData/Application/src/main/res/values/strings.xml
new file mode 100644
index 0000000..9969f4f
--- /dev/null
+++ b/wearable/wear/AgendaData/Application/src/main/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="get_events">Sync calendar events to wearable</string>
+ <string name="delete_events">Delete calendar events from wearable</string>
+ <string name="log">Log</string>
+</resources>
diff --git a/wearable/wear/AgendaData/CONTRIB.md b/wearable/wear/AgendaData/CONTRIB.md
new file mode 100644
index 0000000..14a4fcf
--- /dev/null
+++ b/wearable/wear/AgendaData/CONTRIB.md
@@ -0,0 +1,35 @@
+# How to become a contributor and submit your own code
+
+## Contributor License Agreements
+
+We'd love to accept your sample apps and patches! Before we can take them, we
+have to jump a couple of legal hurdles.
+
+Please fill out either the individual or corporate Contributor License Agreement (CLA).
+
+ * If you are an individual writing original source code and you're sure you
+ own the intellectual property, then you'll need to sign an [individual CLA]
+ (https://developers.google.com/open-source/cla/individual).
+ * If you work for a company that wants to allow you to contribute your work,
+ then you'll need to sign a [corporate CLA]
+ (https://developers.google.com/open-source/cla/corporate).
+
+Follow either of the two links above to access the appropriate CLA and
+instructions for how to sign and return it. Once we receive it, we'll be able to
+accept your pull requests.
+
+## Contributing A Patch
+
+1. Submit an issue describing your proposed change to the repo in question.
+1. The repo owner will respond to your issue promptly.
+1. If your proposed change is accepted, and you haven't already done so, sign a
+ Contributor License Agreement (see details above).
+1. Fork the desired repo, develop and test your code changes.
+1. Ensure that your code adheres to the existing style in the sample to which
+ you are contributing. Refer to the
+ [Android Code Style Guide]
+ (https://source.android.com/source/code-style.html) for the
+ recommended coding standards for this organization.
+1. Ensure that your code has an appropriate set of unit tests which all pass.
+1. Submit a pull request.
+
diff --git a/wearable/wear/AgendaData/LICENSE b/wearable/wear/AgendaData/LICENSE
new file mode 100644
index 0000000..1af981f
--- /dev/null
+++ b/wearable/wear/AgendaData/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/wearable/wear/AgendaData/README-wear.txt b/wearable/wear/AgendaData/README-wear.txt
new file mode 100644
index 0000000..17523d7
--- /dev/null
+++ b/wearable/wear/AgendaData/README-wear.txt
@@ -0,0 +1,30 @@
+<#--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+Steps to use Wear template on top of an existing sample:
+- In template-params.xml.ftl:
+ - Add the following template:
+ <template src="Wear"/>
+
+- Refresh your project (./gradlew refresh)
+- Add Wearable-specific code to Wearable directory
+- Add code to be shared among the main application and the wearable to Shared
+ directory
+
+Note that you still need the main application sample code. This is usually
+achieved by adding another template, like "base" for example.
+
+
diff --git a/wearable/wear/AgendaData/Shared/.gitignore b/wearable/wear/AgendaData/Shared/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/AgendaData/Shared/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/AgendaData/Shared/src/main/AndroidManifest.xml b/wearable/wear/AgendaData/Shared/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..07bc153
--- /dev/null
+++ b/wearable/wear/AgendaData/Shared/src/main/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.agendadata.common">
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name">
+ </application>
+
+</manifest>
diff --git a/wearable/wear/AgendaData/Shared/src/main/res/values/strings.xml b/wearable/wear/AgendaData/Shared/src/main/res/values/strings.xml
new file mode 100644
index 0000000..0f2bb90
--- /dev/null
+++ b/wearable/wear/AgendaData/Shared/src/main/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <string name="app_name">Shared</string>
+</resources>
diff --git a/wearable/wear/AgendaData/Wearable/.gitignore b/wearable/wear/AgendaData/Wearable/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/AgendaData/Wearable/src/main/AndroidManifest.xml b/wearable/wear/AgendaData/Wearable/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..c91f09c
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/AndroidManifest.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.agendadata" >
+
+ <uses-sdk android:minSdkVersion="20"
+ android:targetSdkVersion="20" />
+
+ <uses-feature android:name="android.hardware.type.watch" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ >
+
+ <meta-data
+ android:name="com.google.android.gms.version"
+ android:value="@integer/google_play_services_version" />
+
+ <service
+ android:name="com.example.android.agendadata.HomeListenerService" >
+ <intent-filter>
+ <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
+ </intent-filter>
+ </service>
+
+ <service android:name="com.example.android.agendadata.DeleteService"/>
+
+ <activity android:name="android.support.wearable.activity.ConfirmationActivity"/>
+
+ </application>
+</manifest>
diff --git a/wearable/wear/AgendaData/Wearable/src/main/java/com/example/android/agendadata/Constants.java b/wearable/wear/AgendaData/Wearable/src/main/java/com/example/android/agendadata/Constants.java
new file mode 100644
index 0000000..5b51751
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/java/com/example/android/agendadata/Constants.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.agendadata;
+
+/** Constants used in wearable app. */
+public final class Constants {
+
+ private Constants() {
+ }
+
+ public static final String TAG = "AgendaDataSample";
+
+ public static final String TITLE = "title";
+ public static final String DESCRIPTION = "description";
+ public static final String BEGIN = "begin";
+ public static final String END = "end";
+ public static final String ALL_DAY = "all_day";
+ public static final String PROFILE_PIC = "profile_pic";
+
+ public static final String EXTRA_SILENT = "silent";
+}
diff --git a/wearable/wear/AgendaData/Wearable/src/main/java/com/example/android/agendadata/DeleteService.java b/wearable/wear/AgendaData/Wearable/src/main/java/com/example/android/agendadata/DeleteService.java
new file mode 100644
index 0000000..7c6bb9b
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/java/com/example/android/agendadata/DeleteService.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.agendadata;
+
+import static com.example.android.agendadata.Constants.TAG;
+import static com.example.android.agendadata.Constants.EXTRA_SILENT;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.wearable.activity.ConfirmationActivity;
+import android.util.Log;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.wearable.DataApi;
+import com.google.android.gms.wearable.Wearable;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Handles "Delete" button on calendar event card.
+ */
+public class DeleteService extends IntentService implements GoogleApiClient.ConnectionCallbacks,
+ GoogleApiClient.OnConnectionFailedListener {
+
+ /* Timeout for making a connection to GoogleApiClient (in milliseconds) */
+ private static final long TIME_OUT = 100;
+
+ private GoogleApiClient mGoogleApiClient;
+
+ public DeleteService() {
+ super(DeleteService.class.getSimpleName());
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mGoogleApiClient = new GoogleApiClient.Builder(this)
+ .addApi(Wearable.API)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .build();
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ mGoogleApiClient.blockingConnect(TIME_OUT, TimeUnit.MILLISECONDS);
+ Uri dataItemUri = intent.getData();
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "DeleteService.onHandleIntent=" + dataItemUri);
+ }
+ if (mGoogleApiClient.isConnected()) {
+ DataApi.DeleteDataItemsResult result = Wearable.DataApi
+ .deleteDataItems(mGoogleApiClient, dataItemUri).await();
+ if (result.getStatus().isSuccess() && !intent.getBooleanExtra(EXTRA_SILENT, false)) {
+ // Show the success animation on the watch unless Silent extra is true.
+ startConfirmationActivity(ConfirmationActivity.SUCCESS_ANIMATION,
+ getString(R.string.delete_successful));
+ } else {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "DeleteService.onHandleIntent: Failed to delete dataItem:"
+ + dataItemUri);
+ }
+ // Show the failure animation on the watch unless Silent extra is true.
+ if (!intent.getBooleanExtra(EXTRA_SILENT, false)) {
+ startConfirmationActivity(ConfirmationActivity.FAILURE_ANIMATION,
+ getString(R.string.delete_unsuccessful));
+ }
+ }
+ } else {
+ Log.e(TAG, "Failed to delete data item: " + dataItemUri
+ + " - Client disconnected from Google Play Services");
+ // Show the failure animation on the watch unless Silent extra is true.
+ if (!intent.getBooleanExtra(EXTRA_SILENT, false)) {
+ startConfirmationActivity(ConfirmationActivity.FAILURE_ANIMATION,
+ getString(R.string.delete_unsuccessful));
+ }
+ }
+ mGoogleApiClient.disconnect();
+ }
+
+ private void startConfirmationActivity(int animationType, String message) {
+ Intent confirmationActivity = new Intent(this, ConfirmationActivity.class)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION)
+ .putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, animationType)
+ .putExtra(ConfirmationActivity.EXTRA_MESSAGE, message);
+ startActivity(confirmationActivity);
+ }
+
+ @Override
+ public void onConnected(Bundle connectionHint) {
+ }
+
+ @Override
+ public void onConnectionSuspended(int cause) {
+ }
+
+ @Override
+ public void onConnectionFailed(ConnectionResult result) {
+ }
+
+}
diff --git a/wearable/wear/AgendaData/Wearable/src/main/java/com/example/android/agendadata/HomeListenerService.java b/wearable/wear/AgendaData/Wearable/src/main/java/com/example/android/agendadata/HomeListenerService.java
new file mode 100644
index 0000000..7a46911
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/java/com/example/android/agendadata/HomeListenerService.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.agendadata;
+
+import static com.example.android.agendadata.Constants.TAG;
+import static com.example.android.agendadata.Constants.EXTRA_SILENT;
+
+import static com.example.android.agendadata.Constants.ALL_DAY;
+import static com.example.android.agendadata.Constants.BEGIN;
+import static com.example.android.agendadata.Constants.DESCRIPTION;
+import static com.example.android.agendadata.Constants.END;
+import static com.example.android.agendadata.Constants.PROFILE_PIC;
+import static com.example.android.agendadata.Constants.TITLE;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.util.Log;
+
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.wearable.Asset;
+import com.google.android.gms.wearable.DataApi;
+import com.google.android.gms.wearable.DataEvent;
+import com.google.android.gms.wearable.DataEventBuffer;
+import com.google.android.gms.wearable.DataItem;
+import com.google.android.gms.wearable.DataMap;
+import com.google.android.gms.wearable.DataMapItem;
+import com.google.android.gms.wearable.MessageEvent;
+import com.google.android.gms.wearable.Wearable;
+import com.google.android.gms.wearable.WearableListenerService;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Listens to DataItem events on the home device.
+ */
+public class HomeListenerService extends WearableListenerService {
+
+ private static final Map<Uri, Integer> sNotificationIdByDataItemUri =
+ new HashMap<Uri, Integer>();
+ private static int sNotificationId = 1;
+ private GoogleApiClient mGoogleApiClient;
+
+ @Override
+ public void onDataChanged(DataEventBuffer dataEvents) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "onDataChanged: " + dataEvents + " for " + getPackageName());
+ }
+ for (DataEvent event : dataEvents) {
+ if (event.getType() == DataEvent.TYPE_DELETED) {
+ deleteDataItem(event.getDataItem());
+ } else if (event.getType() == DataEvent.TYPE_CHANGED) {
+ UpdateNotificationForDataItem(event.getDataItem());
+ }
+ }
+ dataEvents.close();
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mGoogleApiClient = new GoogleApiClient.Builder(this.getApplicationContext())
+ .addApi(Wearable.API)
+ .build();
+ mGoogleApiClient.connect();
+ }
+
+ /**
+ * Posts a local notification to show calendar card.
+ */
+ private void UpdateNotificationForDataItem(DataItem dataItem) {
+ DataMapItem mapDataItem = DataMapItem.fromDataItem(dataItem);
+ DataMap data = mapDataItem.getDataMap();
+
+ String description = data.getString(DESCRIPTION);
+ if (TextUtils.isEmpty(description)) {
+ description = "";
+ } else {
+ // Add a space between the description and the time of the event.
+ description += " ";
+ }
+ String contentText;
+ if (data.getBoolean(ALL_DAY)) {
+ contentText = getString(R.string.desc_all_day, description);
+ } else {
+ String startTime = DateFormat.getTimeFormat(this).format(new Date(data.getLong(BEGIN)));
+ String endTime = DateFormat.getTimeFormat(this).format(new Date(data.getLong(END)));
+ contentText = getString(R.string.desc_time_period, description, startTime, endTime);
+ }
+
+ Intent deleteOperation = new Intent(this, DeleteService.class);
+ // Use a unique identifier for the delete action.
+ String deleteAction = "action_delete" + dataItem.getUri().toString() + sNotificationId;
+ deleteOperation.setAction(deleteAction);
+ deleteOperation.setData(dataItem.getUri());
+ PendingIntent deleteIntent = PendingIntent.getService(this, 0, deleteOperation,
+ PendingIntent.FLAG_ONE_SHOT);
+ PendingIntent silentDeleteIntent = PendingIntent.getService(this, 1,
+ deleteOperation.putExtra(EXTRA_SILENT, true), PendingIntent.FLAG_ONE_SHOT);
+
+ Notification.Builder notificationBuilder = new Notification.Builder(this)
+ .setContentTitle(data.getString(TITLE))
+ .setContentText(contentText)
+ .setSmallIcon(R.drawable.ic_launcher)
+ .addAction(R.drawable.ic_menu_delete, getText(R.string.delete), deleteIntent)
+ .setDeleteIntent(silentDeleteIntent) // Delete DataItem if notification dismissed.
+ .setLocalOnly(true)
+ .setPriority(Notification.PRIORITY_MIN);
+
+ // Set the event owner's profile picture as the notification background.
+ Asset asset = data.getAsset(PROFILE_PIC);
+ if (null != asset) {
+ if (mGoogleApiClient.isConnected()) {
+ DataApi.GetFdForAssetResult assetFdResult =
+ Wearable.DataApi.getFdForAsset(mGoogleApiClient, asset).await();
+ if (assetFdResult.getStatus().isSuccess()) {
+ Bitmap profilePic = BitmapFactory.decodeStream(assetFdResult.getInputStream());
+ notificationBuilder.extend(new Notification.WearableExtender()
+ .setBackground(profilePic));
+ } else if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "asset fetch failed with statusCode: "
+ + assetFdResult.getStatus().getStatusCode());
+ }
+ } else {
+ Log.e(TAG, "Failed to set notification background"
+ + " - Client disconnected from Google Play Services");
+ }
+ }
+ Notification card = notificationBuilder.build();
+
+ ((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
+ .notify(sNotificationId, card);
+
+ sNotificationIdByDataItemUri.put(dataItem.getUri(), sNotificationId++);
+ }
+
+ /**
+ * Deletes the calendar card associated with the data item.
+ */
+ private void deleteDataItem(DataItem dataItem) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "onDataItemDeleted:DataItem=" + dataItem.getUri());
+ }
+ Integer notificationId = sNotificationIdByDataItemUri.remove(dataItem.getUri());
+ if (notificationId != null) {
+ ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancel(notificationId);
+ }
+ }
+
+ @Override
+ public void onMessageReceived(MessageEvent messageEvent) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "onMessageReceived: " + messageEvent.getPath()
+ + " " + messageEvent.getData() + " for " + getPackageName());
+ }
+ }
+
+}
diff --git a/wearable/wear/AgendaData/Wearable/src/main/res/drawable-hdpi/ic_launcher.png b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..0564717
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Wearable/src/main/res/drawable-hdpi/ic_menu_delete.png b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-hdpi/ic_menu_delete.png
new file mode 100644
index 0000000..24d8f6a
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-hdpi/ic_menu_delete.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Wearable/src/main/res/drawable-mdpi/ic_launcher.png b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..0f40347
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Wearable/src/main/res/drawable-mdpi/ic_menu_delete.png b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-mdpi/ic_menu_delete.png
new file mode 100644
index 0000000..e2c8700
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-mdpi/ic_menu_delete.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Wearable/src/main/res/drawable-xhdpi/ic_launcher.png b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..d7705cf
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Wearable/src/main/res/drawable-xhdpi/ic_menu_delete.png b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-xhdpi/ic_menu_delete.png
new file mode 100644
index 0000000..65b9cae
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-xhdpi/ic_menu_delete.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..f07299f
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Wearable/src/main/res/drawable-xxhdpi/ic_menu_delete.png b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-xxhdpi/ic_menu_delete.png
new file mode 100644
index 0000000..8e9e78d
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/res/drawable-xxhdpi/ic_menu_delete.png
Binary files differ
diff --git a/wearable/wear/AgendaData/Wearable/src/main/res/values/strings.xml b/wearable/wear/AgendaData/Wearable/src/main/res/values/strings.xml
new file mode 100644
index 0000000..10ef53c
--- /dev/null
+++ b/wearable/wear/AgendaData/Wearable/src/main/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name">Android Wear AgendaData Example Application</string>
+ <string name="delete">Delete</string>
+ <string name="desc_all_day">%s(All day)</string>
+ <string name="desc_time_period">%1$s(%2$s - %3$s)</string>
+ <string name="delete_successful">Event deleted</string>
+ <string name="delete_unsuccessful">Unable to delete event</string>
+</resources>
diff --git a/wearable/wear/AgendaData/build.gradle b/wearable/wear/AgendaData/build.gradle
new file mode 100644
index 0000000..be1fa82
--- /dev/null
+++ b/wearable/wear/AgendaData/build.gradle
@@ -0,0 +1,14 @@
+
+
+
+
+// BEGIN_EXCLUDE
+import com.example.android.samples.build.SampleGenPlugin
+apply plugin: SampleGenPlugin
+
+samplegen {
+ pathToBuild "../../../../../build"
+ pathToSamplesCommon "../../../common"
+}
+apply from: "../../../../../build/build.gradle"
+// END_EXCLUDE
diff --git a/wearable/wear/AgendaData/buildSrc/build.gradle b/wearable/wear/AgendaData/buildSrc/build.gradle
new file mode 100644
index 0000000..e344a8c
--- /dev/null
+++ b/wearable/wear/AgendaData/buildSrc/build.gradle
@@ -0,0 +1,18 @@
+
+
+
+repositories {
+ mavenCentral()
+}
+dependencies {
+ compile 'org.freemarker:freemarker:2.3.20'
+}
+
+sourceSets {
+ main {
+ groovy {
+ srcDir new File(rootDir, "../../../../../../build/buildSrc/src/main/groovy")
+ }
+ }
+}
+
diff --git a/wearable/wear/AgendaData/gradle/wrapper/gradle-wrapper.jar b/wearable/wear/AgendaData/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/wearable/wear/AgendaData/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/wearable/wear/AgendaData/gradle/wrapper/gradle-wrapper.properties b/wearable/wear/AgendaData/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..d7f03cf
--- /dev/null
+++ b/wearable/wear/AgendaData/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-bin.zip
diff --git a/wearable/wear/AgendaData/gradlew b/wearable/wear/AgendaData/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/wearable/wear/AgendaData/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/wearable/wear/AgendaData/gradlew.bat b/wearable/wear/AgendaData/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/wearable/wear/AgendaData/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/wearable/wear/AgendaData/settings.gradle b/wearable/wear/AgendaData/settings.gradle
new file mode 100644
index 0000000..8522c57
--- /dev/null
+++ b/wearable/wear/AgendaData/settings.gradle
@@ -0,0 +1 @@
+include ':Application', ':Wearable', ':Shared'
diff --git a/wearable/wear/AgendaData/template-params.xml b/wearable/wear/AgendaData/template-params.xml
new file mode 100644
index 0000000..6da1cba
--- /dev/null
+++ b/wearable/wear/AgendaData/template-params.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<sample>
+ <name>AgendaData</name>
+ <group>Connectivity</group>
+ <package>com.example.android.agendadata</package>
+
+
+
+ <!-- change minSdk if needed-->
+ <minSdk>20</minSdk>
+
+
+ <strings>
+ <intro>
+ <![CDATA[
+ Syncs calendar events to your wearable at the press of a button, using the Wearable
+ DataApi to transmit data such as event time, description, and background image. The DataItems can be
+ deleted individually via an action on the event notifications, or all at once via a button on the
+ companion. When deleted using the notification action, a ConfirmationActivity is used to indicate
+ success or failure.
+ ]]>
+ </intro>
+ </strings>
+
+ <template src="base"/>
+ <template src="Wear"/>
+ <common src="logger"/>
+ <common src="activities"/>
+
+</sample>
diff --git a/wearable/wear/DataLayer/Application/.gitignore b/wearable/wear/DataLayer/Application/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/DataLayer/Application/proguard-project.txt b/wearable/wear/DataLayer/Application/proguard-project.txt
new file mode 100644
index 0000000..0d8f171
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/proguard-project.txt
@@ -0,0 +1,20 @@
+ To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/wearable/wear/DataLayer/Application/src/main/AndroidManifest.xml b/wearable/wear/DataLayer/Application/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..f382b25
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.datalayer" >
+
+ <uses-sdk android:minSdkVersion="19"
+ android:targetSdkVersion="19" />
+
+ <uses-feature android:name="android.hardware.camera" android:required="false" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name">
+
+ <meta-data
+ android:name="com.google.android.gms.version"
+ android:value="@integer/google_play_services_version" />
+
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:launchMode="singleTask" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/wearable/wear/DataLayer/Application/src/main/java/com/example/android/datalayer/MainActivity.java b/wearable/wear/DataLayer/Application/src/main/java/com/example/android/datalayer/MainActivity.java
new file mode 100644
index 0000000..d94261d
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/java/com/example/android/datalayer/MainActivity.java
@@ -0,0 +1,484 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.datalayer;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.MediaStore;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.ResultCallback;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
+import com.google.android.gms.common.data.FreezableUtils;
+import com.google.android.gms.wearable.Asset;
+import com.google.android.gms.wearable.DataApi.DataItemResult;
+import com.google.android.gms.wearable.DataEvent;
+import com.google.android.gms.wearable.DataEventBuffer;
+import com.google.android.gms.wearable.MessageApi.SendMessageResult;
+import com.google.android.gms.wearable.DataApi;
+import com.google.android.gms.wearable.MessageApi;
+import com.google.android.gms.wearable.MessageEvent;
+import com.google.android.gms.wearable.Node;
+import com.google.android.gms.wearable.NodeApi;
+import com.google.android.gms.wearable.PutDataMapRequest;
+import com.google.android.gms.wearable.PutDataRequest;
+import com.google.android.gms.wearable.Wearable;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Receives its own events using a listener API designed for foreground activities. Updates a data
+ * item every second while it is open. Also allows user to take a photo and send that as an asset to
+ * the paired wearable.
+ */
+public class MainActivity extends Activity implements DataApi.DataListener,
+ MessageApi.MessageListener, NodeApi.NodeListener, ConnectionCallbacks,
+ OnConnectionFailedListener {
+
+ private static final String TAG = "MainActivity";
+
+ /** Request code for launching the Intent to resolve Google Play services errors. */
+ private static final int REQUEST_RESOLVE_ERROR = 1000;
+
+ private static final String START_ACTIVITY_PATH = "/start-activity";
+ private static final String COUNT_PATH = "/count";
+ private static final String IMAGE_PATH = "/image";
+ private static final String IMAGE_KEY = "photo";
+ private static final String COUNT_KEY = "count";
+
+ private GoogleApiClient mGoogleApiClient;
+ private boolean mResolvingError = false;
+ private boolean mCameraSupported = false;
+
+ private ListView mDataItemList;
+ private Button mTakePhotoBtn;
+ private Button mSendPhotoBtn;
+ private ImageView mThumbView;
+ private Bitmap mImageBitmap;
+ private View mStartActivityBtn;
+
+ private DataItemAdapter mDataItemListAdapter;
+ private Handler mHandler;
+
+ // Send DataItems.
+ private ScheduledExecutorService mGeneratorExecutor;
+ private ScheduledFuture<?> mDataItemGeneratorFuture;
+
+ static final int REQUEST_IMAGE_CAPTURE = 1;
+
+ @Override
+ public void onCreate(Bundle b) {
+ super.onCreate(b);
+ mHandler = new Handler();
+ LOGD(TAG, "onCreate");
+ mCameraSupported = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
+ setContentView(R.layout.main_activity);
+ setupViews();
+
+ // Stores DataItems received by the local broadcaster or from the paired watch.
+ mDataItemListAdapter = new DataItemAdapter(this, android.R.layout.simple_list_item_1);
+ mDataItemList.setAdapter(mDataItemListAdapter);
+
+ mGeneratorExecutor = new ScheduledThreadPoolExecutor(1);
+
+ mGoogleApiClient = new GoogleApiClient.Builder(this)
+ .addApi(Wearable.API)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .build();
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
+ Bundle extras = data.getExtras();
+ mImageBitmap = (Bitmap) extras.get("data");
+ mThumbView.setImageBitmap(mImageBitmap);
+ }
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ if (!mResolvingError) {
+ mGoogleApiClient.connect();
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mDataItemGeneratorFuture = mGeneratorExecutor.scheduleWithFixedDelay(
+ new DataItemGenerator(), 1, 5, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mDataItemGeneratorFuture.cancel(true /* mayInterruptIfRunning */);
+ }
+
+ @Override
+ protected void onStop() {
+ if (!mResolvingError) {
+ Wearable.DataApi.removeListener(mGoogleApiClient, this);
+ Wearable.MessageApi.removeListener(mGoogleApiClient, this);
+ Wearable.NodeApi.removeListener(mGoogleApiClient, this);
+ mGoogleApiClient.disconnect();
+ }
+ super.onStop();
+ }
+
+ @Override //ConnectionCallbacks
+ public void onConnected(Bundle connectionHint) {
+ LOGD(TAG, "Google API Client was connected");
+ mResolvingError = false;
+ mStartActivityBtn.setEnabled(true);
+ mSendPhotoBtn.setEnabled(mCameraSupported);
+ Wearable.DataApi.addListener(mGoogleApiClient, this);
+ Wearable.MessageApi.addListener(mGoogleApiClient, this);
+ Wearable.NodeApi.addListener(mGoogleApiClient, this);
+ }
+
+ @Override //ConnectionCallbacks
+ public void onConnectionSuspended(int cause) {
+ LOGD(TAG, "Connection to Google API client was suspended");
+ mStartActivityBtn.setEnabled(false);
+ mSendPhotoBtn.setEnabled(false);
+ }
+
+ @Override //OnConnectionFailedListener
+ public void onConnectionFailed(ConnectionResult result) {
+ if (mResolvingError) {
+ // Already attempting to resolve an error.
+ return;
+ } else if (result.hasResolution()) {
+ try {
+ mResolvingError = true;
+ result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
+ } catch (IntentSender.SendIntentException e) {
+ // There was an error with the resolution intent. Try again.
+ mGoogleApiClient.connect();
+ }
+ } else {
+ Log.e(TAG, "Connection to Google API client has failed");
+ mResolvingError = false;
+ mStartActivityBtn.setEnabled(false);
+ mSendPhotoBtn.setEnabled(false);
+ Wearable.DataApi.removeListener(mGoogleApiClient, this);
+ Wearable.MessageApi.removeListener(mGoogleApiClient, this);
+ Wearable.NodeApi.removeListener(mGoogleApiClient, this);
+ }
+ }
+
+ @Override //DataListener
+ public void onDataChanged(DataEventBuffer dataEvents) {
+ LOGD(TAG, "onDataChanged: " + dataEvents);
+ final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
+ dataEvents.close();
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ for (DataEvent event : events) {
+ if (event.getType() == DataEvent.TYPE_CHANGED) {
+ mDataItemListAdapter.add(
+ new Event("DataItem Changed", event.getDataItem().toString()));
+ } else if (event.getType() == DataEvent.TYPE_DELETED) {
+ mDataItemListAdapter.add(
+ new Event("DataItem Deleted", event.getDataItem().toString()));
+ }
+ }
+ }
+ });
+ }
+
+ @Override //MessageListener
+ public void onMessageReceived(final MessageEvent messageEvent) {
+ LOGD(TAG, "onMessageReceived() A message from watch was received:" + messageEvent
+ .getRequestId() + " " + messageEvent.getPath());
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mDataItemListAdapter.add(new Event("Message from watch", messageEvent.toString()));
+ }
+ });
+
+ }
+
+ @Override //NodeListener
+ public void onPeerConnected(final Node peer) {
+ LOGD(TAG, "onPeerConnected: " + peer);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mDataItemListAdapter.add(new Event("Connected", peer.toString()));
+ }
+ });
+
+ }
+
+ @Override //NodeListener
+ public void onPeerDisconnected(final Node peer) {
+ LOGD(TAG, "onPeerDisconnected: " + peer);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mDataItemListAdapter.add(new Event("Disconnected", peer.toString()));
+ }
+ });
+ }
+
+ /**
+ * A View Adapter for presenting the Event objects in a list
+ */
+ private static class DataItemAdapter extends ArrayAdapter<Event> {
+
+ private final Context mContext;
+
+ public DataItemAdapter(Context context, int unusedResource) {
+ super(context, unusedResource);
+ mContext = context;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+ if (convertView == null) {
+ holder = new ViewHolder();
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ convertView = inflater.inflate(android.R.layout.two_line_list_item, null);
+ convertView.setTag(holder);
+ holder.text1 = (TextView) convertView.findViewById(android.R.id.text1);
+ holder.text2 = (TextView) convertView.findViewById(android.R.id.text2);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+ Event event = getItem(position);
+ holder.text1.setText(event.title);
+ holder.text2.setText(event.text);
+ return convertView;
+ }
+
+ private class ViewHolder {
+
+ TextView text1;
+ TextView text2;
+ }
+ }
+
+ private class Event {
+
+ String title;
+ String text;
+
+ public Event(String title, String text) {
+ this.title = title;
+ this.text = text;
+ }
+ }
+
+ private Collection<String> getNodes() {
+ HashSet<String> results = new HashSet<String>();
+ NodeApi.GetConnectedNodesResult nodes =
+ Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
+
+ for (Node node : nodes.getNodes()) {
+ results.add(node.getId());
+ }
+
+ return results;
+ }
+
+ private void sendStartActivityMessage(String node) {
+ Wearable.MessageApi.sendMessage(
+ mGoogleApiClient, node, START_ACTIVITY_PATH, new byte[0]).setResultCallback(
+ new ResultCallback<SendMessageResult>() {
+ @Override
+ public void onResult(SendMessageResult sendMessageResult) {
+ if (!sendMessageResult.getStatus().isSuccess()) {
+ Log.e(TAG, "Failed to send message with status code: "
+ + sendMessageResult.getStatus().getStatusCode());
+ }
+ }
+ }
+ );
+ }
+
+ private class StartWearableActivityTask extends AsyncTask<Void, Void, Void> {
+
+ @Override
+ protected Void doInBackground(Void... args) {
+ Collection<String> nodes = getNodes();
+ for (String node : nodes) {
+ sendStartActivityMessage(node);
+ }
+ return null;
+ }
+ }
+
+ /** Sends an RPC to start a fullscreen Activity on the wearable. */
+ public void onStartWearableActivityClick(View view) {
+ LOGD(TAG, "Generating RPC");
+
+ // Trigger an AsyncTask that will query for a list of connected nodes and send a
+ // "start-activity" message to each connected node.
+ new StartWearableActivityTask().execute();
+ }
+
+ /** Generates a DataItem based on an incrementing count. */
+ private class DataItemGenerator implements Runnable {
+
+ private int count = 0;
+
+ @Override
+ public void run() {
+ PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(COUNT_PATH);
+ putDataMapRequest.getDataMap().putInt(COUNT_KEY, count++);
+ PutDataRequest request = putDataMapRequest.asPutDataRequest();
+
+ LOGD(TAG, "Generating DataItem: " + request);
+ if (!mGoogleApiClient.isConnected()) {
+ return;
+ }
+ Wearable.DataApi.putDataItem(mGoogleApiClient, request)
+ .setResultCallback(new ResultCallback<DataItemResult>() {
+ @Override
+ public void onResult(DataItemResult dataItemResult) {
+ if (!dataItemResult.getStatus().isSuccess()) {
+ Log.e(TAG, "ERROR: failed to putDataItem, status code: "
+ + dataItemResult.getStatus().getStatusCode());
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Dispatches an {@link android.content.Intent} to take a photo. Result will be returned back
+ * in onActivityResult().
+ */
+ private void dispatchTakePictureIntent() {
+ Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+ if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
+ startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
+ }
+ }
+
+ /**
+ * Builds an {@link com.google.android.gms.wearable.Asset} from a bitmap. The image that we get
+ * back from the camera in "data" is a thumbnail size. Typically, your image should not exceed
+ * 320x320 and if you want to have zoom and parallax effect in your app, limit the size of your
+ * image to 640x400. Resize your image before transferring to your wearable device.
+ */
+ private static Asset toAsset(Bitmap bitmap) {
+ ByteArrayOutputStream byteStream = null;
+ try {
+ byteStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
+ return Asset.createFromBytes(byteStream.toByteArray());
+ } finally {
+ if (null != byteStream) {
+ try {
+ byteStream.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * Sends the asset that was created form the photo we took by adding it to the Data Item store.
+ */
+ private void sendPhoto(Asset asset) {
+ PutDataMapRequest dataMap = PutDataMapRequest.create(IMAGE_PATH);
+ dataMap.getDataMap().putAsset(IMAGE_KEY, asset);
+ dataMap.getDataMap().putLong("time", new Date().getTime());
+ PutDataRequest request = dataMap.asPutDataRequest();
+ Wearable.DataApi.putDataItem(mGoogleApiClient, request)
+ .setResultCallback(new ResultCallback<DataItemResult>() {
+ @Override
+ public void onResult(DataItemResult dataItemResult) {
+ LOGD(TAG, "Sending image was successful: " + dataItemResult.getStatus()
+ .isSuccess());
+ }
+ });
+
+ }
+
+ public void onTakePhotoClick(View view) {
+ dispatchTakePictureIntent();
+ }
+
+ public void onSendPhotoClick(View view) {
+ if (null != mImageBitmap && mGoogleApiClient.isConnected()) {
+ sendPhoto(toAsset(mImageBitmap));
+ }
+ }
+
+ /**
+ * Sets up UI components and their callback handlers.
+ */
+ private void setupViews() {
+ mTakePhotoBtn = (Button) findViewById(R.id.takePhoto);
+ mSendPhotoBtn = (Button) findViewById(R.id.sendPhoto);
+
+ // Shows the image received from the handset
+ mThumbView = (ImageView) findViewById(R.id.imageView);
+ mDataItemList = (ListView) findViewById(R.id.data_item_list);
+
+ mStartActivityBtn = findViewById(R.id.start_wearable_activity);
+ }
+
+ /**
+ * As simple wrapper around Log.d
+ */
+ private static void LOGD(final String tag, String message) {
+ if (Log.isLoggable(tag, Log.DEBUG)) {
+ Log.d(tag, message);
+ }
+ }
+
+}
diff --git a/wearable/wear/DataLayer/Application/src/main/res/drawable-hdpi/ic_content_picture.png b/wearable/wear/DataLayer/Application/src/main/res/drawable-hdpi/ic_content_picture.png
new file mode 100644
index 0000000..597997c
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/res/drawable-hdpi/ic_content_picture.png
Binary files differ
diff --git a/wearable/wear/DataLayer/Application/src/main/res/drawable-hdpi/ic_launcher.png b/wearable/wear/DataLayer/Application/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..589f229
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DataLayer/Application/src/main/res/drawable-mdpi/ic_content_picture.png b/wearable/wear/DataLayer/Application/src/main/res/drawable-mdpi/ic_content_picture.png
new file mode 100644
index 0000000..c23f4c0
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/res/drawable-mdpi/ic_content_picture.png
Binary files differ
diff --git a/wearable/wear/DataLayer/Application/src/main/res/drawable-mdpi/ic_launcher.png b/wearable/wear/DataLayer/Application/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..77dd571
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DataLayer/Application/src/main/res/drawable-xhdpi/ic_content_picture.png b/wearable/wear/DataLayer/Application/src/main/res/drawable-xhdpi/ic_content_picture.png
new file mode 100644
index 0000000..289adf1
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/res/drawable-xhdpi/ic_content_picture.png
Binary files differ
diff --git a/wearable/wear/DataLayer/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/wearable/wear/DataLayer/Application/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..fe34ebe
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DataLayer/Application/src/main/res/drawable-xxhdpi/ic_content_picture.png b/wearable/wear/DataLayer/Application/src/main/res/drawable-xxhdpi/ic_content_picture.png
new file mode 100644
index 0000000..073ad55
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/res/drawable-xxhdpi/ic_content_picture.png
Binary files differ
diff --git a/wearable/wear/DataLayer/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/wearable/wear/DataLayer/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..ab80bcd
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DataLayer/Application/src/main/res/drawable/divider.xml b/wearable/wear/DataLayer/Application/src/main/res/drawable/divider.xml
new file mode 100644
index 0000000..95c4d33
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/res/drawable/divider.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <size android:height="2dip"/>
+ <solid android:color="#ffffffff"/>
+</shape>
diff --git a/wearable/wear/DataLayer/Application/src/main/res/layout/main_activity.xml b/wearable/wear/DataLayer/Application/src/main/res/layout/main_activity.xml
new file mode 100644
index 0000000..0412023
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/res/layout/main_activity.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <RelativeLayout
+ android:id="@+id/top"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_marginTop="10dp">
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/take_photo"
+ android:id="@+id/takePhoto"
+ android:onClick="onTakePhotoClick"
+ android:layout_marginLeft="39dp"
+ android:layout_alignParentStart="true"
+ android:layout_alignParentTop="true" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/send_photo"
+ android:id="@+id/sendPhoto"
+ android:layout_alignRight="@+id/takePhoto"
+ android:layout_marginLeft="39dp"
+ android:enabled="false"
+ android:onClick="onSendPhotoClick"
+ android:layout_alignParentStart="true"
+ android:layout_below="@+id/takePhoto" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/imageView"
+ android:layout_marginLeft="29dp"
+ android:layout_centerVertical="true"
+ android:layout_alignParentRight="true"
+ android:src="@drawable/ic_content_picture" />
+ </RelativeLayout>
+
+ <View
+ style="@style/Divider"
+ android:id="@+id/divider"
+ android:layout_below="@+id/top"
+ android:layout_marginTop="5dp"
+ android:layout_marginLeft="20dp"
+ android:layout_marginRight="20dp" />
+
+ <Button
+ android:id="@+id/start_wearable_activity"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="10dp"
+ android:onClick="onStartWearableActivityClick"
+ android:text="@string/start_wearable_activity"
+ android:enabled="false"
+ android:layout_below="@+id/divider"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="10dp" />
+
+ <ListView
+ android:id="@+id/data_item_list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_below="@+id/start_wearable_activity"
+ android:transcriptMode="alwaysScroll" />
+</RelativeLayout>
diff --git a/wearable/wear/DataLayer/Application/src/main/res/values/strings.xml b/wearable/wear/DataLayer/Application/src/main/res/values/strings.xml
new file mode 100644
index 0000000..9eba46c
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="start_wearable_activity">Start Wearable Activity</string>
+ <string name="start">Start</string>
+ <string name="take_photo">Take a Photo</string>
+ <string name="send_photo">Send Photo</string>
+</resources>
diff --git a/wearable/wear/DataLayer/Application/src/main/res/values/style.xml b/wearable/wear/DataLayer/Application/src/main/res/values/style.xml
new file mode 100644
index 0000000..81d6799
--- /dev/null
+++ b/wearable/wear/DataLayer/Application/src/main/res/values/style.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <style name="Divider">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">3dp</item>
+ <item name="android:background">?android:attr/listDivider</item>
+ </style>
+</resources>
diff --git a/wearable/wear/DataLayer/CONTRIB.md b/wearable/wear/DataLayer/CONTRIB.md
new file mode 100644
index 0000000..14a4fcf
--- /dev/null
+++ b/wearable/wear/DataLayer/CONTRIB.md
@@ -0,0 +1,35 @@
+# How to become a contributor and submit your own code
+
+## Contributor License Agreements
+
+We'd love to accept your sample apps and patches! Before we can take them, we
+have to jump a couple of legal hurdles.
+
+Please fill out either the individual or corporate Contributor License Agreement (CLA).
+
+ * If you are an individual writing original source code and you're sure you
+ own the intellectual property, then you'll need to sign an [individual CLA]
+ (https://developers.google.com/open-source/cla/individual).
+ * If you work for a company that wants to allow you to contribute your work,
+ then you'll need to sign a [corporate CLA]
+ (https://developers.google.com/open-source/cla/corporate).
+
+Follow either of the two links above to access the appropriate CLA and
+instructions for how to sign and return it. Once we receive it, we'll be able to
+accept your pull requests.
+
+## Contributing A Patch
+
+1. Submit an issue describing your proposed change to the repo in question.
+1. The repo owner will respond to your issue promptly.
+1. If your proposed change is accepted, and you haven't already done so, sign a
+ Contributor License Agreement (see details above).
+1. Fork the desired repo, develop and test your code changes.
+1. Ensure that your code adheres to the existing style in the sample to which
+ you are contributing. Refer to the
+ [Android Code Style Guide]
+ (https://source.android.com/source/code-style.html) for the
+ recommended coding standards for this organization.
+1. Ensure that your code has an appropriate set of unit tests which all pass.
+1. Submit a pull request.
+
diff --git a/wearable/wear/DataLayer/LICENSE b/wearable/wear/DataLayer/LICENSE
new file mode 100644
index 0000000..1af981f
--- /dev/null
+++ b/wearable/wear/DataLayer/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/wearable/wear/DataLayer/README-wear.txt b/wearable/wear/DataLayer/README-wear.txt
new file mode 100644
index 0000000..17523d7
--- /dev/null
+++ b/wearable/wear/DataLayer/README-wear.txt
@@ -0,0 +1,30 @@
+<#--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+Steps to use Wear template on top of an existing sample:
+- In template-params.xml.ftl:
+ - Add the following template:
+ <template src="Wear"/>
+
+- Refresh your project (./gradlew refresh)
+- Add Wearable-specific code to Wearable directory
+- Add code to be shared among the main application and the wearable to Shared
+ directory
+
+Note that you still need the main application sample code. This is usually
+achieved by adding another template, like "base" for example.
+
+
diff --git a/wearable/wear/DataLayer/Shared/.gitignore b/wearable/wear/DataLayer/Shared/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/DataLayer/Shared/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/DataLayer/Shared/src/main/AndroidManifest.xml b/wearable/wear/DataLayer/Shared/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..b7d03bf
--- /dev/null
+++ b/wearable/wear/DataLayer/Shared/src/main/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.datalayer.common">
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name">
+ </application>
+
+</manifest>
diff --git a/wearable/wear/DataLayer/Shared/src/main/res/values/strings.xml b/wearable/wear/DataLayer/Shared/src/main/res/values/strings.xml
new file mode 100644
index 0000000..0f2bb90
--- /dev/null
+++ b/wearable/wear/DataLayer/Shared/src/main/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <string name="app_name">Shared</string>
+</resources>
diff --git a/wearable/wear/DataLayer/Wearable/.gitignore b/wearable/wear/DataLayer/Wearable/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/DataLayer/Wearable/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/DataLayer/Wearable/src/main/AndroidManifest.xml b/wearable/wear/DataLayer/Wearable/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..ee79242
--- /dev/null
+++ b/wearable/wear/DataLayer/Wearable/src/main/AndroidManifest.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.datalayer" >
+
+ <uses-sdk android:minSdkVersion="20"
+ android:targetSdkVersion="20" />
+
+ <uses-feature android:name="android.hardware.type.watch" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@android:style/Theme.DeviceDefault">
+
+ <meta-data
+ android:name="com.google.android.gms.version"
+ android:value="@integer/google_play_services_version" />
+
+ <service
+ android:name=".DataLayerListenerService" >
+ <intent-filter>
+ <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
+ </intent-filter>
+ </service>
+
+ <activity
+ android:name=".MainActivity"
+ android:screenOrientation="portrait"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ <intent-filter>
+ <action android:name="com.example.android.datalayer.EXAMPLE"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/wearable/wear/DataLayer/Wearable/src/main/java/com/example/android/datalayer/DataLayerListenerService.java b/wearable/wear/DataLayer/Wearable/src/main/java/com/example/android/datalayer/DataLayerListenerService.java
new file mode 100644
index 0000000..9356f39
--- /dev/null
+++ b/wearable/wear/DataLayer/Wearable/src/main/java/com/example/android/datalayer/DataLayerListenerService.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.datalayer;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.util.Log;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.data.FreezableUtils;
+import com.google.android.gms.wearable.DataEvent;
+import com.google.android.gms.wearable.DataEventBuffer;
+import com.google.android.gms.wearable.MessageEvent;
+import com.google.android.gms.wearable.Node;
+import com.google.android.gms.wearable.Wearable;
+import com.google.android.gms.wearable.WearableListenerService;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Listens to DataItems and Messages from the local node.
+ */
+public class DataLayerListenerService extends WearableListenerService {
+
+ private static final String TAG = "DataLayerListenerServic";
+
+ private static final String START_ACTIVITY_PATH = "/start-activity";
+ private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received";
+ public static final String COUNT_PATH = "/count";
+ public static final String IMAGE_PATH = "/image";
+ public static final String IMAGE_KEY = "photo";
+ private static final String COUNT_KEY = "count";
+ private static final int MAX_LOG_TAG_LENGTH = 23;
+ GoogleApiClient mGoogleApiClient;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mGoogleApiClient = new GoogleApiClient.Builder(this)
+ .addApi(Wearable.API)
+ .build();
+ mGoogleApiClient.connect();
+ }
+
+ @Override
+ public void onDataChanged(DataEventBuffer dataEvents) {
+ LOGD(TAG, "onDataChanged: " + 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, "DataLayerListenerService failed to connect to GoogleApiClient.");
+ return;
+ }
+ }
+
+ // Loop through the events and send a message back to the node that created the data item.
+ for (DataEvent event : events) {
+ Uri uri = event.getDataItem().getUri();
+ String path = uri.getPath();
+ if (COUNT_PATH.equals(path)) {
+ // Get the node id of the node that created the data item from the host portion of
+ // the uri.
+ String nodeId = uri.getHost();
+ // Set the data of the message to be the bytes of the Uri.
+ byte[] payload = uri.toString().getBytes();
+
+ // Send the rpc
+ Wearable.MessageApi.sendMessage(mGoogleApiClient, nodeId, DATA_ITEM_RECEIVED_PATH,
+ payload);
+ }
+ }
+ }
+
+ @Override
+ public void onMessageReceived(MessageEvent messageEvent) {
+ LOGD(TAG, "onMessageReceived: " + messageEvent);
+
+ // Check to see if the message is to start an activity
+ if (messageEvent.getPath().equals(START_ACTIVITY_PATH)) {
+ Intent startIntent = new Intent(this, MainActivity.class);
+ startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(startIntent);
+ }
+ }
+
+ @Override
+ public void onPeerConnected(Node peer) {
+ LOGD(TAG, "onPeerConnected: " + peer);
+ }
+
+ @Override
+ public void onPeerDisconnected(Node peer) {
+ LOGD(TAG, "onPeerDisconnected: " + peer);
+ }
+
+ public static void LOGD(final String tag, String message) {
+ if (Log.isLoggable(tag, Log.DEBUG)) {
+ Log.d(tag, message);
+ }
+ }
+}
diff --git a/wearable/wear/DataLayer/Wearable/src/main/java/com/example/android/datalayer/MainActivity.java b/wearable/wear/DataLayer/Wearable/src/main/java/com/example/android/datalayer/MainActivity.java
new file mode 100644
index 0000000..5f763b8
--- /dev/null
+++ b/wearable/wear/DataLayer/Wearable/src/main/java/com/example/android/datalayer/MainActivity.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.datalayer;
+
+import static com.example.android.datalayer.DataLayerListenerService.LOGD;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
+import com.google.android.gms.common.data.FreezableUtils;
+import com.google.android.gms.wearable.Asset;
+import com.google.android.gms.wearable.DataApi;
+import com.google.android.gms.wearable.DataEvent;
+import com.google.android.gms.wearable.DataEventBuffer;
+import com.google.android.gms.wearable.DataMapItem;
+import com.google.android.gms.wearable.MessageApi;
+import com.google.android.gms.wearable.MessageEvent;
+import com.google.android.gms.wearable.Node;
+import com.google.android.gms.wearable.NodeApi;
+import com.google.android.gms.wearable.Wearable;
+
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * Shows events and photo from the Wearable APIs.
+ */
+public class MainActivity extends Activity implements ConnectionCallbacks,
+ OnConnectionFailedListener, DataApi.DataListener, MessageApi.MessageListener,
+ NodeApi.NodeListener {
+
+ private static final String TAG = "MainActivity";
+
+ private GoogleApiClient mGoogleApiClient;
+ private ListView mDataItemList;
+ private TextView mIntroText;
+ private DataItemAdapter mDataItemListAdapter;
+ private View mLayout;
+ private Handler mHandler;
+
+ @Override
+ public void onCreate(Bundle b) {
+ super.onCreate(b);
+ mHandler = new Handler();
+ LOGD(TAG, "onCreate");
+ setContentView(R.layout.main_activity);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ mDataItemList = (ListView) findViewById(R.id.dataItem_list);
+ mIntroText = (TextView) findViewById(R.id.intro);
+ mLayout = findViewById(R.id.layout);
+
+ // Stores data events received by the local broadcaster.
+ mDataItemListAdapter = new DataItemAdapter(this, android.R.layout.simple_list_item_1);
+ mDataItemList.setAdapter(mDataItemListAdapter);
+
+ mGoogleApiClient = new GoogleApiClient.Builder(this)
+ .addApi(Wearable.API)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .build();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mGoogleApiClient.connect();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ Wearable.DataApi.removeListener(mGoogleApiClient, this);
+ Wearable.MessageApi.removeListener(mGoogleApiClient, this);
+ Wearable.NodeApi.removeListener(mGoogleApiClient, this);
+ mGoogleApiClient.disconnect();
+ }
+
+ @Override
+ public void onConnected(Bundle connectionHint) {
+ LOGD(TAG, "onConnected(): Successfully connected to Google API client");
+ Wearable.DataApi.addListener(mGoogleApiClient, this);
+ Wearable.MessageApi.addListener(mGoogleApiClient, this);
+ Wearable.NodeApi.addListener(mGoogleApiClient, this);
+ }
+
+ @Override
+ public void onConnectionSuspended(int cause) {
+ LOGD(TAG, "onConnectionSuspended(): Connection to Google API client was suspended");
+ }
+
+ @Override
+ public void onConnectionFailed(ConnectionResult result) {
+ Log.e(TAG, "onConnectionFailed(): Failed to connect, with result: " + result);
+ }
+
+ private void generateEvent(final String title, final String text) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mIntroText.setVisibility(View.INVISIBLE);
+ mDataItemListAdapter.add(new Event(title, text));
+ }
+ });
+ }
+
+ @Override
+ public void onDataChanged(DataEventBuffer dataEvents) {
+ LOGD(TAG, "onDataChanged(): " + dataEvents);
+
+ final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
+ dataEvents.close();
+ for (DataEvent event : events) {
+ if (event.getType() == DataEvent.TYPE_CHANGED) {
+ String path = event.getDataItem().getUri().getPath();
+ if (DataLayerListenerService.IMAGE_PATH.equals(path)) {
+ DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
+ Asset photo = dataMapItem.getDataMap()
+ .getAsset(DataLayerListenerService.IMAGE_KEY);
+ final Bitmap bitmap = loadBitmapFromAsset(mGoogleApiClient, photo);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ Log.d(TAG, "Setting background image..");
+ mLayout.setBackground(new BitmapDrawable(getResources(), bitmap));
+ }
+ });
+
+ } else if (DataLayerListenerService.COUNT_PATH.equals(path)) {
+ LOGD(TAG, "Data Changed for COUNT_PATH");
+ generateEvent("DataItem Changed", event.getDataItem().toString());
+ } else {
+ LOGD(TAG, "Unrecognized path: " + path);
+ }
+
+ } else if (event.getType() == DataEvent.TYPE_DELETED) {
+ generateEvent("DataItem Deleted", event.getDataItem().toString());
+ } else {
+ generateEvent("Unknown data event type", "Type = " + event.getType());
+ }
+ }
+ }
+
+ /**
+ * Extracts {@link android.graphics.Bitmap} data from the
+ * {@link com.google.android.gms.wearable.Asset}
+ */
+ private Bitmap loadBitmapFromAsset(GoogleApiClient apiClient, Asset asset) {
+ if (asset == null) {
+ throw new IllegalArgumentException("Asset must be non-null");
+ }
+
+ InputStream assetInputStream = Wearable.DataApi.getFdForAsset(
+ apiClient, asset).await().getInputStream();
+
+ if (assetInputStream == null) {
+ Log.w(TAG, "Requested an unknown Asset.");
+ return null;
+ }
+ return BitmapFactory.decodeStream(assetInputStream);
+ }
+
+ @Override
+ public void onMessageReceived(MessageEvent event) {
+ LOGD(TAG, "onMessageReceived: " + event);
+ generateEvent("Message", event.toString());
+ }
+
+ @Override
+ public void onPeerConnected(Node node) {
+ generateEvent("Node Connected", node.getId());
+ }
+
+ @Override
+ public void onPeerDisconnected(Node node) {
+ generateEvent("Node Disconnected", node.getId());
+ }
+
+ private static class DataItemAdapter extends ArrayAdapter<Event> {
+
+ private final Context mContext;
+
+ public DataItemAdapter(Context context, int unusedResource) {
+ super(context, unusedResource);
+ mContext = context;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+ if (convertView == null) {
+ holder = new ViewHolder();
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ convertView = inflater.inflate(android.R.layout.two_line_list_item, null);
+ convertView.setTag(holder);
+ holder.text1 = (TextView) convertView.findViewById(android.R.id.text1);
+ holder.text2 = (TextView) convertView.findViewById(android.R.id.text2);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+ Event event = getItem(position);
+ holder.text1.setText(event.title);
+ holder.text2.setText(event.text);
+ return convertView;
+ }
+
+ private class ViewHolder {
+
+ TextView text1;
+ TextView text2;
+ }
+ }
+
+ private class Event {
+
+ String title;
+ String text;
+
+ public Event(String title, String text) {
+ this.title = title;
+ this.text = text;
+ }
+ }
+}
diff --git a/wearable/wear/DataLayer/Wearable/src/main/res/drawable-hdpi/ic_launcher.png b/wearable/wear/DataLayer/Wearable/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..589f229
--- /dev/null
+++ b/wearable/wear/DataLayer/Wearable/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DataLayer/Wearable/src/main/res/drawable-mdpi/ic_launcher.png b/wearable/wear/DataLayer/Wearable/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..77dd571
--- /dev/null
+++ b/wearable/wear/DataLayer/Wearable/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DataLayer/Wearable/src/main/res/drawable-xhdpi/ic_launcher.png b/wearable/wear/DataLayer/Wearable/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..fe34ebe
--- /dev/null
+++ b/wearable/wear/DataLayer/Wearable/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DataLayer/Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png b/wearable/wear/DataLayer/Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..ab80bcd
--- /dev/null
+++ b/wearable/wear/DataLayer/Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DataLayer/Wearable/src/main/res/layout/main_activity.xml b/wearable/wear/DataLayer/Wearable/src/main/res/layout/main_activity.xml
new file mode 100644
index 0000000..f98e667
--- /dev/null
+++ b/wearable/wear/DataLayer/Wearable/src/main/res/layout/main_activity.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <ListView
+ android:id="@+id/dataItem_list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:transcriptMode="alwaysScroll"/>
+
+ <TextView
+ android:id="@+id/intro"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:textSize="20sp"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ android:gravity="center"
+ android:fontFamily="sans-serif-condensed-light"
+ android:text="@string/intro" />
+</RelativeLayout>
diff --git a/wearable/wear/DataLayer/Wearable/src/main/res/values/strings.xml b/wearable/wear/DataLayer/Wearable/src/main/res/values/strings.xml
new file mode 100644
index 0000000..331e736
--- /dev/null
+++ b/wearable/wear/DataLayer/Wearable/src/main/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name">Data Layer Sample Wearable App</string>
+ <string name="intro">Waiting for data to arrive\u2026</string>
+</resources>
diff --git a/wearable/wear/DataLayer/build.gradle b/wearable/wear/DataLayer/build.gradle
new file mode 100644
index 0000000..be1fa82
--- /dev/null
+++ b/wearable/wear/DataLayer/build.gradle
@@ -0,0 +1,14 @@
+
+
+
+
+// BEGIN_EXCLUDE
+import com.example.android.samples.build.SampleGenPlugin
+apply plugin: SampleGenPlugin
+
+samplegen {
+ pathToBuild "../../../../../build"
+ pathToSamplesCommon "../../../common"
+}
+apply from: "../../../../../build/build.gradle"
+// END_EXCLUDE
diff --git a/wearable/wear/DataLayer/buildSrc/build.gradle b/wearable/wear/DataLayer/buildSrc/build.gradle
new file mode 100644
index 0000000..e344a8c
--- /dev/null
+++ b/wearable/wear/DataLayer/buildSrc/build.gradle
@@ -0,0 +1,18 @@
+
+
+
+repositories {
+ mavenCentral()
+}
+dependencies {
+ compile 'org.freemarker:freemarker:2.3.20'
+}
+
+sourceSets {
+ main {
+ groovy {
+ srcDir new File(rootDir, "../../../../../../build/buildSrc/src/main/groovy")
+ }
+ }
+}
+
diff --git a/wearable/wear/DataLayer/gradle/wrapper/gradle-wrapper.jar b/wearable/wear/DataLayer/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/wearable/wear/DataLayer/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/wearable/wear/DataLayer/gradle/wrapper/gradle-wrapper.properties b/wearable/wear/DataLayer/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..d7f03cf
--- /dev/null
+++ b/wearable/wear/DataLayer/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-bin.zip
diff --git a/wearable/wear/DataLayer/gradlew b/wearable/wear/DataLayer/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/wearable/wear/DataLayer/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/wearable/wear/DataLayer/gradlew.bat b/wearable/wear/DataLayer/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/wearable/wear/DataLayer/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/wearable/wear/DataLayer/settings.gradle b/wearable/wear/DataLayer/settings.gradle
new file mode 100644
index 0000000..8522c57
--- /dev/null
+++ b/wearable/wear/DataLayer/settings.gradle
@@ -0,0 +1 @@
+include ':Application', ':Wearable', ':Shared'
diff --git a/wearable/wear/DataLayer/template-params.xml b/wearable/wear/DataLayer/template-params.xml
new file mode 100644
index 0000000..c346012
--- /dev/null
+++ b/wearable/wear/DataLayer/template-params.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<sample>
+ <name>DataLayer</name>
+ <group>Connectivity</group>
+ <package>com.example.android.datalayer</package>
+
+
+
+ <!-- change minSdk if needed-->
+ <minSdk>20</minSdk>
+
+
+ <strings>
+ <intro>
+ <![CDATA[
+ You can cause the wearable to start an activity by pressing a button in the
+ companion app UI. You can also take a picture on the companion device, which will be transmitted as
+ an Asset for display on the wearable.
+ ]]>
+ </intro>
+ </strings>
+
+ <template src="base"/>
+ <template src="Wear"/>
+ <common src="logger"/>
+ <common src="activities"/>
+
+</sample>
diff --git a/wearable/wear/DelayedConfirmation/Application/.gitignore b/wearable/wear/DelayedConfirmation/Application/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Application/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/DelayedConfirmation/Application/proguard-project.txt b/wearable/wear/DelayedConfirmation/Application/proguard-project.txt
new file mode 100644
index 0000000..0d8f171
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Application/proguard-project.txt
@@ -0,0 +1,20 @@
+ To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/wearable/wear/DelayedConfirmation/Application/src/main/AndroidManifest.xml b/wearable/wear/DelayedConfirmation/Application/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..115ebec
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Application/src/main/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.delayedconfirmation" >
+
+ <uses-sdk android:minSdkVersion="19"
+ android:targetSdkVersion="19" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name">
+
+ <meta-data
+ android:name="com.google.android.gms.version"
+ android:value="@integer/google_play_services_version" />
+
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:launchMode="singleTask" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/wearable/wear/DelayedConfirmation/Application/src/main/java/com/example/android/delayedconfirmation/MainActivity.java b/wearable/wear/DelayedConfirmation/Application/src/main/java/com/example/android/delayedconfirmation/MainActivity.java
new file mode 100644
index 0000000..6fe681f
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Application/src/main/java/com/example/android/delayedconfirmation/MainActivity.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.delayedconfirmation;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Toast;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.ResultCallback;
+import com.google.android.gms.wearable.MessageApi;
+import com.google.android.gms.wearable.MessageEvent;
+import com.google.android.gms.wearable.Node;
+import com.google.android.gms.wearable.NodeApi;
+import com.google.android.gms.wearable.Wearable;
+
+/**
+ * Has a single button, used to start the Wearable MainActivity.
+ */
+public class MainActivity extends Activity implements MessageApi.MessageListener,
+ GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
+
+ private static final String TAG = "DelayedConfirmation";
+ private static final String START_ACTIVITY_PATH = "/start-activity";
+ private static final String TIMER_SELECTED_PATH = "/timer_selected";
+ private static final String TIMER_FINISHED_PATH = "/timer_finished";
+ private GoogleApiClient mGoogleApiClient;
+
+ @Override
+ public void onCreate(Bundle b) {
+ super.onCreate(b);
+ setContentView(R.layout.main_activity);
+ mGoogleApiClient = new GoogleApiClient.Builder(this)
+ .addApi(Wearable.API)
+ .addConnectionCallbacks(this)
+ .addOnConnectionFailedListener(this)
+ .build();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if (!mGoogleApiClient.isConnected()) {
+ mGoogleApiClient.connect();
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (mGoogleApiClient.isConnected()) {
+ mGoogleApiClient.disconnect();
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ public void onConnected(Bundle bundle) {
+ Wearable.MessageApi.addListener(mGoogleApiClient, this);
+ }
+
+ @Override
+ public void onConnectionSuspended(int i) {
+ Wearable.MessageApi.removeListener(mGoogleApiClient, this);
+ }
+
+ @Override
+ public void onMessageReceived(final MessageEvent messageEvent) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (messageEvent.getPath().equals(TIMER_SELECTED_PATH)) {
+ Toast.makeText(getApplicationContext(), R.string.toast_timer_selected,
+ Toast.LENGTH_SHORT).show();
+ } else if (messageEvent.getPath().equals(TIMER_FINISHED_PATH)) {
+ Toast.makeText(getApplicationContext(), R.string.toast_timer_finished,
+ Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+
+ }
+
+ @Override
+ public void onConnectionFailed(ConnectionResult connectionResult) {
+ Log.e(TAG, "Failed to connect to Google Api Client with error code "
+ + connectionResult.getErrorCode());
+ }
+
+ /**
+ * Sends a message to Wearable MainActivity when button is pressed.
+ */
+ public void onStartWearableActivityClick(View view) {
+ Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(
+ new ResultCallback<NodeApi.GetConnectedNodesResult>() {
+ @Override
+ public void onResult(NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
+ for (final Node node : getConnectedNodesResult.getNodes()) {
+ Wearable.MessageApi.sendMessage(
+ mGoogleApiClient, node.getId(), START_ACTIVITY_PATH, new byte[0])
+ .setResultCallback(getSendMessageResultCallback());
+ }
+ }
+ });
+ }
+
+ private ResultCallback<MessageApi.SendMessageResult> getSendMessageResultCallback() {
+ return new ResultCallback<MessageApi.SendMessageResult>() {
+ @Override
+ public void onResult(MessageApi.SendMessageResult sendMessageResult) {
+ if (!sendMessageResult.getStatus().isSuccess()) {
+ Log.e(TAG, "Failed to connect to Google Api Client with status "
+ + sendMessageResult.getStatus());
+ }
+ }
+ };
+ }
+}
diff --git a/wearable/wear/DelayedConfirmation/Application/src/main/res/drawable-hdpi/ic_launcher.png b/wearable/wear/DelayedConfirmation/Application/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..589f229
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DelayedConfirmation/Application/src/main/res/drawable-mdpi/ic_launcher.png b/wearable/wear/DelayedConfirmation/Application/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..77dd571
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DelayedConfirmation/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/wearable/wear/DelayedConfirmation/Application/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..fe34ebe
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DelayedConfirmation/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/wearable/wear/DelayedConfirmation/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..ab80bcd
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DelayedConfirmation/Application/src/main/res/layout/main_activity.xml b/wearable/wear/DelayedConfirmation/Application/src/main/res/layout/main_activity.xml
new file mode 100644
index 0000000..cbc1874
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Application/src/main/res/layout/main_activity.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+ <TextView
+ android:id="@+id/text_start_wearable_activity"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="20sp"
+ android:text="@string/start_wearable_activity" />
+ <Button
+ android:id="@+id/start_wearable_activity"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minWidth="150dp"
+ android:onClick="onStartWearableActivityClick"
+ android:text="@string/start"/>
+</LinearLayout>
diff --git a/wearable/wear/DelayedConfirmation/Application/src/main/res/values/strings.xml b/wearable/wear/DelayedConfirmation/Application/src/main/res/values/strings.xml
new file mode 100644
index 0000000..1708705
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Application/src/main/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="start_wearable_activity">Start Wearable Activity</string>
+ <string name="start">Start</string>
+
+ <string name="toast_timer_selected">Timer Selected</string>
+ <string name="toast_timer_finished">Timer Finished</string>
+</resources>
diff --git a/wearable/wear/DelayedConfirmation/CONTRIB.md b/wearable/wear/DelayedConfirmation/CONTRIB.md
new file mode 100644
index 0000000..14a4fcf
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/CONTRIB.md
@@ -0,0 +1,35 @@
+# How to become a contributor and submit your own code
+
+## Contributor License Agreements
+
+We'd love to accept your sample apps and patches! Before we can take them, we
+have to jump a couple of legal hurdles.
+
+Please fill out either the individual or corporate Contributor License Agreement (CLA).
+
+ * If you are an individual writing original source code and you're sure you
+ own the intellectual property, then you'll need to sign an [individual CLA]
+ (https://developers.google.com/open-source/cla/individual).
+ * If you work for a company that wants to allow you to contribute your work,
+ then you'll need to sign a [corporate CLA]
+ (https://developers.google.com/open-source/cla/corporate).
+
+Follow either of the two links above to access the appropriate CLA and
+instructions for how to sign and return it. Once we receive it, we'll be able to
+accept your pull requests.
+
+## Contributing A Patch
+
+1. Submit an issue describing your proposed change to the repo in question.
+1. The repo owner will respond to your issue promptly.
+1. If your proposed change is accepted, and you haven't already done so, sign a
+ Contributor License Agreement (see details above).
+1. Fork the desired repo, develop and test your code changes.
+1. Ensure that your code adheres to the existing style in the sample to which
+ you are contributing. Refer to the
+ [Android Code Style Guide]
+ (https://source.android.com/source/code-style.html) for the
+ recommended coding standards for this organization.
+1. Ensure that your code has an appropriate set of unit tests which all pass.
+1. Submit a pull request.
+
diff --git a/wearable/wear/DelayedConfirmation/LICENSE b/wearable/wear/DelayedConfirmation/LICENSE
new file mode 100644
index 0000000..1af981f
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/wearable/wear/DelayedConfirmation/README-wear.txt b/wearable/wear/DelayedConfirmation/README-wear.txt
new file mode 100644
index 0000000..17523d7
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/README-wear.txt
@@ -0,0 +1,30 @@
+<#--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+Steps to use Wear template on top of an existing sample:
+- In template-params.xml.ftl:
+ - Add the following template:
+ <template src="Wear"/>
+
+- Refresh your project (./gradlew refresh)
+- Add Wearable-specific code to Wearable directory
+- Add code to be shared among the main application and the wearable to Shared
+ directory
+
+Note that you still need the main application sample code. This is usually
+achieved by adding another template, like "base" for example.
+
+
diff --git a/wearable/wear/DelayedConfirmation/Shared/.gitignore b/wearable/wear/DelayedConfirmation/Shared/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Shared/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/DelayedConfirmation/Shared/src/main/AndroidManifest.xml b/wearable/wear/DelayedConfirmation/Shared/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..2c9b669
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Shared/src/main/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.delayedconfirmation.common">
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name">
+ </application>
+
+</manifest>
diff --git a/wearable/wear/DelayedConfirmation/Shared/src/main/res/values/strings.xml b/wearable/wear/DelayedConfirmation/Shared/src/main/res/values/strings.xml
new file mode 100644
index 0000000..0f2bb90
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Shared/src/main/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <string name="app_name">Shared</string>
+</resources>
diff --git a/wearable/wear/DelayedConfirmation/Wearable/.gitignore b/wearable/wear/DelayedConfirmation/Wearable/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Wearable/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/DelayedConfirmation/Wearable/src/main/AndroidManifest.xml b/wearable/wear/DelayedConfirmation/Wearable/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..a220008
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Wearable/src/main/AndroidManifest.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.delayedconfirmation" >
+
+ <uses-sdk android:minSdkVersion="20"
+ android:targetSdkVersion="20" />
+
+ <uses-feature android:name="android.hardware.type.watch" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@android:style/Theme.DeviceDefault">
+
+ <meta-data
+ android:name="com.google.android.gms.version"
+ android:value="@integer/google_play_services_version" />
+
+ <service
+ android:name=".WearableMessageListenerService" >
+ <intent-filter>
+ <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
+ </intent-filter>
+ </service>
+
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name">
+ </activity>
+ </application>
+</manifest>
diff --git a/wearable/wear/DelayedConfirmation/Wearable/src/main/java/com/example/android/delayedconfirmation/MainActivity.java b/wearable/wear/DelayedConfirmation/Wearable/src/main/java/com/example/android/delayedconfirmation/MainActivity.java
new file mode 100644
index 0000000..2e169c7
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Wearable/src/main/java/com/example/android/delayedconfirmation/MainActivity.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.delayedconfirmation;
+
+import android.app.Activity;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.os.Bundle;
+import android.support.wearable.view.DelayedConfirmationView;
+import android.util.Log;
+import android.view.View;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.ResultCallback;
+import com.google.android.gms.wearable.MessageApi;
+import com.google.android.gms.wearable.Node;
+import com.google.android.gms.wearable.NodeApi;
+import com.google.android.gms.wearable.Wearable;
+
+
+public class MainActivity extends Activity implements
+ DelayedConfirmationView.DelayedConfirmationListener,
+ GoogleApiClient.OnConnectionFailedListener {
+
+ private static final String TAG = "DelayedConfirmation";
+ private static final int NUM_SECONDS = 5;
+
+ private static final String TIMER_SELECTED_PATH = "/timer_selected";
+ private static final String TIMER_FINISHED_PATH = "/timer_finished";
+
+ private DelayedConfirmationView delayedConfirmationView;
+ private GoogleApiClient mGoogleApiClient;
+
+ @Override
+ public void onCreate(Bundle b) {
+ super.onCreate(b);
+ setContentView(R.layout.main_activity);
+ delayedConfirmationView = (DelayedConfirmationView) findViewById(R.id.delayed_confirmation);
+ delayedConfirmationView.setTotalTimeMs(NUM_SECONDS * 1000);
+ mGoogleApiClient = new GoogleApiClient.Builder(this)
+ .addApi(Wearable.API)
+ .addOnConnectionFailedListener(this)
+ .build();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if (!mGoogleApiClient.isConnected()) {
+ mGoogleApiClient.connect();
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (mGoogleApiClient.isConnected()) {
+ mGoogleApiClient.disconnect();
+ }
+ super.onDestroy();
+ }
+
+ /**
+ * Starts the DelayedConfirmationView when user presses "Start Timer" button.
+ */
+ public void onStartTimer(View view) {
+ delayedConfirmationView.start();
+ delayedConfirmationView.setListener(this);
+ }
+
+ @Override
+ public void onTimerSelected(View v) {
+ v.setPressed(true);
+ Notification notification = new Notification.Builder(this)
+ .setSmallIcon(R.drawable.ic_launcher)
+ .setContentTitle(getString(R.string.notification_title))
+ .setContentText(getString(R.string.notification_timer_selected))
+ .build();
+ ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).notify(0, notification);
+ sendMessageToCompanion(TIMER_SELECTED_PATH);
+ // Prevent onTimerFinished from being heard.
+ ((DelayedConfirmationView) v).setListener(null);
+ finish();
+ }
+
+ @Override
+ public void onTimerFinished(View v) {
+ Notification notification = new Notification.Builder(this)
+ .setSmallIcon(R.drawable.ic_launcher)
+ .setContentTitle(getString(R.string.notification_title))
+ .setContentText(getString(R.string.notification_timer_finished))
+ .build();
+ ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).notify(0, notification);
+ sendMessageToCompanion(TIMER_FINISHED_PATH);
+ finish();
+ }
+
+ @Override
+ public void onConnectionFailed(ConnectionResult connectionResult) {
+ Log.e(TAG, "Failed to connect to Google Api Client");
+ }
+
+ private void sendMessageToCompanion(final String path) {
+ Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(
+ new ResultCallback<NodeApi.GetConnectedNodesResult>() {
+ @Override
+ public void onResult(NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
+ for (final Node node : getConnectedNodesResult.getNodes()) {
+ Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), path,
+ new byte[0]).setResultCallback(getSendMessageResultCallback());
+ }
+ }
+ }
+ );
+
+ }
+
+ private ResultCallback<MessageApi.SendMessageResult> getSendMessageResultCallback() {
+ return new ResultCallback<MessageApi.SendMessageResult>() {
+ @Override
+ public void onResult(MessageApi.SendMessageResult sendMessageResult) {
+ if (!sendMessageResult.getStatus().isSuccess()) {
+ Log.e(TAG, "Failed to connect to Google Api Client with status "
+ + sendMessageResult.getStatus());
+ }
+ }
+ };
+ }
+}
diff --git a/wearable/wear/DelayedConfirmation/Wearable/src/main/java/com/example/android/delayedconfirmation/WearableMessageListenerService.java b/wearable/wear/DelayedConfirmation/Wearable/src/main/java/com/example/android/delayedconfirmation/WearableMessageListenerService.java
new file mode 100644
index 0000000..0032fda
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Wearable/src/main/java/com/example/android/delayedconfirmation/WearableMessageListenerService.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.delayedconfirmation;
+
+import android.content.Intent;
+
+import com.google.android.gms.wearable.MessageEvent;
+import com.google.android.gms.wearable.WearableListenerService;
+
+/**
+ * Listens for a message telling it to start the Wearable MainActivity.
+ */
+public class WearableMessageListenerService extends WearableListenerService {
+ private static final String START_ACTIVITY_PATH = "/start-activity";
+
+ @Override
+ public void onMessageReceived(MessageEvent event) {
+ if (event.getPath().equals(START_ACTIVITY_PATH)) {
+ Intent startIntent = new Intent(this, MainActivity.class);
+ startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(startIntent);
+ }
+ }
+}
diff --git a/wearable/wear/DelayedConfirmation/Wearable/src/main/res/drawable-hdpi/ic_launcher.png b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..589f229
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DelayedConfirmation/Wearable/src/main/res/drawable-mdpi/ic_launcher.png b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..77dd571
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DelayedConfirmation/Wearable/src/main/res/drawable-xhdpi/ic_launcher.png b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..fe34ebe
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DelayedConfirmation/Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..ab80bcd
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/DelayedConfirmation/Wearable/src/main/res/layout/main_activity.xml b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/layout/main_activity.xml
new file mode 100644
index 0000000..1b9bcb3
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/layout/main_activity.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<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_height="match_parent"
+ android:layout_width="match_parent">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:background="@color/grey"
+ app:layout_box="top">
+
+ <Button
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:onClick="onStartTimer"
+ android:text="@string/start_timer"/>
+
+ <android.support.wearable.view.DelayedConfirmationView
+ android:id="@+id/delayed_confirmation"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:src="@drawable/ic_launcher"
+ app:circle_color="@color/blue"
+ app:circle_radius="@dimen/circle_radius"
+ app:circle_radius_pressed="@dimen/circle_radius_pressed"
+ app:circle_padding="@dimen/circle_padding"
+ app:circle_border_width="@dimen/circle_border_normal_width"
+ app:circle_border_color="@color/white"/>
+
+ </LinearLayout>
+</android.support.wearable.view.BoxInsetLayout>
diff --git a/wearable/wear/DelayedConfirmation/Wearable/src/main/res/values/dimens.xml b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..677a0f1
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/values/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <dimen name="circle_border_normal_width">10dp</dimen>
+ <dimen name="circle_padding">5dp</dimen>
+ <dimen name="circle_radius">60dp</dimen>
+ <dimen name="circle_radius_pressed">55dp</dimen>
+</resources>
diff --git a/wearable/wear/DelayedConfirmation/Wearable/src/main/res/values/strings.xml b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/values/strings.xml
new file mode 100644
index 0000000..46f5326
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/Wearable/src/main/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+
+ <string name="app_name">Delayed Confirmation</string>
+ <string name="start_timer">Start Timer (5 seconds)</string>
+
+ <string name="notification_title">DelayedConfirmation</string>
+ <string name="notification_timer_selected">Timer Selected</string>
+ <string name="notification_timer_finished">Timer Finished</string>
+</resources>
diff --git a/wearable/wear/DelayedConfirmation/build.gradle b/wearable/wear/DelayedConfirmation/build.gradle
new file mode 100644
index 0000000..be1fa82
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/build.gradle
@@ -0,0 +1,14 @@
+
+
+
+
+// BEGIN_EXCLUDE
+import com.example.android.samples.build.SampleGenPlugin
+apply plugin: SampleGenPlugin
+
+samplegen {
+ pathToBuild "../../../../../build"
+ pathToSamplesCommon "../../../common"
+}
+apply from: "../../../../../build/build.gradle"
+// END_EXCLUDE
diff --git a/wearable/wear/DelayedConfirmation/buildSrc/build.gradle b/wearable/wear/DelayedConfirmation/buildSrc/build.gradle
new file mode 100644
index 0000000..e344a8c
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/buildSrc/build.gradle
@@ -0,0 +1,18 @@
+
+
+
+repositories {
+ mavenCentral()
+}
+dependencies {
+ compile 'org.freemarker:freemarker:2.3.20'
+}
+
+sourceSets {
+ main {
+ groovy {
+ srcDir new File(rootDir, "../../../../../../build/buildSrc/src/main/groovy")
+ }
+ }
+}
+
diff --git a/wearable/wear/DelayedConfirmation/gradle/wrapper/gradle-wrapper.jar b/wearable/wear/DelayedConfirmation/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/wearable/wear/DelayedConfirmation/gradle/wrapper/gradle-wrapper.properties b/wearable/wear/DelayedConfirmation/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..d7f03cf
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-bin.zip
diff --git a/wearable/wear/DelayedConfirmation/gradlew b/wearable/wear/DelayedConfirmation/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/wearable/wear/DelayedConfirmation/gradlew.bat b/wearable/wear/DelayedConfirmation/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/wearable/wear/DelayedConfirmation/settings.gradle b/wearable/wear/DelayedConfirmation/settings.gradle
new file mode 100644
index 0000000..8522c57
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/settings.gradle
@@ -0,0 +1 @@
+include ':Application', ':Wearable', ':Shared'
diff --git a/wearable/wear/DelayedConfirmation/template-params.xml b/wearable/wear/DelayedConfirmation/template-params.xml
new file mode 100644
index 0000000..a0432ac
--- /dev/null
+++ b/wearable/wear/DelayedConfirmation/template-params.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<sample>
+ <name>DelayedConfirmation</name>
+ <group>Connectivity</group>
+ <package>com.example.android.delayedconfirmation</package>
+
+
+
+ <!-- change minSdk if needed-->
+ <minSdk>20</minSdk>
+
+
+ <strings>
+ <intro>
+ <![CDATA[
+ Demonstrates how to create a DelayedConfirmationView in your wearable app. In this
+ sample, pressing a button on the phone app sends a message to the wearable to start a simple
+ activity. This activity displays a DelayedConfirmationView that starts when the user presses "Start
+ Timer." Then, callbacks are implemented on both the wearable and phone to show when the timer is
+ selected or finishes. The activity on the wearable uses BoxInsetLayout to automatically apply
+ appropriate margins based on whether the display is square or circular.
+ ]]>
+ </intro>
+ </strings>
+
+ <template src="base"/>
+ <template src="Wear"/>
+ <common src="logger"/>
+ <common src="activities"/>
+
+</sample>
diff --git a/wearable/wear/ElizaChat/Application/.gitignore b/wearable/wear/ElizaChat/Application/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/ElizaChat/Application/proguard-project.txt b/wearable/wear/ElizaChat/Application/proguard-project.txt
new file mode 100644
index 0000000..0d8f171
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/proguard-project.txt
@@ -0,0 +1,20 @@
+ To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/wearable/wear/ElizaChat/Application/src/main/AndroidManifest.xml b/wearable/wear/ElizaChat/Application/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..e653fa9
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.elizachat" >
+
+ <uses-sdk android:minSdkVersion="19"
+ android:targetSdkVersion="19" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@mipmap/ic_app_eliza"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <service
+ android:name=".ResponderService">
+ <intent-filter>
+ <action android:name="com.example.android.elizachat.REPLY" />
+ <action android:name="com.example.android.elizachat.CONVERSATION" />
+ </intent-filter>
+ </service>
+ </application>
+
+</manifest>
diff --git a/wearable/wear/ElizaChat/Application/src/main/java/com/example/android/elizachat/ElizaResponder.java b/wearable/wear/ElizaChat/Application/src/main/java/com/example/android/elizachat/ElizaResponder.java
new file mode 100644
index 0000000..e87f6de
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/java/com/example/android/elizachat/ElizaResponder.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.elizachat;
+
+import android.text.TextUtils;
+
+/**
+ * A basic chat bot based on ELIZA, one of the earliest programs to employ primitive natural
+ * language processing. Like ELIZA, this bot can simulate a Rogerian psychotherapist using a
+ * collection of vague and generic responses.
+ */
+public class ElizaResponder {
+
+ private static final String[] CONVERSATION_KEYWORDS = {
+ "CAN YOU", "CAN I", "YOU ARE", "YOURE", "I DONT", "I FEEL", "WHY DONT YOU", "WHY CANT I",
+ "ARE YOU", "I CANT", "I AM", " IM ", "YOU", "I WANT", "WHAT", "HOW", "WHO", "WHERE",
+ "WHEN", "WHY", "NAME", "CAUSE", "SORRY", "DREAM", "HELLO", "HI", "MAYBE", "NO", "YOUR",
+ "ALWAYS", "THINK", "ALIKE", "YES", "FRIEND", "COMPUTER", "NOKEYFOUND" };
+
+ private static String[] WORDS_TO_REPLACE = {"ARE","AM","WERE","WAS","YOU","I","YOUR","MY",
+ "IVE","YOUVE","IM","YOURE", "YOU", "ME"};
+
+ private static String[] QUESTIONS = {
+ "DON'T YOU BELIEVE THAT I CAN.", "PERHAPS YOU WOULD LIKE TO BE ABLE TO.",
+ "YOU WANT ME TO BE ABLE TO*", "PERHAPS YOU DON'T WANT TO*",
+ "DO YOU WANT TO BE ABLE TO*", "WHAT MAKES YOU THINK I AM*",
+ "DOES IT PLEASE YOU TO BELIEVE I AM*", "PERHAPS YOU WOULD LIKE TO BE*",
+ "DO YOU SOMETIMES WISH YOU WERE*", "DON'T YOU REALLY*", "WHY DON'T YOU*",
+ "DO YOU WISH TO BE ABLE TO*", "DOES THAT TROUBLE YOU?",
+ "TELL ME MORE ABOUT SUCH FEELINGS*", "DO YOU OFTEN FEEL*",
+ "DO YOU ENJOY FEELING*", "DO YOU REALLY BELIEVE I DON'T*",
+ "PERHAPS IN TIME I WILL*", "DO YOU WANT ME TO*",
+ "DO YOU THINK YOU SHOULD BE ABLE TO*", "WHY CAN'T YOU*",
+ "WHAT MAKES YOU WONDER WHETHER OR NOT I AM*",
+ "WOULD YOU PREFER IF I WERE NOT*", "PERHAPS IN YOUR FANTASIES I AM*",
+ "HOW DO YOU KNOW YOU CAN'T*", "HAVE YOU TRIED?", "PERHAPS YOU CAN NOW*",
+ "DID YOU COME TO ME BECAUSE YOU ARE*", "HOW LONG HAVE YOU BEEN*",
+ "DO YOU BELIEVE IT IS NORMAL TO BE*", "DO YOU ENJOY BEING*",
+ "I AM MORE INTERESTED IN TALKING ABOUT YOU.", "OH, I*",
+ "ARE YOU REALLY SO INTERESTED IN SOMEONE LIKE ME?",
+ "WHAT WOULD IT MEAN TO YOU IF YOU GOT*", "WHY DO YOU WANT*",
+ "SUPPOSE YOU SOON GOT*", "WHAT IF YOU NEVER GOT*", "I SOMETIMES ALSO WANT*",
+ "WHY DO YOU ASK?", "DOES THAT QUESTION INTEREST YOU?",
+ "WHAT ANSWER WOULD PLEASE YOU THE MOST?", "WHAT DO YOU THINK?",
+ "ARE SUCH QUESTIONS ON YOUR MIND OFTEN?",
+ "WHAT IS IT THAT YOU REALLY WANT TO KNOW?", "HAVE YOU ASKED ANYONE ELSE?",
+ "HAVE YOU ASKED SUCH QUESTIONS BEFORE?",
+ "WHAT ELSE COMES TO MIND WHEN YOU ASK THAT?", "WE CAN KEEP THIS ANONYMOUS.",
+ "NO NEED TO SPECIFY ANY NAMES-- PLEASE GO ON.", "IS THAT THE REAL REASON?",
+ "DON'T ANY OTHER REASONS COME TO MIND?",
+ "DOES THAT REASON EXPLAIN ANYTHING ELSE?", "WHAT OTHER REASONS MIGHT THERE BE?",
+ "PLEASE DON'T APOLOGIZE.", "APOLOGIES ARE NOT NECESSARY.",
+ "WHAT FEELINGS DO YOU HAVE WHEN YOU APOLOGIZE?", "NO NEED TO BE DEFENSIVE!",
+ "WHAT DOES THAT DREAM SUGGEST TO YOU?", "DO YOU DREAM OFTEN?",
+ "WHAT PERSONS APPEAR IN YOUR DREAMS?", "DO YOU HAVE PLEASANT DREAMS?",
+ "HOW DO YOU DO ... PLEASE STATE YOUR PROBLEM.", "YOU DON'T SEEM QUITE CERTAIN.",
+ "WHY THE UNCERTAIN TONE?", "LET'S TRY TO KEEP THIS POSITIVE.", "YOU AREN'T SURE?",
+ "DON'T YOU KNOW?", "IS THAT A DEFINITE NO OR MIGHT YOU CHANGE YOUR MIND?",
+ "I AM SENSING SOME NEGATIVITY.", "WHY NOT?", "ARE YOU SURE?", "WHY NO?",
+ "WHY ARE YOU CONCERNED ABOUT MY*", "WHAT ABOUT YOUR OWN*",
+ "CAN'T YOU THINK OF A SPECIFIC EXAMPLE?", "WHEN?", "WHAT ARE YOU THINKING OF?",
+ "REALLY. ALWAYS?", "DO YOU REALLY THINK SO?", "BUT YOU ARE NOT SURE YOU.",
+ "BELIEVE IN YOURSELF.", "IN WHAT WAY?", "WHAT RESEMBLANCE DO YOU SEE?",
+ "WHAT DOES THE SIMILARITY SUGGEST TO YOU?",
+ "WHAT OTHER CONNECTIONS DO YOU SEE?", "COULD THERE REALLY BE SOME CONNECTION?",
+ "HOW?", "YOU SEEM QUITE POSITIVE.", "ARE YOU SURE?", "I SEE.", "I UNDERSTAND.",
+ "TELL ME ABOUT YOUR FRIENDS.", "ARE YOU WORRIED ABOUT YOUR FRIENDS?",
+ "DO YOUR FRIENDS EVER GIVE YOU A HARD TIME?", "WHAT DO YOU LIKE ABOUT YOUR FRIENDS?",
+ "DO YOU LOVE YOUR FRIENDS?", "PERHAPS YOUR LOVE FOR FRIENDS WORRIES YOU.",
+ "DO COMPUTERS EXCITE YOU?", "ARE YOU TALKING ABOUT ME IN PARTICULAR?",
+ "HOW DO YOU LIKE YOUR WATCH?", "WHY DO YOU MENTION COMPUTERS?",
+ "DO YOU FIND MACHINES AS FASCINATING AS I DO?",
+ "DON'T YOU THINK COMPUTERS CAN HELP PEOPLE?",
+ "WHAT ABOUT MACHINES EXCITES YOU THE MOST?",
+ "HEY THERE, HOW CAN I HELP YOU?",
+ "WHAT DOES THAT SUGGEST TO YOU?", "I SEE.",
+ "I'M NOT SURE I UNDERSTAND YOU FULLY.", "COME COME ELUCIDATE YOUR THOUGHTS.",
+ "CAN YOU ELABORATE ON THAT?", "THAT IS QUITE INTERESTING."};
+
+ private static char[] CONVERSATION_TO_RESPONSES_MAP = {
+ 1,3,4,2,6,4,6,4,10,4,14,3,17,3,20,2,22,3,25,3,
+ 28,4,28,4,32,3,35,5,40,9,40,9,40,9,40,9,40,9,40,9,
+ 49,2,51,4,55,4,59,4,63,1,63,1,64,5,69,5,74,2,76,4,
+ 80,3,83,7,90,3,93,6,99,7,106,6};
+
+ private int[] responseStarts = new int[36];
+ private int[] responseCurrentIndices = new int[36];
+ private int[] responseEnds = new int[36];
+ private String previousInput = null;
+
+ public ElizaResponder() {
+ for (int i = 0; i < CONVERSATION_TO_RESPONSES_MAP.length / 2; i++) {
+ responseStarts[i] = CONVERSATION_TO_RESPONSES_MAP[2 * i];
+ responseCurrentIndices[i] = CONVERSATION_TO_RESPONSES_MAP[2 * i];
+ responseEnds[i] = responseStarts[i] + CONVERSATION_TO_RESPONSES_MAP[2 * i + 1];
+ }
+ }
+
+ public String elzTalk(String input) {
+ if (null == input) {
+ input = "";
+ }
+ String result = "";
+
+ input = " " + input.toUpperCase().replace("\'", "") + " ";
+
+ if (previousInput != null && input.equals(previousInput)) {
+ return "DIDN'T YOU JUST SAY THAT?\n";
+ }
+ previousInput = input;
+
+ int keywordIndex = 0;
+ for (; keywordIndex < CONVERSATION_KEYWORDS.length; ++keywordIndex) {
+ int index = input.indexOf(CONVERSATION_KEYWORDS[keywordIndex]);
+ if (index != -1) {
+ break;
+ }
+ }
+
+ String afterKeyword = "";
+ if (keywordIndex == CONVERSATION_KEYWORDS.length) {
+ keywordIndex = 35;
+ } else {
+ int index = input.indexOf(CONVERSATION_KEYWORDS[keywordIndex]);
+ afterKeyword = input.substring(index + CONVERSATION_KEYWORDS[keywordIndex].length());
+ String[] parts = afterKeyword.split("\\s+");
+ for (int i = 0; i < WORDS_TO_REPLACE.length / 2; i++) {
+ String first = WORDS_TO_REPLACE[i * 2];
+ String second = WORDS_TO_REPLACE[i * 2 + 1];
+ for (int j = 0; j < parts.length; ++j) {
+ if (parts[j].equals(first)) {
+ parts[j] = second;
+ } else if (parts[j].equals(second)) {
+ parts[j] = first;
+ }
+ }
+ }
+ afterKeyword = TextUtils.join(" ", parts);
+ }
+
+ String question = QUESTIONS[responseCurrentIndices[keywordIndex] - 1];
+ responseCurrentIndices[keywordIndex] = responseCurrentIndices[keywordIndex] + 1;
+ if (responseCurrentIndices[keywordIndex] > responseEnds[keywordIndex]) {
+ responseCurrentIndices[keywordIndex] = responseStarts[keywordIndex];
+ }
+ result += question;
+ if (result.endsWith("*")) {
+ result = result.substring(0, result.length() - 1);
+ result += " " + afterKeyword;
+ }
+
+ return result;
+ }
+}
diff --git a/wearable/wear/ElizaChat/Application/src/main/java/com/example/android/elizachat/MainActivity.java b/wearable/wear/ElizaChat/Application/src/main/java/com/example/android/elizachat/MainActivity.java
new file mode 100644
index 0000000..421dcb8
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/java/com/example/android/elizachat/MainActivity.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.elizachat;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.support.v4.content.LocalBroadcastManager;
+import android.text.TextUtils;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.TextView;
+
+public class MainActivity extends Activity {
+
+ @SuppressWarnings("unused")
+ private static final String TAG = "MainActivity";
+
+ public static final String EXTRA_MESSAGE = "message";
+
+ public static final String ACTION_NOTIFY = "com.example.android.elizachat.NOTIFY";
+
+ public static final String ACTION_GET_CONVERSATION
+ = "com.example.android.elizachat.CONVERSATION";
+
+ private BroadcastReceiver mReceiver;
+
+ private TextView mHistoryView;
+
+ @Override
+ protected void onCreate(Bundle saved) {
+ super.onCreate(saved);
+ setContentView(R.layout.main);
+ mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ processMessage(intent);
+ }
+ };
+ mHistoryView = (TextView) findViewById(R.id.history);
+ startResponderService();
+ }
+
+ private void startResponderService() {
+ Intent serviceIntent = new Intent(ResponderService.ACTION_INCOMING);
+ startService(serviceIntent);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver,
+ new IntentFilter(ACTION_NOTIFY));
+ mHistoryView.setText("");
+ Intent serviceIntent = new Intent(ACTION_GET_CONVERSATION);
+ startService(serviceIntent);
+
+ }
+
+ @Override
+ protected void onPause() {
+ LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
+ super.onPause();
+ }
+
+ private void processMessage(Intent intent) {
+ String text = intent.getStringExtra(EXTRA_MESSAGE);
+ if (!TextUtils.isEmpty(text)) {
+ mHistoryView.append("\n" + text);
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_stop_service:
+ stopService(new Intent(this, ResponderService.class));
+ finish();
+ break;
+ }
+ return true;
+ }
+}
diff --git a/wearable/wear/ElizaChat/Application/src/main/java/com/example/android/elizachat/ResponderService.java b/wearable/wear/ElizaChat/Application/src/main/java/com/example/android/elizachat/ResponderService.java
new file mode 100644
index 0000000..6d6cd9a
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/java/com/example/android/elizachat/ResponderService.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.elizachat;
+
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.support.v4.app.NotificationCompat;
+import android.support.v4.app.RemoteInput;
+import android.support.v4.content.LocalBroadcastManager;
+import android.support.v4.app.NotificationManagerCompat;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * A service that runs in the background and provides responses to the incoming messages from the
+ * wearable. It also keeps a record of the chat session history, which it can provide upon request.
+ */
+public class ResponderService extends Service {
+
+ public static final String ACTION_INCOMING = "com.example.android.elizachat.INCOMING";
+
+ public static final String ACTION_RESPONSE = "com.example.android.elizachat.REPLY";
+
+ public static final String EXTRA_REPLY = "reply";
+
+ private static final String TAG = "ResponderService";
+
+ private ElizaResponder mResponder;
+
+ private String mLastResponse = null;
+
+ private StringBuffer mCompleteConversation = new StringBuffer();
+
+ private LocalBroadcastManager mBroadcastManager;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Chat Service started");
+ }
+ mResponder = new ElizaResponder();
+ mBroadcastManager = LocalBroadcastManager.getInstance(this);
+ processIncoming(null);
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (null == intent || null == intent.getAction()) {
+ return Service.START_STICKY;
+ }
+ String action = intent.getAction();
+ if (action.equals(ACTION_RESPONSE)) {
+ Bundle remoteInputResults = RemoteInput.getResultsFromIntent(intent);
+ CharSequence replyMessage = "";
+ if (remoteInputResults != null) {
+ replyMessage = remoteInputResults.getCharSequence(EXTRA_REPLY);
+ }
+ processIncoming(replyMessage.toString());
+ } else if (action.equals(MainActivity.ACTION_GET_CONVERSATION)) {
+ broadcastMessage(mCompleteConversation.toString());
+ }
+ return Service.START_STICKY;
+ }
+
+ private void showNotification() {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Sent: " + mLastResponse);
+ }
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
+ .setContentTitle(getString(R.string.eliza))
+ .setContentText(mLastResponse)
+ .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.bg_eliza))
+ .setSmallIcon(R.drawable.bg_eliza)
+ .setPriority(NotificationCompat.PRIORITY_MIN);
+
+ Intent intent = new Intent(ACTION_RESPONSE);
+ PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent,
+ PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT);
+ Notification notification = builder
+ .extend(new NotificationCompat.WearableExtender()
+ .addAction(new NotificationCompat.Action.Builder(
+ R.drawable.ic_full_reply, getString(R.string.reply), pendingIntent)
+ .addRemoteInput(new RemoteInput.Builder(EXTRA_REPLY)
+ .setLabel(getString(R.string.reply))
+ .build())
+ .build()))
+ .build();
+ NotificationManagerCompat.from(this).notify(0, notification);
+ }
+
+ private void processIncoming(String text) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Received: " + text);
+ }
+ mLastResponse = mResponder.elzTalk(text);
+ String line = TextUtils.isEmpty(text) ? mLastResponse : text + "\n" + mLastResponse;
+
+ // Send a new line of conversation to update the Activity, unless the incoming text was
+ // empty.
+ if (!TextUtils.isEmpty(text)) {
+ broadcastMessage(line);
+ }
+ NotificationManagerCompat.from(this).cancelAll();
+ showNotification();
+ mCompleteConversation.append("\n" + line);
+ }
+
+ private void broadcastMessage(String message) {
+ Intent intent = new Intent(MainActivity.ACTION_NOTIFY);
+ intent.putExtra(MainActivity.EXTRA_MESSAGE, message);
+ mBroadcastManager.sendBroadcast(intent);
+ }
+
+ @Override
+ public void onDestroy() {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Chat Service stopped");
+ }
+ NotificationManagerCompat.from(this).cancel(0);
+ mBroadcastManager = null;
+ super.onDestroy();
+ }
+}
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/drawable-hdpi/ic_full_reply.png b/wearable/wear/ElizaChat/Application/src/main/res/drawable-hdpi/ic_full_reply.png
new file mode 100644
index 0000000..66388d5
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/drawable-hdpi/ic_full_reply.png
Binary files differ
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/drawable-mdpi/ic_full_reply.png b/wearable/wear/ElizaChat/Application/src/main/res/drawable-mdpi/ic_full_reply.png
new file mode 100644
index 0000000..60ce9f9
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/drawable-mdpi/ic_full_reply.png
Binary files differ
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/drawable-nodpi/bg_eliza.png b/wearable/wear/ElizaChat/Application/src/main/res/drawable-nodpi/bg_eliza.png
new file mode 100644
index 0000000..3bbdf48
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/drawable-nodpi/bg_eliza.png
Binary files differ
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/drawable-xhdpi/ic_full_reply.png b/wearable/wear/ElizaChat/Application/src/main/res/drawable-xhdpi/ic_full_reply.png
new file mode 100644
index 0000000..dba6fa7
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/drawable-xhdpi/ic_full_reply.png
Binary files differ
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/layout/main.xml b/wearable/wear/ElizaChat/Application/src/main/res/layout/main.xml
new file mode 100644
index 0000000..6ffed8e
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/layout/main.xml
@@ -0,0 +1,17 @@
+<ScrollView 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:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ tools:context="com.example.android.wearable.elizachat.MainActivity$PlaceholderFragment"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/history"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+
+</ScrollView>
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/menu/main.xml b/wearable/wear/ElizaChat/Application/src/main/res/menu/main.xml
new file mode 100644
index 0000000..b8e1ef2
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/menu/main.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/action_stop_service"
+ android:orderInCategory="100"
+ android:showAsAction="always|withText"
+ android:title="@string/stop_service" />
+
+</menu>
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/mipmap-hdpi/ic_app_eliza.png b/wearable/wear/ElizaChat/Application/src/main/res/mipmap-hdpi/ic_app_eliza.png
new file mode 100644
index 0000000..1bdb147
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/mipmap-hdpi/ic_app_eliza.png
Binary files differ
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/mipmap-mdpi/ic_app_eliza.png b/wearable/wear/ElizaChat/Application/src/main/res/mipmap-mdpi/ic_app_eliza.png
new file mode 100644
index 0000000..2e0e198
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/mipmap-mdpi/ic_app_eliza.png
Binary files differ
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/mipmap-xhdpi/ic_app_eliza.png b/wearable/wear/ElizaChat/Application/src/main/res/mipmap-xhdpi/ic_app_eliza.png
new file mode 100644
index 0000000..8d0f436
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/mipmap-xhdpi/ic_app_eliza.png
Binary files differ
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/mipmap-xxhdpi/ic_app_eliza.png b/wearable/wear/ElizaChat/Application/src/main/res/mipmap-xxhdpi/ic_app_eliza.png
new file mode 100644
index 0000000..e72b967
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/mipmap-xxhdpi/ic_app_eliza.png
Binary files differ
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/mipmap-xxxhdpi/ic_app_eliza.png b/wearable/wear/ElizaChat/Application/src/main/res/mipmap-xxxhdpi/ic_app_eliza.png
new file mode 100644
index 0000000..06ea079
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/mipmap-xxxhdpi/ic_app_eliza.png
Binary files differ
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/values/dimens.xml b/wearable/wear/ElizaChat/Application/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..a1e9cfe
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/values/dimens.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/wearable/wear/ElizaChat/Application/src/main/res/values/strings.xml b/wearable/wear/ElizaChat/Application/src/main/res/values/strings.xml
new file mode 100644
index 0000000..9a5c9d7
--- /dev/null
+++ b/wearable/wear/ElizaChat/Application/src/main/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+
+ <string name="send_notification">Send notification!</string>
+ <string name="eliza">Eliza</string>
+ <string name="answer_eliza">Answer Eliza</string>
+ <string name="reply">Reply</string>
+ <string name="stop_service">End Chat Session</string>
+
+</resources>
diff --git a/wearable/wear/ElizaChat/CONTRIB.md b/wearable/wear/ElizaChat/CONTRIB.md
new file mode 100644
index 0000000..14a4fcf
--- /dev/null
+++ b/wearable/wear/ElizaChat/CONTRIB.md
@@ -0,0 +1,35 @@
+# How to become a contributor and submit your own code
+
+## Contributor License Agreements
+
+We'd love to accept your sample apps and patches! Before we can take them, we
+have to jump a couple of legal hurdles.
+
+Please fill out either the individual or corporate Contributor License Agreement (CLA).
+
+ * If you are an individual writing original source code and you're sure you
+ own the intellectual property, then you'll need to sign an [individual CLA]
+ (https://developers.google.com/open-source/cla/individual).
+ * If you work for a company that wants to allow you to contribute your work,
+ then you'll need to sign a [corporate CLA]
+ (https://developers.google.com/open-source/cla/corporate).
+
+Follow either of the two links above to access the appropriate CLA and
+instructions for how to sign and return it. Once we receive it, we'll be able to
+accept your pull requests.
+
+## Contributing A Patch
+
+1. Submit an issue describing your proposed change to the repo in question.
+1. The repo owner will respond to your issue promptly.
+1. If your proposed change is accepted, and you haven't already done so, sign a
+ Contributor License Agreement (see details above).
+1. Fork the desired repo, develop and test your code changes.
+1. Ensure that your code adheres to the existing style in the sample to which
+ you are contributing. Refer to the
+ [Android Code Style Guide]
+ (https://source.android.com/source/code-style.html) for the
+ recommended coding standards for this organization.
+1. Ensure that your code has an appropriate set of unit tests which all pass.
+1. Submit a pull request.
+
diff --git a/wearable/wear/ElizaChat/LICENSE b/wearable/wear/ElizaChat/LICENSE
new file mode 100644
index 0000000..1af981f
--- /dev/null
+++ b/wearable/wear/ElizaChat/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/wearable/wear/ElizaChat/Shared/.gitignore b/wearable/wear/ElizaChat/Shared/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/ElizaChat/Shared/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/ElizaChat/Shared/src/main/AndroidManifest.xml b/wearable/wear/ElizaChat/Shared/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9c02d59
--- /dev/null
+++ b/wearable/wear/ElizaChat/Shared/src/main/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.elizachat.common">
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name">
+ </application>
+
+</manifest>
diff --git a/wearable/wear/ElizaChat/Shared/src/main/res/values/strings.xml b/wearable/wear/ElizaChat/Shared/src/main/res/values/strings.xml
new file mode 100644
index 0000000..0f2bb90
--- /dev/null
+++ b/wearable/wear/ElizaChat/Shared/src/main/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <string name="app_name">Shared</string>
+</resources>
diff --git a/wearable/wear/ElizaChat/build.gradle b/wearable/wear/ElizaChat/build.gradle
new file mode 100644
index 0000000..be1fa82
--- /dev/null
+++ b/wearable/wear/ElizaChat/build.gradle
@@ -0,0 +1,14 @@
+
+
+
+
+// BEGIN_EXCLUDE
+import com.example.android.samples.build.SampleGenPlugin
+apply plugin: SampleGenPlugin
+
+samplegen {
+ pathToBuild "../../../../../build"
+ pathToSamplesCommon "../../../common"
+}
+apply from: "../../../../../build/build.gradle"
+// END_EXCLUDE
diff --git a/wearable/wear/ElizaChat/buildSrc/build.gradle b/wearable/wear/ElizaChat/buildSrc/build.gradle
new file mode 100644
index 0000000..e344a8c
--- /dev/null
+++ b/wearable/wear/ElizaChat/buildSrc/build.gradle
@@ -0,0 +1,18 @@
+
+
+
+repositories {
+ mavenCentral()
+}
+dependencies {
+ compile 'org.freemarker:freemarker:2.3.20'
+}
+
+sourceSets {
+ main {
+ groovy {
+ srcDir new File(rootDir, "../../../../../../build/buildSrc/src/main/groovy")
+ }
+ }
+}
+
diff --git a/wearable/wear/ElizaChat/gradle/wrapper/gradle-wrapper.jar b/wearable/wear/ElizaChat/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/wearable/wear/ElizaChat/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/wearable/wear/ElizaChat/gradle/wrapper/gradle-wrapper.properties b/wearable/wear/ElizaChat/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..d7f03cf
--- /dev/null
+++ b/wearable/wear/ElizaChat/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-bin.zip
diff --git a/wearable/wear/ElizaChat/gradlew b/wearable/wear/ElizaChat/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/wearable/wear/ElizaChat/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/wearable/wear/ElizaChat/gradlew.bat b/wearable/wear/ElizaChat/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/wearable/wear/ElizaChat/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/wearable/wear/ElizaChat/settings.gradle b/wearable/wear/ElizaChat/settings.gradle
new file mode 100644
index 0000000..360755c
--- /dev/null
+++ b/wearable/wear/ElizaChat/settings.gradle
@@ -0,0 +1 @@
+include ':Application', ':Shared'
diff --git a/wearable/wear/ElizaChat/template-params.xml b/wearable/wear/ElizaChat/template-params.xml
new file mode 100644
index 0000000..bce15a9
--- /dev/null
+++ b/wearable/wear/ElizaChat/template-params.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<sample>
+ <name>ElizaChat</name>
+ <group>Connectivity</group>
+ <package>com.example.android.elizachat</package>
+
+
+
+ <!-- change minSdk if needed-->
+ <minSdk>20</minSdk>
+
+
+ <strings>
+ <intro>
+ <![CDATA[
+ This sample is a phone application that provides a chat experience in which users can respond to
+ messages with a quick voice response. New messages create a notification with a "Reply" action.
+ The notification is bridged from phone to wearable, and selecting the "Reply" action on the
+ wearable opens the voice transcription UI allowing the user to speak a response.
+ ]]>
+ </intro>
+ </strings>
+
+ <template src="base"/>
+ <common src="logger"/>
+ <common src="activities"/>
+
+</sample>
diff --git a/wearable/wear/EmbeddedApp/Application/.gitignore b/wearable/wear/EmbeddedApp/Application/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Application/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/EmbeddedApp/Application/proguard-project.txt b/wearable/wear/EmbeddedApp/Application/proguard-project.txt
new file mode 100644
index 0000000..0d8f171
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Application/proguard-project.txt
@@ -0,0 +1,20 @@
+ To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/wearable/wear/EmbeddedApp/Application/src/main/AndroidManifest.xml b/wearable/wear/EmbeddedApp/Application/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..2d266f2
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Application/src/main/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.embeddedapp" >
+ <uses-sdk android:minSdkVersion="18" android:targetSdkVersion="19" />
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@android:style/Theme.DeviceDefault.Light" >
+ <activity
+ android:name=".PhoneActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/wearable/wear/EmbeddedApp/Application/src/main/java/com/example/android/embeddedapp/PhoneActivity.java b/wearable/wear/EmbeddedApp/Application/src/main/java/com/example/android/embeddedapp/PhoneActivity.java
new file mode 100644
index 0000000..de95938
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Application/src/main/java/com/example/android/embeddedapp/PhoneActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.embeddedapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class PhoneActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_phone);
+ }
+}
diff --git a/wearable/wear/EmbeddedApp/Application/src/main/res/drawable-hdpi/ic_launcher.png b/wearable/wear/EmbeddedApp/Application/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..589f229
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/EmbeddedApp/Application/src/main/res/drawable-mdpi/ic_launcher.png b/wearable/wear/EmbeddedApp/Application/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..77dd571
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/EmbeddedApp/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/wearable/wear/EmbeddedApp/Application/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..fe34ebe
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/EmbeddedApp/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/wearable/wear/EmbeddedApp/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..ab80bcd
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/EmbeddedApp/Application/src/main/res/layout/activity_phone.xml b/wearable/wear/EmbeddedApp/Application/src/main/res/layout/activity_phone.xml
new file mode 100644
index 0000000..54ca57e
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Application/src/main/res/layout/activity_phone.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ tools:context=".PhoneActivity">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:text="@string/welcome_message"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentStart="true" />
+</RelativeLayout>
diff --git a/wearable/wear/EmbeddedApp/Application/src/main/res/values/dimens.xml b/wearable/wear/EmbeddedApp/Application/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..a1e9cfe
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Application/src/main/res/values/dimens.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/wearable/wear/EmbeddedApp/Application/src/main/res/values/strings.xml b/wearable/wear/EmbeddedApp/Application/src/main/res/values/strings.xml
new file mode 100644
index 0000000..05b6f12
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Application/src/main/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+
+ <string name="welcome_message">
+ By installing the release build of this application, the corresponding wearable app should
+ automatically be installed on any connected wearable devices.
+ </string>
+
+</resources>
diff --git a/wearable/wear/EmbeddedApp/CONTRIB.md b/wearable/wear/EmbeddedApp/CONTRIB.md
new file mode 100644
index 0000000..14a4fcf
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/CONTRIB.md
@@ -0,0 +1,35 @@
+# How to become a contributor and submit your own code
+
+## Contributor License Agreements
+
+We'd love to accept your sample apps and patches! Before we can take them, we
+have to jump a couple of legal hurdles.
+
+Please fill out either the individual or corporate Contributor License Agreement (CLA).
+
+ * If you are an individual writing original source code and you're sure you
+ own the intellectual property, then you'll need to sign an [individual CLA]
+ (https://developers.google.com/open-source/cla/individual).
+ * If you work for a company that wants to allow you to contribute your work,
+ then you'll need to sign a [corporate CLA]
+ (https://developers.google.com/open-source/cla/corporate).
+
+Follow either of the two links above to access the appropriate CLA and
+instructions for how to sign and return it. Once we receive it, we'll be able to
+accept your pull requests.
+
+## Contributing A Patch
+
+1. Submit an issue describing your proposed change to the repo in question.
+1. The repo owner will respond to your issue promptly.
+1. If your proposed change is accepted, and you haven't already done so, sign a
+ Contributor License Agreement (see details above).
+1. Fork the desired repo, develop and test your code changes.
+1. Ensure that your code adheres to the existing style in the sample to which
+ you are contributing. Refer to the
+ [Android Code Style Guide]
+ (https://source.android.com/source/code-style.html) for the
+ recommended coding standards for this organization.
+1. Ensure that your code has an appropriate set of unit tests which all pass.
+1. Submit a pull request.
+
diff --git a/wearable/wear/EmbeddedApp/LICENSE b/wearable/wear/EmbeddedApp/LICENSE
new file mode 100644
index 0000000..1af981f
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/wearable/wear/EmbeddedApp/README-wear.txt b/wearable/wear/EmbeddedApp/README-wear.txt
new file mode 100644
index 0000000..17523d7
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/README-wear.txt
@@ -0,0 +1,30 @@
+<#--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+Steps to use Wear template on top of an existing sample:
+- In template-params.xml.ftl:
+ - Add the following template:
+ <template src="Wear"/>
+
+- Refresh your project (./gradlew refresh)
+- Add Wearable-specific code to Wearable directory
+- Add code to be shared among the main application and the wearable to Shared
+ directory
+
+Note that you still need the main application sample code. This is usually
+achieved by adding another template, like "base" for example.
+
+
diff --git a/wearable/wear/EmbeddedApp/Shared/.gitignore b/wearable/wear/EmbeddedApp/Shared/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Shared/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/EmbeddedApp/Shared/src/main/AndroidManifest.xml b/wearable/wear/EmbeddedApp/Shared/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..f026bc5
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Shared/src/main/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.embeddedapp.common">
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name">
+ </application>
+
+</manifest>
diff --git a/wearable/wear/EmbeddedApp/Shared/src/main/res/values/strings.xml b/wearable/wear/EmbeddedApp/Shared/src/main/res/values/strings.xml
new file mode 100644
index 0000000..0f2bb90
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Shared/src/main/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <string name="app_name">Shared</string>
+</resources>
diff --git a/wearable/wear/EmbeddedApp/Wearable/.gitignore b/wearable/wear/EmbeddedApp/Wearable/.gitignore
new file mode 100644
index 0000000..6eb878d
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Wearable/.gitignore
@@ -0,0 +1,16 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+src/template/
+src/common/
+build.gradle
diff --git a/wearable/wear/EmbeddedApp/Wearable/src/main/AndroidManifest.xml b/wearable/wear/EmbeddedApp/Wearable/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..fd07d3c
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Wearable/src/main/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.embeddedapp" >
+
+ <uses-sdk android:minSdkVersion="20"
+ android:targetSdkVersion="20" />
+
+ <uses-feature android:name="android.hardware.type.watch" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@android:style/Theme.DeviceDefault.Light" >
+ <activity
+ android:name=".WearableActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/wearable/wear/EmbeddedApp/Wearable/src/main/java/com/example/android/embeddedapp/WearableActivity.java b/wearable/wear/EmbeddedApp/Wearable/src/main/java/com/example/android/embeddedapp/WearableActivity.java
new file mode 100644
index 0000000..1ae0c1f
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Wearable/src/main/java/com/example/android/embeddedapp/WearableActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.embeddedapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class WearableActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_wearable);
+ }
+}
diff --git a/wearable/wear/EmbeddedApp/Wearable/src/main/res/drawable-hdpi/ic_launcher.png b/wearable/wear/EmbeddedApp/Wearable/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..589f229
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Wearable/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/EmbeddedApp/Wearable/src/main/res/drawable-mdpi/ic_launcher.png b/wearable/wear/EmbeddedApp/Wearable/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..77dd571
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Wearable/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/EmbeddedApp/Wearable/src/main/res/drawable-xhdpi/ic_launcher.png b/wearable/wear/EmbeddedApp/Wearable/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..fe34ebe
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Wearable/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/EmbeddedApp/Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png b/wearable/wear/EmbeddedApp/Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..ab80bcd
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/wearable/wear/EmbeddedApp/Wearable/src/main/res/layout/activity_wearable.xml b/wearable/wear/EmbeddedApp/Wearable/src/main/res/layout/activity_wearable.xml
new file mode 100644
index 0000000..1f6a78a
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Wearable/src/main/res/layout/activity_wearable.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".WearableActivity">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/welcome_message"
+ android:layout_centerVertical="true"
+ android:layout_centerHorizontal="true" />
+</RelativeLayout>
diff --git a/wearable/wear/EmbeddedApp/Wearable/src/main/res/values/strings.xml b/wearable/wear/EmbeddedApp/Wearable/src/main/res/values/strings.xml
new file mode 100644
index 0000000..1823c57
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/Wearable/src/main/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+
+ <string name="app_name">EmbeddedApp Sample</string>
+ <string name="welcome_message">
+ This wearable app should be automatically installed on wearable devices whenever the
+ release build of the corresponding phone app is installed.
+ </string>
+
+</resources>
diff --git a/wearable/wear/EmbeddedApp/build.gradle b/wearable/wear/EmbeddedApp/build.gradle
new file mode 100644
index 0000000..be1fa82
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/build.gradle
@@ -0,0 +1,14 @@
+
+
+
+
+// BEGIN_EXCLUDE
+import com.example.android.samples.build.SampleGenPlugin
+apply plugin: SampleGenPlugin
+
+samplegen {
+ pathToBuild "../../../../../build"
+ pathToSamplesCommon "../../../common"
+}
+apply from: "../../../../../build/build.gradle"
+// END_EXCLUDE
diff --git a/wearable/wear/EmbeddedApp/buildSrc/build.gradle b/wearable/wear/EmbeddedApp/buildSrc/build.gradle
new file mode 100644
index 0000000..e344a8c
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/buildSrc/build.gradle
@@ -0,0 +1,18 @@
+
+
+
+repositories {
+ mavenCentral()
+}
+dependencies {
+ compile 'org.freemarker:freemarker:2.3.20'
+}
+
+sourceSets {
+ main {
+ groovy {
+ srcDir new File(rootDir, "../../../../../../build/buildSrc/src/main/groovy")
+ }
+ }
+}
+
diff --git a/wearable/wear/EmbeddedApp/gradle/wrapper/gradle-wrapper.jar b/wearable/wear/EmbeddedApp/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/wearable/wear/EmbeddedApp/gradle/wrapper/gradle-wrapper.properties b/wearable/wear/EmbeddedApp/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..d7f03cf
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-bin.zip
diff --git a/wearable/wear/EmbeddedApp/gradlew b/wearable/wear/EmbeddedApp/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/wearable/wear/EmbeddedApp/gradlew.bat b/wearable/wear/EmbeddedApp/gradlew.bat
new file mode 100644
index 0000000..8a0b282
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/wearable/wear/EmbeddedApp/settings.gradle b/wearable/wear/EmbeddedApp/settings.gradle
new file mode 100644
index 0000000..8522c57
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/settings.gradle
@@ -0,0 +1 @@
+include ':Application', ':Wearable', ':Shared'
diff --git a/wearable/wear/EmbeddedApp/template-params.xml b/wearable/wear/EmbeddedApp/template-params.xml
new file mode 100644
index 0000000..e4141f8
--- /dev/null
+++ b/wearable/wear/EmbeddedApp/template-params.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<sample>
+ <name>EmbeddedApp</name>
+ <group>Connectivity</group>
+ <package>com.example.android.embeddedapp</package>
+
+
+
+ <!-- change minSdk if needed-->
+ <minSdk>20</minSdk>
+
+
+ <strings>
+ <intro>
+ <![CDATA[
+ This simple app demonstrates how to embed a wearable app into a phone app.
+ ]]>
+ </intro>
+ </strings>
+
+ <template src="base"/>
+ <template src="Wear"/>
+ <common src="logger"/>
+ <common src="activities"/>
+
+</sample>
diff --git a/wearable/wear/SynchronizedNotifications/Shared/src/main/res/values/strings.xml b/wearable/wear/SynchronizedNotifications/Shared/src/main/res/values/strings.xml
index 4a466aa..0f2bb90 100644
--- a/wearable/wear/SynchronizedNotifications/Shared/src/main/res/values/strings.xml
+++ b/wearable/wear/SynchronizedNotifications/Shared/src/main/res/values/strings.xml
@@ -1,3 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<resources>
<string name="app_name">Shared</string>
</resources>