original source : http://www.androiddocs.com/training/wearables/notifications/creating.html

Creating a Notification for Wearables

NotificationCompat.Builder 을 사용하면 기본적으로 mobile, wearable 기기에 전달될 기본 notification을 만들수 있다.



Import the necessary classes

build.gradlefile:

compile "com.android.support:support-v4:20.0.+"
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.app.NotificationCompat.WearableExtender;



Create Notifications with the Notification Builder

int notificationId = 001;
// Build intent for notification content
Intent viewIntent = new Intent(this, ViewEventActivity.class);
viewIntent.putExtra(EXTRA_EVENT_ID, eventId);
PendingIntent viewPendingIntent =
       PendingIntent.getActivity(this, 0, viewIntent, 0);

NotificationCompat.Builder notificationBuilder =
       new NotificationCompat.Builder(this)
       .setSmallIcon(R.drawable.ic_event)
       .setContentTitle(eventTitle)
       .setContentText(eventLocation)
       .setContentIntent(viewPendingIntent);

// Get an instance of the NotificationManager service
NotificationManagerCompat notificationManager =
       NotificationManagerCompat.from(this);

// Build the notification and issues it with notification manager.
notificationManager.notify(notificationId, notificationBuilder.build());

When this notification appears on a handheld device, the user can invoke the PendingIntent specified by the setContentIntent() method by touching the notification. When this notification appears on an Android wearable, the user can swipe the notification to the left to reveal the Open action, which invokes the intent on the handheld device.

Add Action Buttons

// Build an intent for an action to view a map
Intent mapIntent = new Intent(Intent.ACTION_VIEW);
Uri geoUri = Uri.parse("geo:0,0?q=" + Uri.encode(location));
mapIntent.setData(geoUri);
PendingIntent mapPendingIntent =
       PendingIntent.getActivity(this, 0, mapIntent, 0);

NotificationCompat.Builder notificationBuilder =
       new NotificationCompat.Builder(this)
       .setSmallIcon(R.drawable.ic_event)
       .setContentTitle(eventTitle)
       .setContentText(eventLocation)
       .setContentIntent(viewPendingIntent)
       .addAction(R.drawable.ic_map,
               getString(R.string.map), mapPendingIntent);

On a handheld, the action appears as an additional button attached to the notification. On a wearable, the action appears as a large button when the user swipes the notification to the left. When the user taps the action, the associated intent is invoked on the handheld.

Specify Wearable-only Actions

If you want the actions available on the wearable to be different from those on the handheld, then use WearableExtender.addAction(). Once you add an action with this method, the wearable does not display any other actions added with NotificationCompat.Builder.addAction(). That is, only the actions added with WearableExtender.addAction() appear on the wearable and they do not appear on the handheld.

// Create an intent for the reply action
Intent actionIntent = new Intent(this, ActionActivity.class);
PendingIntent actionPendingIntent =
       PendingIntent.getActivity(this, 0, actionIntent,
               PendingIntent.FLAG_UPDATE_CURRENT);

// Create the action
NotificationCompat.Action action =
       new NotificationCompat.Action.Builder(R.drawable.ic_action,
               getString(R.string.label), actionPendingIntent)
               .build();

// Build the notification and add the action via WearableExtender
Notification notification =
       new NotificationCompat.Builder(mContext)
               .setSmallIcon(R.drawable.ic_message)
               .setContentTitle(getString(R.string.title))
               .setContentText(getString(R.string.content))
               .extend(new WearableExtender().addAction(action))
               .build();



Add a Big View

To add the extended content to your notification, call setStyle() on the NotificationCompat.Builder object, passing it an instance of eitherBigTextStyle or InboxStyle.

// Specify the 'big view' content to display the long
// event description that may not fit the normal content text.
BigTextStyle bigStyle = new NotificationCompat.BigTextStyle();
bigStyle.bigText(eventDescription);

NotificationCompat.Builder notificationBuilder =
       new NotificationCompat.Builder(this)
       .setSmallIcon(R.drawable.ic_event)
       .setLargeIcon(BitmapFactory.decodeResource(
               getResources(), R.drawable.notif_background))
       .setContentTitle(eventTitle)
       .setContentText(eventLocation)
       .setContentIntent(viewPendingIntent)
       .addAction(R.drawable.ic_map,
               getString(R.string.map), mapPendingIntent)
       .setStyle(bigStyle);



Add Wearable Features For a Notification

예시) 

setHintHideIcon(), setBackground()

  1. Create an instance of a WearableExtender, setting the wearable-specific options for the notication.
  2. Create an instance of NotificationCompat.Builder, setting the desired properties for your notification as described earlier in this lesson.
  3. Call extend() on the notification and pass in the WearableExtender. This applies the wearable options to the notification.
  4. Call build() to build the notification.
// Create a WearableExtender to add functionality for wearables
NotificationCompat.WearableExtender wearableExtender =
       new NotificationCompat.WearableExtender()
       .setHintHideIcon(true)
       .setBackground(mBitmap);

// Create a NotificationCompat.Builder to build a standard notification
// then extend it with the WearableExtender
Notification notif = new NotificationCompat.Builder(mContext)
       .setContentTitle("New mail from " + sender)
       .setContentText(subject)
       .setSmallIcon(R.drawable.new_mail)
       .extend(wearableExtender)
       .build();

Note: The bitmap that you use with setBackground() should have a resolution of 400×400 for non-scrolling backgrounds and 640×400 for backgrounds that support parallax scrolling. Place these bitmap images in the res/drawable-nodpi directory. Place other non-bitmap resources for wearable notifications, such as those used with the setContentIcon() method, in the res/drawable-hdpi directory.

If you ever need to read wearable-specific options at a later time, use the corresponding get method for the option. This example calls the getHintHideIcon()

NotificationCompat.WearableExtender wearableExtender =
       new NotificationCompat.WearableExtender(notif);
boolean hintHideIcon = wearableExtender.getHintHideIcon();



Deliver the Notification

When you want to deliver your notifications, always use the NotificationManagerCompat API instead ofNotificationManager:

// Get an instance of the NotificationManager service
NotificationManagerCompat notificationManager =
       NotificationManagerCompat.from(mContext);

// Issue the notification with notification manager.
notificationManager.notify(notificationId, notif);

original source : http://www.androiddocs.com/training/wearables/ui/cards.html

Creating Cards

The Wearable UI Library provides implementations of cards specifically designed for wearable devices. This library contains the CardFrame class, which wraps views inside a card-styled frame. CardFrame can only contain one direct child, 어떤 fragment가 cardFrame안에 들어갈지는 layout manager를 통해 결정한다.  

You can add cards to your app in two ways:

  • Use or extend the CardFragment class.
  • Add a card inside a CardScrollView in your layout.

Note: This lesson shows you how to add cards to Android Wear activities. Android notifications on wearable devices are also displayed as cards. For more information, see Adding Wearable Features to Notifications



Create a Card Fragment

To add a CardFragment to your app:

  1. In your layout, assign an ID to the element that contains the card
  2. Create a CardFragment instance in your activity
  3. Use the fragment manager to add the CardFragment instance to its container
<android.support.wearable.view.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/robot_background"
android:layout_height="match_parent"
android:layout_width="match_parent">

   <FrameLayout
       android:id="@+id/frame_layout"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       app:layout_box="bottom">

   </FrameLayout>
</android.support.wearable.view.BoxInsetLayout>

The following code adds the CardFragment instance to the activity in Figure 1:

protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_wear_activity2);

   FragmentManager fragmentManager = getFragmentManager();
   FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
   CardFragment cardFragment = CardFragment.create(getString(R.string.cftitle),
                                                   getString(R.string.cfdesc),
                                                   R.drawable.p);
   fragmentTransaction.add(R.id.frame_layout, cardFragment);
   fragmentTransaction.commit();
}

To create a card with a custom layout using CardFragment, extend this class and override its onCreateContentView method.

Add a CardFrame to Your Layout

You can also add a card directly to your layout definition,

<android.support.wearable.view.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/robot_background"
android:layout_height="match_parent"
android:layout_width="match_parent">

   <android.support.wearable.view.CardScrollView
       android:id="@+id/card_scroll_view"
       android:layout_height="match_parent"
       android:layout_width="match_parent"
       app:layout_box="bottom">

       <android.support.wearable.view.CardFrame
           android:layout_height="wrap_content"
           android:layout_width="fill_parent">

           <LinearLayout
               android:layout_height="wrap_content"
               android:layout_width="match_parent"
               android:orientation="vertical"
               android:paddingLeft="5dp">
               <TextView
                   android:fontFamily="sans-serif-light"
                   android:layout_height="wrap_content"
                   android:layout_width="match_parent"
                   android:text="@string/custom_card"
                   android:textColor="@color/black"
                   android:textSize="20sp"/>
               <TextView
                   android:fontFamily="sans-serif-light"
                   android:layout_height="wrap_content"
                   android:layout_width="match_parent"
                   android:text="@string/description"
                   android:textColor="@color/black"
                   android:textSize="14sp"/>
           </LinearLayout>
       </android.support.wearable.view.CardFrame>
   </android.support.wearable.view.CardScrollView>
</android.support.wearable.view.BoxInsetLayout>
@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_wear_activity2);

   CardScrollView cardScrollView =
       (CardScrollView) findViewById(R.id.card_scroll_view);
   cardScrollView.setCardGravity(Gravity.BOTTOM);
}

original source : http://www.androiddocs.com/training/wearables/ui/cards.html

Creating Cards

The Wearable UI Library provides implementations of cards specifically designed for wearable devices. This library contains the CardFrame class, which wraps views inside a card-styled frame. CardFrame can only contain one direct child, 어떤 fragment가 cardFrame안에 들어갈지는 layout manager를 통해 결정한다.  

You can add cards to your app in two ways:

  • Use or extend the CardFragment class.
  • Add a card inside a CardScrollView in your layout.

Note: This lesson shows you how to add cards to Android Wear activities. Android notifications on wearable devices are also displayed as cards. For more information, see Adding Wearable Features to Notifications



Create a Card Fragment

To add a CardFragment to your app:

  1. In your layout, assign an ID to the element that contains the card
  2. Create a CardFragment instance in your activity
  3. Use the fragment manager to add the CardFragment instance to its container
<android.support.wearable.view.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/robot_background"
android:layout_height="match_parent"
android:layout_width="match_parent">

   <FrameLayout
       android:id="@+id/frame_layout"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       app:layout_box="bottom">

   </FrameLayout>
</android.support.wearable.view.BoxInsetLayout>

The following code adds the CardFragment instance to the activity in Figure 1:

protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_wear_activity2);

   FragmentManager fragmentManager = getFragmentManager();
   FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
   CardFragment cardFragment = CardFragment.create(getString(R.string.cftitle),
                                                   getString(R.string.cfdesc),
                                                   R.drawable.p);
   fragmentTransaction.add(R.id.frame_layout, cardFragment);
   fragmentTransaction.commit();
}

To create a card with a custom layout using CardFragment, extend this class and override its onCreateContentView method.

Add a CardFrame to Your Layout

You can also add a card directly to your layout definition,

<android.support.wearable.view.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/robot_background"
android:layout_height="match_parent"
android:layout_width="match_parent">

   <android.support.wearable.view.CardScrollView
       android:id="@+id/card_scroll_view"
       android:layout_height="match_parent"
       android:layout_width="match_parent"
       app:layout_box="bottom">

       <android.support.wearable.view.CardFrame
           android:layout_height="wrap_content"
           android:layout_width="fill_parent">

           <LinearLayout
               android:layout_height="wrap_content"
               android:layout_width="match_parent"
               android:orientation="vertical"
               android:paddingLeft="5dp">
               <TextView
                   android:fontFamily="sans-serif-light"
                   android:layout_height="wrap_content"
                   android:layout_width="match_parent"
                   android:text="@string/custom_card"
                   android:textColor="@color/black"
                   android:textSize="20sp"/>
               <TextView
                   android:fontFamily="sans-serif-light"
                   android:layout_height="wrap_content"
                   android:layout_width="match_parent"
                   android:text="@string/description"
                   android:textColor="@color/black"
                   android:textSize="14sp"/>
           </LinearLayout>
       </android.support.wearable.view.CardFrame>
   </android.support.wearable.view.CardScrollView>
</android.support.wearable.view.BoxInsetLayout>
@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_wear_activity2);

   CardScrollView cardScrollView =
       (CardScrollView) findViewById(R.id.card_scroll_view);
   cardScrollView.setCardGravity(Gravity.BOTTOM);
}

original source : http://www.androiddocs.com/training/wearables/ui/confirm.html

Showing Confirmations

The Wearable UI Library helps you show confirmation animations and timers in your Android Wear apps:

  • Confirmation timers          Automatic confirmation timers show users an animated timer that lets them cancel an action they just performed.
  • Confirmation           animationsConfirmation animations give users visual feedback when they complete an action. 

아래 confirmation timer는 deprecated 되었다.
https://developer.android.com/training/wearables/ui/confirm.html
를 대신 이용할것

Use Automatic Confirmation Timers

image

Automatic confirmation timers let users cancel an action they just performed. When the user performs the action, your app shows a button to cancel the action with a timer animation and starts the timer. The user has the option to cancel the action until the timer finishes. Your app gets notified if the user cancels the action and when the timer expires.

To show a confirmation timer when users complete an action in your app:

  1. Add a DelayedConfirmationView element to your layout.
  2. Implement the DelayedConfirmationListener interface in your activity.
  3. Set the duration of the timer and start it when the user completes an action.
<android.support.wearable.view.DelayedConfirmationView
   android:id="@+id/delayed_confirm"
   android:layout_width="40dp"
   android:layout_height="40dp"
   android:src="@drawable/cancel_circle"
   app:circle_border_color="@color/lightblue"
   app:circle_border_width="4dp"
   app:circle_radius="16dp">
</android.support.wearable.view.DelayedConfirmationView>

You can assign a drawable resource to display inside the circle with the android:src attribute and configure the parameters of the circle directly on the layout definition.

To be notified when the timer finishes or when users tap on it, implement the corresponding listener methods in your activity:

public class WearActivity extends Activity implements
                          DelayedConfirmationView.DelayedConfirmationListener {

   private DelayedConfirmationView mDelayedView;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_wear_activity);

       mDelayedView =
               (DelayedConfirmationView) findViewById(R.id.delayed_confirm);
       mDelayedView.setListener(this);
   }

   @Override
   public void onTimerFinished(View view) {
       // User didn't cancel, perform the action
   }

   @Override
   public void onTimerSelected(View view) {
       // User canceled, abort the action
   }
}

To start the timer

// Two seconds to cancel the action
mDelayedView.setTotalTimeMs(2000);
// Start the timer
mDelayedView.start();



Show Confirmation Animations

image

To show a confirmation animation when users complete an action in your app, create an intent that starts ConfirmationActivity from one of your activities. You can specify one of the these animations with the EXTRA_ANIMATION_TYPE intent extra:

  • SUCCESS_ANIMATION
  • FAILURE_ANIMATION
  • OPEN_ON_PHONE_ANIMATION

You can also add a message that appears under the confirmation icon.

<manifest>
 <application>
   ...
   <activity
       android:name="android.support.wearable.activity.ConfirmationActivity">
   </activity>
 </application>
</manifest>
Intent intent = new Intent(this, ConfirmationActivity.class);
intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE,
               ConfirmationActivity.SUCCESS_ANIMATION);
intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE,
               getString(R.string.msg_sent));
startActivity(intent);

After showing the confirmation animation, ConfirmationActivity finishes and your activity resumes.

original source : http://www.androiddocs.com/training/wearables/ui/confirm.html

Showing Confirmations

The Wearable UI Library helps you show confirmation animations and timers in your Android Wear apps:

  • Confirmation timers          Automatic confirmation timers show users an animated timer that lets them cancel an action they just performed.
  • Confirmation           animationsConfirmation animations give users visual feedback when they complete an action. 

아래 confirmation timer는 deprecated 되었다.
https://developer.android.com/training/wearables/ui/confirm.html
를 대신 이용할것

Use Automatic Confirmation Timers

image

Automatic confirmation timers let users cancel an action they just performed. When the user performs the action, your app shows a button to cancel the action with a timer animation and starts the timer. The user has the option to cancel the action until the timer finishes. Your app gets notified if the user cancels the action and when the timer expires.

To show a confirmation timer when users complete an action in your app:

  1. Add a DelayedConfirmationView element to your layout.
  2. Implement the DelayedConfirmationListener interface in your activity.
  3. Set the duration of the timer and start it when the user completes an action.
<android.support.wearable.view.DelayedConfirmationView
   android:id="@+id/delayed_confirm"
   android:layout_width="40dp"
   android:layout_height="40dp"
   android:src="@drawable/cancel_circle"
   app:circle_border_color="@color/lightblue"
   app:circle_border_width="4dp"
   app:circle_radius="16dp">
</android.support.wearable.view.DelayedConfirmationView>

You can assign a drawable resource to display inside the circle with the android:src attribute and configure the parameters of the circle directly on the layout definition.

To be notified when the timer finishes or when users tap on it, implement the corresponding listener methods in your activity:

public class WearActivity extends Activity implements
                          DelayedConfirmationView.DelayedConfirmationListener {

   private DelayedConfirmationView mDelayedView;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_wear_activity);

       mDelayedView =
               (DelayedConfirmationView) findViewById(R.id.delayed_confirm);
       mDelayedView.setListener(this);
   }

   @Override
   public void onTimerFinished(View view) {
       // User didn't cancel, perform the action
   }

   @Override
   public void onTimerSelected(View view) {
       // User canceled, abort the action
   }
}

To start the timer

// Two seconds to cancel the action
mDelayedView.setTotalTimeMs(2000);
// Start the timer
mDelayedView.start();



Show Confirmation Animations

image

To show a confirmation animation when users complete an action in your app, create an intent that starts ConfirmationActivity from one of your activities. You can specify one of the these animations with the EXTRA_ANIMATION_TYPE intent extra:

  • SUCCESS_ANIMATION
  • FAILURE_ANIMATION
  • OPEN_ON_PHONE_ANIMATION

You can also add a message that appears under the confirmation icon.

<manifest>
 <application>
   ...
   <activity
       android:name="android.support.wearable.activity.ConfirmationActivity">
   </activity>
 </application>
</manifest>
Intent intent = new Intent(this, ConfirmationActivity.class);
intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE,
               ConfirmationActivity.SUCCESS_ANIMATION);
intent.putExtra(ConfirmationActivity.EXTRA_MESSAGE,
               getString(R.string.msg_sent));
startActivity(intent);

After showing the confirmation animation, ConfirmationActivity finishes and your activity resumes.

original source: http://www.androiddocs.com/training/wearables/notifications/pages.html

Adding Pages to a Notification

When you’d like to provide more information without requiring users to open your app on their handheld device, you can add one or more pages to the notification on the wearable. (notification에 추가적으로 정보를 전달하고 싶은 경우 pages를 이용한다.)

  1. Create the main notification (the first page) with NotificationCompat.Builder, in the way you’d like the notification to appear on a handset.
  2. Create the additional pages for the wearable with NotificationCompat.Builder.
  3. Apply the pages to the main notification with the addPage() method or add multiple pages in a Collectionwith the addPages() method.
// Create builder for the main notification
NotificationCompat.Builder notificationBuilder =
       new NotificationCompat.Builder(this)
       .setSmallIcon(R.drawable.new_message)
       .setContentTitle("Page 1")
       .setContentText("Short message")
       .setContentIntent(viewPendingIntent);

// Create a big text style for the second page
BigTextStyle secondPageStyle = new NotificationCompat.BigTextStyle();
secondPageStyle.setBigContentTitle("Page 2")
              .bigText("A lot of text...");

// Create second page notification
Notification secondPageNotification =
       new NotificationCompat.Builder(this)
       .setStyle(secondPageStyle)
       .build();

// Extend the notification builder with the second page
Notification notification = notificationBuilder
       .extend(new NotificationCompat.WearableExtender()
               .addPage(secondPageNotification))
       .build();

// Issue the notification
notificationManager =
       NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, notification);

original source: http://www.androiddocs.com/training/wearables/notifications/pages.html

Adding Pages to a Notification

When you’d like to provide more information without requiring users to open your app on their handheld device, you can add one or more pages to the notification on the wearable. (notification에 추가적으로 정보를 전달하고 싶은 경우 pages를 이용한다.)

  1. Create the main notification (the first page) with NotificationCompat.Builder, in the way you’d like the notification to appear on a handset.
  2. Create the additional pages for the wearable with NotificationCompat.Builder.
  3. Apply the pages to the main notification with the addPage() method or add multiple pages in a Collectionwith the addPages() method.
// Create builder for the main notification
NotificationCompat.Builder notificationBuilder =
       new NotificationCompat.Builder(this)
       .setSmallIcon(R.drawable.new_message)
       .setContentTitle("Page 1")
       .setContentText("Short message")
       .setContentIntent(viewPendingIntent);

// Create a big text style for the second page
BigTextStyle secondPageStyle = new NotificationCompat.BigTextStyle();
secondPageStyle.setBigContentTitle("Page 2")
              .bigText("A lot of text...");

// Create second page notification
Notification secondPageNotification =
       new NotificationCompat.Builder(this)
       .setStyle(secondPageStyle)
       .build();

// Extend the notification builder with the second page
Notification notification = notificationBuilder
       .extend(new NotificationCompat.WearableExtender()
               .addPage(secondPageNotification))
       .build();

// Issue the notification
notificationManager =
       NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, notification);