diff --git a/docs/html/images/training/wear/ask_again.png b/docs/html/images/training/wear/ask_again.png new file mode 100644 index 0000000000000..33c110b4b07c8 Binary files /dev/null and b/docs/html/images/training/wear/ask_again.png differ diff --git a/docs/html/images/training/wear/ask_again_2x.png b/docs/html/images/training/wear/ask_again_2x.png new file mode 100644 index 0000000000000..899620348c045 Binary files /dev/null and b/docs/html/images/training/wear/ask_again_2x.png differ diff --git a/docs/html/images/training/wear/ask_in_context.png b/docs/html/images/training/wear/ask_in_context.png new file mode 100644 index 0000000000000..61fa478baac9f Binary files /dev/null and b/docs/html/images/training/wear/ask_in_context.png differ diff --git a/docs/html/images/training/wear/ask_in_context_2x.png b/docs/html/images/training/wear/ask_in_context_2x.png new file mode 100644 index 0000000000000..20c1f47ce04ed Binary files /dev/null and b/docs/html/images/training/wear/ask_in_context_2x.png differ diff --git a/docs/html/images/training/wear/ask_up_front.png b/docs/html/images/training/wear/ask_up_front.png new file mode 100644 index 0000000000000..ced2228377cf4 Binary files /dev/null and b/docs/html/images/training/wear/ask_up_front.png differ diff --git a/docs/html/images/training/wear/ask_up_front_2x.png b/docs/html/images/training/wear/ask_up_front_2x.png new file mode 100644 index 0000000000000..ef7eb46ee07e8 Binary files /dev/null and b/docs/html/images/training/wear/ask_up_front_2x.png differ diff --git a/docs/html/images/training/wear/deny.png b/docs/html/images/training/wear/deny.png new file mode 100644 index 0000000000000..a1e956205d618 Binary files /dev/null and b/docs/html/images/training/wear/deny.png differ diff --git a/docs/html/images/training/wear/deny_2x.png b/docs/html/images/training/wear/deny_2x.png new file mode 100644 index 0000000000000..721c2712c7424 Binary files /dev/null and b/docs/html/images/training/wear/deny_2x.png differ diff --git a/docs/html/images/training/wear/educate_in_context.png b/docs/html/images/training/wear/educate_in_context.png new file mode 100644 index 0000000000000..c8ac64119002a Binary files /dev/null and b/docs/html/images/training/wear/educate_in_context.png differ diff --git a/docs/html/images/training/wear/educate_in_context_2x.png b/docs/html/images/training/wear/educate_in_context_2x.png new file mode 100644 index 0000000000000..92baead40512c Binary files /dev/null and b/docs/html/images/training/wear/educate_in_context_2x.png differ diff --git a/docs/html/images/training/wear/educate_up_front.png b/docs/html/images/training/wear/educate_up_front.png new file mode 100644 index 0000000000000..2e4fdf79293aa Binary files /dev/null and b/docs/html/images/training/wear/educate_up_front.png differ diff --git a/docs/html/images/training/wear/educate_up_front_2x.png b/docs/html/images/training/wear/educate_up_front_2x.png new file mode 100644 index 0000000000000..1f6f491b70d69 Binary files /dev/null and b/docs/html/images/training/wear/educate_up_front_2x.png differ diff --git a/docs/html/images/training/wear/for_services.png b/docs/html/images/training/wear/for_services.png new file mode 100644 index 0000000000000..0aaae10313bce Binary files /dev/null and b/docs/html/images/training/wear/for_services.png differ diff --git a/docs/html/images/training/wear/for_services_2x.png b/docs/html/images/training/wear/for_services_2x.png new file mode 100644 index 0000000000000..a7f92f2ab2be2 Binary files /dev/null and b/docs/html/images/training/wear/for_services_2x.png differ diff --git a/docs/html/images/training/wear/for_settings.png b/docs/html/images/training/wear/for_settings.png new file mode 100644 index 0000000000000..fde50c7da1f28 Binary files /dev/null and b/docs/html/images/training/wear/for_settings.png differ diff --git a/docs/html/images/training/wear/for_settings_2x.png b/docs/html/images/training/wear/for_settings_2x.png new file mode 100644 index 0000000000000..c2daa7c501379 Binary files /dev/null and b/docs/html/images/training/wear/for_settings_2x.png differ diff --git a/docs/html/images/training/wear/multiple_permissions.png b/docs/html/images/training/wear/multiple_permissions.png new file mode 100644 index 0000000000000..65e3e08d753a2 Binary files /dev/null and b/docs/html/images/training/wear/multiple_permissions.png differ diff --git a/docs/html/images/training/wear/multiple_permissions_2x.png b/docs/html/images/training/wear/multiple_permissions_2x.png new file mode 100644 index 0000000000000..cbaace89c5fa3 Binary files /dev/null and b/docs/html/images/training/wear/multiple_permissions_2x.png differ diff --git a/docs/html/images/training/wear/open_on_phone.png b/docs/html/images/training/wear/open_on_phone.png new file mode 100644 index 0000000000000..189983996df68 Binary files /dev/null and b/docs/html/images/training/wear/open_on_phone.png differ diff --git a/docs/html/images/training/wear/open_on_phone_2x.png b/docs/html/images/training/wear/open_on_phone_2x.png new file mode 100644 index 0000000000000..e5c2c9659418f Binary files /dev/null and b/docs/html/images/training/wear/open_on_phone_2x.png differ diff --git a/docs/html/images/training/wear/phone_requests_wear.png b/docs/html/images/training/wear/phone_requests_wear.png new file mode 100644 index 0000000000000..4d0b09dabb19f Binary files /dev/null and b/docs/html/images/training/wear/phone_requests_wear.png differ diff --git a/docs/html/images/training/wear/phone_requests_wear_2x.png b/docs/html/images/training/wear/phone_requests_wear_2x.png new file mode 100644 index 0000000000000..1c98f4a637ac7 Binary files /dev/null and b/docs/html/images/training/wear/phone_requests_wear_2x.png differ diff --git a/docs/html/training/articles/wear-permissions.jd b/docs/html/training/articles/wear-permissions.jd new file mode 100644 index 0000000000000..5f226e49c9f53 --- /dev/null +++ b/docs/html/training/articles/wear-permissions.jd @@ -0,0 +1,323 @@ +page.title=Requesting Permissions on Android Wear +page.tags="Permissions" + +page.article=true +@jd:body + +
+
+

In this document

+
    +
  1. Permission Scenarios
  2. +
  3. Requesting Permissions
  4. +
  5. Permissions for Services
  6. +
  7. Settings
  8. +
+ +

Dependencies and prerequisites

+ +

See also

+ +
+ +

Android 6.0 (API level 23) +introduces a new permissions model, +bringing some changes that are specific to Wear, and other changes that apply to all Android-powered +devices.

+ +

The user must now grant permissions to Wear apps separately from the handset versions of the +apps. Previously, when a user installed a Wear app, it automatically inherited the set of +permissions that the user had granted to the handset version of the app. However, from Android 6.0 +(API level 23), the Wear app no longer inherits these permissions. Thus, for example, +a user might grant a handset app permission to use location data, and subsequently +have to grant the same permission to the Wear version of the app.

+ +

For both Wear and handset apps, the Android 6.0 (API level 23) permissions model also +streamlines app installation and upgrade by eliminating the requirement that the user grant upfront +every permission an app may ever need. Instead, the app does not request permissions until it +actually needs them.

+ +

Note: For an app to use the new permissions model, it must +specify a value of {@code 23} for both +{@code uses-sdk-element} +and {@code compileSdkVersion}.

+ +

The rest of this document discusses how to use the Android 6.0 (API level 23) permissions model +when developing Android Wear apps.

+ +

Permission Scenarios

+ +

Broadly speaking, there are four scenarios you may encounter when requesting +dangerous permissions +on Android Wear:

+ + + +

The rest of this section explains each of these scenarios. For more detailed information +about requesting permissions, see Requesting Permissions.

+ +

Wear app requests permission for an app running on the wearable +device

+ +

When the Wear app requests a permission for an app running on the wearable device, the system +displays a dialog to prompt the user for that permission. An app or service can only call the +{@link android.support.v4.app.ActivityCompat#requestPermissions requestPermissions()} +method from an activity. If the user interacts with your app +via a service, such as +a watch face, the service must open an activity before requesting the permission.

+ +

Your app requests permissions in context when it’s clear why the +permissions are needed to perform a given operation. If it's obvious that your app requires +certain permissions, your app can prompt for them on launch. If it may not be so obvious, +you may choose to provide additional education before prompting for a permission.

+ +

If an app or watch face requires more than one permission at a time, +permission requests appear one after the other.

+ + +

+ Figure 1. Permission screens appearing in succession. +

+ +

Note: From Android 6.0 (API level 23), Android Wear +automatically syncs Calendar, Contact, and Location data to the Wear device. As a result, this +scenario is the applicable one when Wear requests this data.

+ +

Wear app requests handset permission

+ +

When the Wear app requests a handset permission, the +Wear app must send the user to the handset to accept the permission. There, the handset app can +provide additional education to the user via an activity. The activity should include two buttons: +one for granting, and one for denying, the permission.

+ + +

+ Figure 2. Sending the user to the handset to grant permission. +

+

Handset app requests wearable permission

+ +

When the user is in a handset app and the app requires a wearable permission, the +handset app must send the user to the wearable to accept the permission. +The handset app uses the +{@link android.support.v4.app.ActivityCompat#requestPermissions requestPermissions()} +method on the wearable to trigger the system permissions dialog.

+ + +

+ Figure 3. Sending the user to the wearable to grant permission. +

+ +

Mismatching permission models between wearable and handset app

+ +

If your handset app begins using the Android 6.0 (API level 23) model but your +wearable app does not, the system downloads the Wear app, but does not install it. +The first time the user launches the app, the system prompts them to grant all pending permissions. +Once they do so, it installs the app. +If your app, for example a watch face, does not have a launcher, the system displays a +stream notification asking the user to grant the permissions the app needs. +

+ +

Permission-Request Patterns

+ +

There are different patterns for requesting permission from users. In order of +priority, they are:

+ + + +

Ask in context

+ +

Your app should request permissions when it’s clear why they are needed in order to perform a +given operation. Users are more likely to grant a permission when they understand its connection to +the feature they want to use.

+ +

For example, an app may require a user’s location in order to show nearby +places of interest. When the user taps to search for nearby places, the app can +immediately request the location permission, because there is a clear +relationship between searching for nearby places and the need for the location +permission. The obviousness of this relationship makes it unnecessary for the app to display +additional education screens.

+ + +

+ Figure 4. Asking in context. + +

Educate in context

+ +

If necessary, you may choose to provide additional education before prompting +for a permission. Again, your app should do this in context of a specific +action, if it’s unclear why your app needs access to the requested permission +in order to complete that action.

+ +

Figure 5 shows an example of in-context education. The app does not require permissions +in order to start the timer, but an inline educational cue shows that part of the +activity (location detection) is locked. When the user taps the cue, a permission-request screen +appears, allowing the user to unlock location-detection.

+ +

You can use the {@link + android.support.v4.app.ActivityCompat#shouldShowRequestPermissionRationale + shouldShowRequestPermissionRationale()} method to help your app decide whether to provide more + information. For additional details, see Requesting Permissions + at Run Time.

+ + + +

+ Figure 5. Educating in context. + +

Ask up front

+ +

If your app clearly requires a permission in order to work at all, you can prompt for that +permission when the user launches the app. For example, a maps app clearly requires access +to the device’s location to run its expected activities. No further education +is necessary for this permission.

+ + +

+ Figure 6. Asking up front. + + +

Educate up front

+ +

In some cases, the app requires a permission for basic functionality, but the need for that +permission is not obvious. In these cases, when the user first +starts the app or sets a watch face, the app or watch face may choose to educate the user and +ask for the permission.

+ + +

+ Figure 7. Educating up front. + +

Handling Rejection

+ +

If a user denies a requested permission that is not critical to an intended +activity, do not block them from continuing the activity. If certain parts of +the activity are disabled by the denied permission, provide visual, actionable +feedback. Figure 8 shows the use of a lock icon to indicate that a feature is +locked because the user did not grant permission to use it.

+ + +

+ Figure 8. Lock icon, showing a feature is locked because of denied permission. +

+

When a previously denied wearable permission dialog appears a second +time, it includes a Deny, don't show again option. If the user +chooses this option, then the only way for them to allow this permission in the +future is to go into the wearable's Settings app.

+ + +

+ Figure 9. Offering not to show the permission-request screen anymore. + +

Permissions for Services

+ +

As mentioned above, only an activity can call the +{@link android.support.v4.app.ActivityCompat#requestPermissions requestPermissions()} +method, so if the user interacts with your app via a service, +for example a watch face, the service must open a background activity before requesting +the permission. This activity could provide additional education, or it could simply +be an invisible activity that brings up the system dialog.

+ +

If your wearable app runs a service that is not a watch face, and the user does not launch +an app in which it might make sense to request a permission, +you can post an educational notification on the wearable. The notification can +provide an action to open an activity that then triggers the system permissions +dialog.

+ +

Note: This is the only acceptable use of a stream notification +for permissions requests.

+ + +

+ Figure 10. A service requesting permission. + +

Settings

+ +

As with the handset, the user can change a Wear app’s permissions in Settings at any time. +Therefore, when the user tries to do something that requires a +permission, the app should always first call the +{@link android.support.v4.content.ContextCompat#checkSelfPermission(android.content.Context,java.lang.String) checkSelfPermission()} +method to see if the app currently has permission to perform this operation. The app should perform +this check even if it knows the user has previously granted that permission, since the +user might have subsequently revoked that permission.

+ + +

+ Figure 11. Changing settings via the Settings app. diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index 85733bfd02e99..8f0865114ac0d 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -1008,6 +1008,21 @@ "How to detect location data on Android Wear devices." >Detecting Location + +

  • + Requesting Permissions +
  • + +
  • + Using the Speaker +
  • + diff --git a/docs/html/training/wearables/wearable-sounds.jd b/docs/html/training/wearables/wearable-sounds.jd new file mode 100644 index 0000000000000..3c3c135756d02 --- /dev/null +++ b/docs/html/training/wearables/wearable-sounds.jd @@ -0,0 +1,63 @@ +page.title=Using Speakers on Wearables + +@jd:body + +
    +
    +

    This lesson teaches you to

    +
      +
    1. Detect the Speaker
    2. +
    3. Play Sounds
    4. +
    +

    You should also read

    + +
    +
    + +

    Some Android Wear devices include speakers, enabling them to incorporate sound into their +apps and offer an extra dimension of engagement with the user. A speaker-equipped Wear device might +trigger a clock or timer alarm, complete with audio notification. Games on Wear become become more +entertaining by offering not just sight, but sound.

    + +

    This page describes how apps on Wear devices running Android 6.0 (API level 23) can use +familiar Android APIs to play sounds through the device speaker.

    + +

    Detect the Speaker

    + +

    A Wear app must first detect whether the wearable device has a speaker. In the following example, +the app uses the {@link android.media.AudioManager#getDevices(int) getDevices() } method in +conjunction with the value of {@link android.content.pm.PackageManager#FEATURE_AUDIO_OUTPUT} to +confirm that the device is equipped with a speaker.

    + +
    +PackageManager packageManager = context.getPackageManager();
    +AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    +
    +// Check whether the device has a speaker.
    +if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    +    // Check FEATURE_AUDIO_OUTPUT to guard against false positives.
    +    if (!packageManager.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
    +        return false;
    +    }
    +
    +    AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
    +    for (AudioDeviceInfo device : devices) {
    +        if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
    +            return true;
    +        }
    +    }
    +}
    +return false;
    +
    + +

    Play Sounds

    + +

    Once you've detected the speaker, the process for playing sound on Android Wear is the +same as for a handset or other device. For more information, see +Media Playback.

    + +

    If you also want to record audio from the microphone on the wearable, your app must also get +permission to use the microphone. To learn more, see +Permissions on Android Wear.

    \ No newline at end of file