summaryrefslogtreecommitdiff
path: root/prebuilts/gradle
diff options
context:
space:
mode:
authorTrevor Johns <trevorjohns@google.com>2014-12-11 14:22:56 -0800
committerTrevor Johns <trevorjohns@google.com>2014-12-11 15:30:20 -0800
commitf4852427259f175605844f385f0be2eb2ae0e5ec (patch)
tree8b5f06594a3c6de514c475786347ecbcd318d905 /prebuilts/gradle
parent5073d44d2b933234d20338d1daaabbc3e9c60d65 (diff)
downloadbuild-f4852427259f175605844f385f0be2eb2ae0e5ec.tar.gz
Sync sample prebuilts for lmp-docs
Synced to developers/samples/android commit c90e4cf627af4eb1c42b759a54baf3ab07998e27. Change-Id: I12bdf2049bd0c735a2385374ed13862b105247f6
Diffstat (limited to 'prebuilts/gradle')
-rw-r--r--prebuilts/gradle/ActionBarCompat-Basic/Application/build.gradle8
-rw-r--r--prebuilts/gradle/ActionBarCompat-ListPopupMenu/.google/packaging.yaml4
-rw-r--r--prebuilts/gradle/ActionBarCompat-ListPopupMenu/Application/build.gradle8
-rw-r--r--prebuilts/gradle/ActionBarCompat-ListPopupMenu/README.md18
-rw-r--r--prebuilts/gradle/ActionBarCompat-ListPopupMenu/screenshots/1-main.pngbin0 -> 82931 bytes
-rw-r--r--prebuilts/gradle/ActionBarCompat-ListPopupMenu/screenshots/2-popup.pngbin0 -> 86469 bytes
-rw-r--r--prebuilts/gradle/ActionBarCompat-ListPopupMenu/screenshots/icon-web.pngbin0 -> 40502 bytes
-rw-r--r--prebuilts/gradle/ActionBarCompat-ShareActionProvider/Application/build.gradle8
-rw-r--r--prebuilts/gradle/ActionBarCompat-Styled/Application/build.gradle6
-rw-r--r--prebuilts/gradle/ActivityInstrumentation/Application/build.gradle2
-rw-r--r--prebuilts/gradle/ActivitySceneTransitionBasic/Application/build.gradle6
-rw-r--r--prebuilts/gradle/AdapterTransition/Application/build.gradle6
-rw-r--r--prebuilts/gradle/AdvancedImmersiveMode/Application/build.gradle2
-rw-r--r--prebuilts/gradle/AgendaData/.google/packaging.yaml6
-rw-r--r--prebuilts/gradle/AgendaData/README.md26
-rw-r--r--prebuilts/gradle/AppRestrictionEnforcer/Application/build.gradle6
-rw-r--r--prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/AppRestrictionEnforcerFragment.java351
-rw-r--r--prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/Constants.java27
-rw-r--r--prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/EasyTextWatcher.java38
-rw-r--r--prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/MainActivity.java47
-rw-r--r--prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/StatusFragment.java136
-rw-r--r--prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_app_restriction_enforcer.xml124
-rw-r--r--prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_status.xml39
-rw-r--r--prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/separator.xml22
-rw-r--r--prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/values/ids.xml21
-rw-r--r--prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/values/strings.xml4
-rw-r--r--prebuilts/gradle/AppRestrictionEnforcer/gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--prebuilts/gradle/AppRestrictionSchema/Application/build.gradle6
-rw-r--r--prebuilts/gradle/AppRestrictionSchema/Application/src/main/java/com/example/android/apprestrictionschema/AppRestrictionSchemaFragment.java117
-rw-r--r--prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/layout/fragment_app_restriction_schema.xml70
-rw-r--r--prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/layout/separator.xml22
-rw-r--r--prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/values/restriction_values.xml77
-rw-r--r--prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/values/strings.xml11
-rw-r--r--prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/xml/app_restrictions.xml48
-rw-r--r--prebuilts/gradle/AppRestrictionSchema/gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--prebuilts/gradle/AppRestrictions/Application/build.gradle6
-rw-r--r--prebuilts/gradle/AppUsageStatistics/.google/packaging.yaml17
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/build.gradle72
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/AndroidManifest.xml37
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/AppUsageStatisticsActivity.java37
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/AppUsageStatisticsFragment.java230
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/CustomUsageStats.java28
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/UsageListAdapter.java95
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-hdpi/ic_default_app_launcher.pngbin0 -> 9397 bytes
-rwxr-xr-xprebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-hdpi/ic_launcher.pngbin0 -> 4248 bytes
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-hdpi/tile.9.pngbin0 -> 196 bytes
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-mdpi/ic_default_app_launcher.pngbin0 -> 5237 bytes
-rwxr-xr-xprebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-mdpi/ic_launcher.pngbin0 -> 2678 bytes
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xhdpi/ic_default_app_launcher.pngbin0 -> 14383 bytes
-rwxr-xr-xprebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xhdpi/ic_launcher.pngbin0 -> 6126 bytes
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xxhdpi/ic_default_app_launcher.pngbin0 -> 19388 bytes
-rwxr-xr-xprebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xxhdpi/ic_launcher.pngbin0 -> 11029 bytes
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/activity_app_usage_statistics.xml23
-rwxr-xr-xprebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/activity_main.xml36
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/fragment_app_usage_statistics.xml55
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/usage_row.xml72
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-sw600dp/template-dimens.xml24
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-sw600dp/template-styles.xml25
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-v11/template-styles.xml22
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-v21/base-colors.xml20
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-v21/base-template-styles.xml23
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/base-strings.xml29
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/dimens.xml20
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/navigation_items.xml24
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/strings.xml25
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/styles.xml21
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/template-dimens.xml32
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/template-styles.xml42
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/tests/src/com/example/android/appusagestatistics/AppUsageStatisticsActivityTests.java70
-rw-r--r--prebuilts/gradle/AppUsageStatistics/Application/tests/src/com/example/android/appusagestatistics/AppUsageStatisticsFragmentTests.java97
-rw-r--r--prebuilts/gradle/AppUsageStatistics/CONTRIBUTING.md35
-rw-r--r--prebuilts/gradle/AppUsageStatistics/LICENSE201
-rw-r--r--prebuilts/gradle/AppUsageStatistics/NOTICE15
-rw-r--r--prebuilts/gradle/AppUsageStatistics/README.md96
-rw-r--r--prebuilts/gradle/AppUsageStatistics/build.gradle11
-rw-r--r--prebuilts/gradle/AppUsageStatistics/gradle/wrapper/gradle-wrapper.jarbin0 -> 49896 bytes
-rw-r--r--prebuilts/gradle/AppUsageStatistics/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xprebuilts/gradle/AppUsageStatistics/gradlew164
-rw-r--r--prebuilts/gradle/AppUsageStatistics/gradlew.bat90
-rw-r--r--prebuilts/gradle/AppUsageStatistics/screenshots/screenshot-1.pngbin0 -> 305215 bytes
-rw-r--r--prebuilts/gradle/AppUsageStatistics/screenshots/screenshot-2.pngbin0 -> 315711 bytes
-rwxr-xr-xprebuilts/gradle/AppUsageStatistics/screenshots/web-icon.pngbin0 -> 71167 bytes
-rw-r--r--prebuilts/gradle/AppUsageStatistics/settings.gradle1
-rw-r--r--prebuilts/gradle/BasicAccessibility/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BasicAndroidKeyStore/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BasicContactables/.google/packaging.yaml8
-rw-r--r--prebuilts/gradle/BasicContactables/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BasicContactables/README.md26
-rw-r--r--prebuilts/gradle/BasicContactables/screenshots/1-main.pngbin0 -> 102700 bytes
-rw-r--r--prebuilts/gradle/BasicContactables/screenshots/2-search.pngbin0 -> 145488 bytes
-rw-r--r--prebuilts/gradle/BasicContactables/screenshots/3-results.pngbin0 -> 108490 bytes
-rw-r--r--prebuilts/gradle/BasicContactables/screenshots/icon-web.pngbin0 -> 54813 bytes
-rw-r--r--prebuilts/gradle/BasicGestureDetect/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BasicImmersiveMode/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BasicManagedProfile/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BasicMediaDecoder/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BasicMediaRouter/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BasicMultitouch/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BasicNetworking/.google/packaging.yaml5
-rw-r--r--prebuilts/gradle/BasicNetworking/Application/build.gradle2
-rwxr-xr-xprebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-hdpi/ic_launcher.pngbin4407 -> 4499 bytes
-rwxr-xr-xprebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-mdpi/ic_launcher.pngbin2668 -> 2721 bytes
-rwxr-xr-xprebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-xhdpi/ic_launcher.pngbin6230 -> 6287 bytes
-rwxr-xr-xprebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-xxhdpi/ic_launcher.pngbin11294 -> 10763 bytes
-rw-r--r--prebuilts/gradle/BasicNetworking/Application/src/main/res/values/base-strings.xml8
-rw-r--r--prebuilts/gradle/BasicNetworking/README.md20
-rw-r--r--prebuilts/gradle/BasicNetworking/screenshots/big_icon.pngbin0 -> 65211 bytes
-rw-r--r--prebuilts/gradle/BasicNetworking/screenshots/start.pngbin0 -> 149545 bytes
-rw-r--r--prebuilts/gradle/BasicNetworking/screenshots/tested.pngbin0 -> 162094 bytes
-rw-r--r--prebuilts/gradle/BasicNotifications/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BasicRenderScript/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BasicSyncAdapter/.google/packaging.yaml11
-rw-r--r--prebuilts/gradle/BasicSyncAdapter/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-hdpi/ic_launcher.pngbin5473 -> 4588 bytes
-rw-r--r--prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-mdpi/ic_launcher.pngbin3298 -> 2770 bytes
-rw-r--r--prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-xhdpi/ic_launcher.pngbin7401 -> 6549 bytes
-rw-r--r--prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-xxhdpi/ic_launcher.pngbin12074 -> 11666 bytes
-rw-r--r--prebuilts/gradle/BasicSyncAdapter/README.md30
-rw-r--r--prebuilts/gradle/BasicSyncAdapter/screenshots/icon-web.pngbin0 -> 74499 bytes
-rw-r--r--prebuilts/gradle/BasicSyncAdapter/screenshots/main.pngbin0 -> 270487 bytes
-rw-r--r--prebuilts/gradle/BasicTransition/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BatchStepSensor/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BluetoothChat/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BluetoothLeGatt/Application/build.gradle6
-rw-r--r--prebuilts/gradle/BorderlessButtons/Application/build.gradle6
-rw-r--r--prebuilts/gradle/Camera2Basic/Application/build.gradle6
-rw-r--r--prebuilts/gradle/Camera2Video/Application/build.gradle6
-rw-r--r--prebuilts/gradle/CardEmulation/Application/build.gradle6
-rw-r--r--prebuilts/gradle/CardReader/Application/build.gradle6
-rw-r--r--prebuilts/gradle/CardView/Application/build.gradle2
-rw-r--r--prebuilts/gradle/ClippingBasic/Application/build.gradle6
-rw-r--r--prebuilts/gradle/CustomChoiceList/Application/build.gradle2
-rw-r--r--prebuilts/gradle/CustomNotifications/Application/build.gradle2
-rw-r--r--prebuilts/gradle/CustomTransition/Application/build.gradle6
-rw-r--r--prebuilts/gradle/DirectorySelection/.google/packaging.yaml17
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/build.gradle71
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/AndroidManifest.xml37
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectoryEntry.java25
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectoryEntryAdapter.java100
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectorySelectionActivity.java37
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectorySelectionFragment.java231
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/ic_description_grey600_36dp.pngbin0 -> 425 bytes
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/ic_folder_grey600_36dp.pngbin0 -> 292 bytes
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/ic_launcher.pngbin0 -> 3779 bytes
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/tile.9.pngbin0 -> 196 bytes
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-mdpi/ic_description_grey600_36dp.pngbin0 -> 271 bytes
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-mdpi/ic_folder_grey600_36dp.pngbin0 -> 227 bytes
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-mdpi/ic_launcher.pngbin0 -> 2391 bytes
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xhdpi/ic_description_grey600_36dp.pngbin0 -> 461 bytes
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xhdpi/ic_folder_grey600_36dp.pngbin0 -> 356 bytes
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xhdpi/ic_launcher.pngbin0 -> 5328 bytes
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xxhdpi/ic_description_grey600_36dp.pngbin0 -> 635 bytes
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xxhdpi/ic_folder_grey600_36dp.pngbin0 -> 493 bytes
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xxhdpi/ic_launcher.pngbin0 -> 9650 bytes
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/activity_directory_selection.xml23
-rwxr-xr-xprebuilts/gradle/DirectorySelection/Application/src/main/res/layout/activity_main.xml36
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/directory_item.xml57
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/fragment_directory_selection.xml74
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/menu/main.xml16
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/values-sw600dp/template-dimens.xml24
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/values-sw600dp/template-styles.xml25
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/values-v11/template-styles.xml22
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/values-v21/base-colors.xml20
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/values-v21/base-template-styles.xml23
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/values/base-strings.xml29
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/values/dimens.xml20
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/values/strings.xml21
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/values/styles.xml21
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/values/template-dimens.xml32
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/src/main/res/values/template-styles.xml42
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/tests/src/com/example/android/directoryselection/DirectoryEntryAdapterTest.java82
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/tests/src/com/example/android/directoryselection/DirectorySelectionActivityTest.java56
-rw-r--r--prebuilts/gradle/DirectorySelection/Application/tests/src/com/example/android/directoryselection/DirectorySelectionFragmentTest.java68
-rw-r--r--prebuilts/gradle/DirectorySelection/CONTRIBUTING.md35
-rw-r--r--prebuilts/gradle/DirectorySelection/LICENSE201
-rw-r--r--prebuilts/gradle/DirectorySelection/NOTICE15
-rw-r--r--prebuilts/gradle/DirectorySelection/README.md154
-rw-r--r--prebuilts/gradle/DirectorySelection/build.gradle11
-rw-r--r--prebuilts/gradle/DirectorySelection/gradle/wrapper/gradle-wrapper.jarbin0 -> 49896 bytes
-rw-r--r--prebuilts/gradle/DirectorySelection/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xprebuilts/gradle/DirectorySelection/gradlew164
-rw-r--r--prebuilts/gradle/DirectorySelection/gradlew.bat90
-rw-r--r--prebuilts/gradle/DirectorySelection/screenshots/screenshot-1.pngbin0 -> 117267 bytes
-rw-r--r--prebuilts/gradle/DirectorySelection/screenshots/screenshot-2.pngbin0 -> 170338 bytes
-rw-r--r--prebuilts/gradle/DirectorySelection/screenshots/screenshot-3.pngbin0 -> 135819 bytes
-rwxr-xr-xprebuilts/gradle/DirectorySelection/screenshots/web-icon.pngbin0 -> 60929 bytes
-rw-r--r--prebuilts/gradle/DirectorySelection/settings.gradle1
-rw-r--r--prebuilts/gradle/DisplayingBitmaps/Application/build.gradle6
-rw-r--r--prebuilts/gradle/DocumentCentricApps/Application/build.gradle6
-rw-r--r--prebuilts/gradle/DocumentCentricRelinquishIdentity/Application/build.gradle6
-rw-r--r--prebuilts/gradle/DoneBar/Application/build.gradle6
-rw-r--r--prebuilts/gradle/DrawableTinting/Application/build.gradle6
-rw-r--r--prebuilts/gradle/ElevationBasic/Application/build.gradle6
-rw-r--r--prebuilts/gradle/ElevationDrag/Application/build.gradle6
-rw-r--r--prebuilts/gradle/ElizaChat/Application/build.gradle6
-rw-r--r--prebuilts/gradle/FloatingActionButtonBasic/Application/build.gradle6
-rw-r--r--prebuilts/gradle/FragmentTransition/Application/build.gradle6
-rw-r--r--prebuilts/gradle/HdrViewfinder/Application/build.gradle6
-rw-r--r--prebuilts/gradle/HorizontalPaging/Application/build.gradle6
-rw-r--r--prebuilts/gradle/ImmersiveMode/Application/build.gradle2
-rw-r--r--prebuilts/gradle/Interpolator/Application/build.gradle6
-rw-r--r--prebuilts/gradle/JobScheduler/Application/build.gradle6
-rw-r--r--prebuilts/gradle/JumpingJack/.google/packaging.yaml5
-rw-r--r--prebuilts/gradle/JumpingJack/README.md44
-rw-r--r--prebuilts/gradle/JumpingJack/screenshots/web-icon.pngbin0 -> 15228 bytes
-rw-r--r--prebuilts/gradle/LNotifications/Application/build.gradle6
-rw-r--r--prebuilts/gradle/MediaBrowserService/.google/packaging.yaml8
-rw-r--r--prebuilts/gradle/MediaBrowserService/Application/build.gradle6
-rw-r--r--prebuilts/gradle/MediaBrowserService/Application/src/main/java/com/example/android/mediabrowserservice/MediaNotification.java50
-rw-r--r--prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-hdpi/ic_launcher.pngbin4805 -> 2051 bytes
-rw-r--r--prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-mdpi/ic_launcher.pngbin2592 -> 1545 bytes
-rw-r--r--prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xhdpi/ic_launcher.pngbin5246 -> 2838 bytes
-rw-r--r--prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xxhdpi/ic_launcher.pngbin14755 -> 4437 bytes
-rw-r--r--prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xxxhdpi/ic_launcher.pngbin0 -> 5982 bytes
-rw-r--r--prebuilts/gradle/MediaBrowserService/README.md61
-rw-r--r--prebuilts/gradle/MediaBrowserService/screenshots/1-main.pngbin0 -> 45426 bytes
-rw-r--r--prebuilts/gradle/MediaBrowserService/screenshots/2-music-play.pngbin0 -> 73643 bytes
-rw-r--r--prebuilts/gradle/MediaBrowserService/screenshots/3-music-notification.pngbin0 -> 174696 bytes
-rw-r--r--prebuilts/gradle/MediaBrowserService/screenshots/icon-web.pngbin0 -> 19980 bytes
-rw-r--r--prebuilts/gradle/MediaEffects/Application/build.gradle6
-rw-r--r--prebuilts/gradle/MediaRecorder/Application/build.gradle6
-rw-r--r--prebuilts/gradle/MediaRouter/Application/build.gradle10
-rw-r--r--prebuilts/gradle/MessagingService/Application/build.gradle6
-rw-r--r--prebuilts/gradle/MessagingService/Application/src/main/res/drawable-hdpi/ic_launcher.pngbin3964 -> 4801 bytes
-rw-r--r--prebuilts/gradle/MessagingService/Application/src/main/res/drawable-mdpi/ic_launcher.pngbin2327 -> 2956 bytes
-rw-r--r--prebuilts/gradle/MessagingService/Application/src/main/res/drawable-xhdpi/ic_launcher.pngbin5488 -> 6724 bytes
-rw-r--r--prebuilts/gradle/MessagingService/Application/src/main/res/drawable-xxhdpi/ic_launcher.pngbin9578 -> 11883 bytes
-rw-r--r--prebuilts/gradle/MessagingService/README.md42
-rw-r--r--prebuilts/gradle/MessagingService/screenshots/icon-web.pngbin9578 -> 73624 bytes
-rw-r--r--prebuilts/gradle/NavigationDrawer/Application/build.gradle8
-rw-r--r--prebuilts/gradle/NetworkConnect/Application/build.gradle6
-rw-r--r--prebuilts/gradle/PdfRendererBasic/Application/build.gradle6
-rw-r--r--prebuilts/gradle/PermissionRequest/.google/packaging.yaml18
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/build.gradle70
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/AndroidManifest.xml39
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/assets/sample.css36
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/assets/sample.html31
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/assets/sample.js56
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/activities/SampleActivityBase.java52
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/Log.java236
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogFragment.java109
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogNode.java39
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogView.java145
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogWrapper.java75
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java60
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/ConfirmationDialogFragment.java79
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/MainActivity.java109
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/PermissionRequestFragment.java180
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/SimpleWebServer.java222
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-hdpi/ic_launcher.pngbin0 -> 5409 bytes
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-hdpi/tile.9.pngbin0 -> 196 bytes
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-mdpi/ic_launcher.pngbin0 -> 3204 bytes
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-xhdpi/ic_launcher.pngbin0 -> 7793 bytes
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-xxhdpi/ic_launcher.pngbin0 -> 13799 bytes
-rwxr-xr-xprebuilts/gradle/PermissionRequest/Application/src/main/res/layout-w720dp/activity_main.xml73
-rwxr-xr-xprebuilts/gradle/PermissionRequest/Application/src/main/res/layout/activity_main.xml65
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/layout/fragment_permission_request.xml27
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/menu/main.xml21
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/values-sw600dp/template-dimens.xml24
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/values-sw600dp/template-styles.xml25
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/values-v11/template-styles.xml22
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/values-v21/base-colors.xml20
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/values-v21/base-template-styles.xml23
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/values/base-strings.xml29
-rwxr-xr-xprebuilts/gradle/PermissionRequest/Application/src/main/res/values/fragmentview_strings.xml19
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/values/strings.xml21
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/values/template-dimens.xml32
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/src/main/res/values/template-styles.xml42
-rw-r--r--prebuilts/gradle/PermissionRequest/Application/tests/src/com/example/android/permissionrequest/test/SampleTests.java196
-rw-r--r--prebuilts/gradle/PermissionRequest/CONTRIBUTING.md35
-rw-r--r--prebuilts/gradle/PermissionRequest/LICENSE201
-rw-r--r--prebuilts/gradle/PermissionRequest/NOTICE15
-rw-r--r--prebuilts/gradle/PermissionRequest/README.md93
-rw-r--r--prebuilts/gradle/PermissionRequest/build.gradle11
-rw-r--r--prebuilts/gradle/PermissionRequest/gradle/wrapper/gradle-wrapper.jarbin0 -> 49896 bytes
-rw-r--r--prebuilts/gradle/PermissionRequest/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xprebuilts/gradle/PermissionRequest/gradlew164
-rw-r--r--prebuilts/gradle/PermissionRequest/gradlew.bat90
-rw-r--r--prebuilts/gradle/PermissionRequest/screenshots/icon_web.pngbin0 -> 87912 bytes
-rw-r--r--prebuilts/gradle/PermissionRequest/screenshots/image1.pngbin0 -> 92266 bytes
-rw-r--r--prebuilts/gradle/PermissionRequest/screenshots/image2.pngbin0 -> 566711 bytes
-rw-r--r--prebuilts/gradle/PermissionRequest/settings.gradle1
-rw-r--r--prebuilts/gradle/RecipeAssistant/Application/build.gradle6
-rw-r--r--prebuilts/gradle/RecyclerView/Application/build.gradle8
-rw-r--r--prebuilts/gradle/RecyclerView/Application/src/main/java/com/example/android/recyclerview/RecyclerViewFragment.java4
-rw-r--r--prebuilts/gradle/RenderScriptIntrinsic/Application/build.gradle6
-rw-r--r--prebuilts/gradle/RepeatingAlarm/Application/build.gradle2
-rw-r--r--prebuilts/gradle/RevealEffectBasic/Application/build.gradle6
-rw-r--r--prebuilts/gradle/ScreenCapture/.google/packaging.yaml18
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/build.gradle70
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/AndroidManifest.xml34
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/activities/SampleActivityBase.java52
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/Log.java236
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogFragment.java109
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogNode.java39
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogView.java145
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogWrapper.java75
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java60
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/screencapture/MainActivity.java109
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/screencapture/ScreenCaptureFragment.java202
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-hdpi/ic_launcher.pngbin0 -> 4972 bytes
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-hdpi/tile.9.pngbin0 -> 196 bytes
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-mdpi/ic_launcher.pngbin0 -> 2932 bytes
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-xhdpi/ic_launcher.pngbin0 -> 7092 bytes
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-xxhdpi/ic_launcher.pngbin0 -> 12718 bytes
-rwxr-xr-xprebuilts/gradle/ScreenCapture/Application/src/main/res/layout-w720dp/activity_main.xml73
-rwxr-xr-xprebuilts/gradle/ScreenCapture/Application/src/main/res/layout/activity_main.xml65
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/layout/fragment_screen_capture.xml36
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/menu/main.xml21
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/values-sw600dp/template-dimens.xml24
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/values-sw600dp/template-styles.xml25
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/values-v11/template-styles.xml22
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/values-v21/base-colors.xml20
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/values-v21/base-template-styles.xml23
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/values/base-strings.xml29
-rwxr-xr-xprebuilts/gradle/ScreenCapture/Application/src/main/res/values/fragmentview_strings.xml19
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/values/strings.xml21
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/values/template-dimens.xml32
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/src/main/res/values/template-styles.xml42
-rw-r--r--prebuilts/gradle/ScreenCapture/Application/tests/src/com/example/android/screencapture/test/SampleTests.java62
-rw-r--r--prebuilts/gradle/ScreenCapture/CONTRIBUTING.md35
-rw-r--r--prebuilts/gradle/ScreenCapture/LICENSE201
-rw-r--r--prebuilts/gradle/ScreenCapture/NOTICE15
-rw-r--r--prebuilts/gradle/ScreenCapture/README.md73
-rw-r--r--prebuilts/gradle/ScreenCapture/build.gradle11
-rw-r--r--prebuilts/gradle/ScreenCapture/gradle/wrapper/gradle-wrapper.jarbin0 -> 49896 bytes
-rw-r--r--prebuilts/gradle/ScreenCapture/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xprebuilts/gradle/ScreenCapture/gradlew164
-rw-r--r--prebuilts/gradle/ScreenCapture/gradlew.bat90
-rw-r--r--prebuilts/gradle/ScreenCapture/screenshots/icon-web.pngbin0 -> 81953 bytes
-rw-r--r--prebuilts/gradle/ScreenCapture/screenshots/main.pngbin0 -> 150405 bytes
-rw-r--r--prebuilts/gradle/ScreenCapture/settings.gradle1
-rw-r--r--prebuilts/gradle/SlidingTabsBasic/Application/build.gradle2
-rw-r--r--prebuilts/gradle/SlidingTabsColors/Application/build.gradle2
-rw-r--r--prebuilts/gradle/StorageClient/Application/build.gradle2
-rw-r--r--prebuilts/gradle/StorageProvider/Application/build.gradle6
-rw-r--r--prebuilts/gradle/SwipeRefreshLayoutBasic/Application/build.gradle6
-rw-r--r--prebuilts/gradle/SwipeRefreshListFragment/Application/build.gradle6
-rw-r--r--prebuilts/gradle/SwipeRefreshMultipleViews/Application/build.gradle6
-rw-r--r--prebuilts/gradle/SynchronizedNotifications/.google/packaging.yaml6
-rw-r--r--prebuilts/gradle/SynchronizedNotifications/README.md52
-rwxr-xr-xprebuilts/gradle/SynchronizedNotifications/screenshots/web-icon.pngbin0 -> 74754 bytes
-rw-r--r--prebuilts/gradle/TextLinkify/Application/build.gradle2
-rw-r--r--prebuilts/gradle/TextSwitcher/Application/build.gradle2
-rw-r--r--prebuilts/gradle/WatchFace/Wearable/src/main/AndroidManifest.xml12
345 files changed, 10309 insertions, 464 deletions
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/Application/build.gradle b/prebuilts/gradle/ActionBarCompat-Basic/Application/build.gradle
index 1eb334ab..39b494bc 100644
--- a/prebuilts/gradle/ActionBarCompat-Basic/Application/build.gradle
+++ b/prebuilts/gradle/ActionBarCompat-Basic/Application/build.gradle
@@ -17,11 +17,11 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
- compile "com.android.support:appcompat-v7:18.0.+"
+ compile "com.android.support:appcompat-v7:21.0.2"
}
// The sample build uses multiple directories to
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/.google/packaging.yaml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/.google/packaging.yaml
index f30211c3..a799cfd4 100644
--- a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/.google/packaging.yaml
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/.google/packaging.yaml
@@ -9,4 +9,8 @@ categories: [UI]
languages: [Java]
solutions: [Mobile]
github: android-ActionBarCompat-ListPopupMenu
+level: INTERMEDIATE
+icon: screenshots/icon-web.png
+apiRefs:
+ - android:android.support.v7.widget.PopupMenu
license: apache2
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/Application/build.gradle b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/Application/build.gradle
index af12607c..39b494bc 100644
--- a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/Application/build.gradle
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/Application/build.gradle
@@ -17,11 +17,11 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
- compile "com.android.support:appcompat-v7:+"
+ compile "com.android.support:appcompat-v7:21.0.2"
}
// The sample build uses multiple directories to
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/README.md b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/README.md
index 282ed60a..5a366eb8 100644
--- a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/README.md
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/README.md
@@ -1,8 +1,17 @@
Android ActionBarCompat-ListPopupMenu Sample
===================================
-This sample shows you how to use {@link android.support.v7.widget.PopupMenu PopupMenu}
-from ActionBarCompat to create a list, with each item having a dropdown menu.
+This sample shows how to display a pop up menu using PopupMenu from the v7 appcompat library.
+
+Introduction
+------------
+
+This sample displays a list of items and for each item, an icon can be clicked. When it is clicked, a pop up menu is shown, placed below the item, using the [PopupMenu][1] from the v7 appcompat support library.
+
+The sample uses [ListFragment][2] from the v4 support library to display the list. It shows how to instantiate and display the [PopupMenu][1], as well as how to use `setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener())` to process the user actions on the [PopupMenu][1].
+
+[1]: https://developer.android.com/reference/android/support/v7/widget/PopupMenu.html
+[2]: https://developer.android.com/reference/android/support/v4/app/ListFragment.html
Pre-requisites
--------------
@@ -11,6 +20,11 @@ Pre-requisites
- Android Build Tools v21.1.1
- Android Support Repository
+Screenshots
+-------------
+
+<img src="screenshots/1-main.png" height="400" alt="Screenshot"/> <img src="screenshots/2-popup.png" height="400" alt="Screenshot"/>
+
Getting Started
---------------
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/screenshots/1-main.png b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/screenshots/1-main.png
new file mode 100644
index 00000000..f69ed96f
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/screenshots/1-main.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/screenshots/2-popup.png b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/screenshots/2-popup.png
new file mode 100644
index 00000000..b03862d1
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/screenshots/2-popup.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/screenshots/icon-web.png b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/screenshots/icon-web.png
new file mode 100644
index 00000000..5220b83f
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/screenshots/icon-web.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/Application/build.gradle b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/Application/build.gradle
index 1eb334ab..39b494bc 100644
--- a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/Application/build.gradle
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/Application/build.gradle
@@ -17,11 +17,11 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
- compile "com.android.support:appcompat-v7:18.0.+"
+ compile "com.android.support:appcompat-v7:21.0.2"
}
// The sample build uses multiple directories to
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/Application/build.gradle b/prebuilts/gradle/ActionBarCompat-Styled/Application/build.gradle
index 1eb334ab..8a24c4d1 100644
--- a/prebuilts/gradle/ActionBarCompat-Styled/Application/build.gradle
+++ b/prebuilts/gradle/ActionBarCompat-Styled/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
compile "com.android.support:appcompat-v7:18.0.+"
}
diff --git a/prebuilts/gradle/ActivityInstrumentation/Application/build.gradle b/prebuilts/gradle/ActivityInstrumentation/Application/build.gradle
index 05020be5..76169dee 100644
--- a/prebuilts/gradle/ActivityInstrumentation/Application/build.gradle
+++ b/prebuilts/gradle/ActivityInstrumentation/Application/build.gradle
@@ -17,7 +17,7 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
+ compile "com.android.support:support-v4:21.0.2"
}
diff --git a/prebuilts/gradle/ActivitySceneTransitionBasic/Application/build.gradle b/prebuilts/gradle/ActivitySceneTransitionBasic/Application/build.gradle
index 28005541..c2ac02c4 100644
--- a/prebuilts/gradle/ActivitySceneTransitionBasic/Application/build.gradle
+++ b/prebuilts/gradle/ActivitySceneTransitionBasic/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
compile "com.squareup.picasso:picasso:2.4.0"
}
diff --git a/prebuilts/gradle/AdapterTransition/Application/build.gradle b/prebuilts/gradle/AdapterTransition/Application/build.gradle
index bfed04fa..c6b8c26a 100644
--- a/prebuilts/gradle/AdapterTransition/Application/build.gradle
+++ b/prebuilts/gradle/AdapterTransition/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/Application/build.gradle b/prebuilts/gradle/AdvancedImmersiveMode/Application/build.gradle
index 05020be5..76169dee 100644
--- a/prebuilts/gradle/AdvancedImmersiveMode/Application/build.gradle
+++ b/prebuilts/gradle/AdvancedImmersiveMode/Application/build.gradle
@@ -17,7 +17,7 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
+ compile "com.android.support:support-v4:21.0.2"
}
diff --git a/prebuilts/gradle/AgendaData/.google/packaging.yaml b/prebuilts/gradle/AgendaData/.google/packaging.yaml
index 5b9e7913..0186ce1c 100644
--- a/prebuilts/gradle/AgendaData/.google/packaging.yaml
+++ b/prebuilts/gradle/AgendaData/.google/packaging.yaml
@@ -9,4 +9,10 @@ categories: [Wearable]
languages: [Java]
solutions: [Mobile]
github: android-AgendaData
+level: INTERMEDIATE
+icon: Wearable/src/main/res/drawable-xxhdpi/ic_launcher.png
+apiRefs:
+ - android:android.app.IntentService
+ - com.google.android.gms.wearable.DataApi
+ - com.google.android.gms.wearable.Node
license: apache2
diff --git a/prebuilts/gradle/AgendaData/README.md b/prebuilts/gradle/AgendaData/README.md
index 52ff0197..c1dcff10 100644
--- a/prebuilts/gradle/AgendaData/README.md
+++ b/prebuilts/gradle/AgendaData/README.md
@@ -1,11 +1,22 @@
Android AgendaData Sample
===================================
-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.
+Sample demonstrating sync of calendar events to a wearable by the press of a button.
+
+Introduction
+------------
+
+Using the Wearable [DataApi][1] allows to transmit data such as event time,
+description, and background image.
+
+The sent [DataItems][2] 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. The sample shows implementations for both the success as well failure case.
+
+[1]: https://developer.android.com/reference/com/google/android/gms/wearable/DataApi.html
+[2]: https://developer.android.com/reference/com/google/android/gms/wearable/DataItem.html
Pre-requisites
--------------
@@ -14,6 +25,11 @@ Pre-requisites
- Android Build Tools v21.1.1
- Android Support Repository
+Screenshots
+-------------
+
+<img src="screenshots/companion_agenda_data.png" height="400" alt="Screenshot"/> <img src="screenshots/dummy_calendar_event.png" height="400" alt="Screenshot"/>
+
Getting Started
---------------
diff --git a/prebuilts/gradle/AppRestrictionEnforcer/Application/build.gradle b/prebuilts/gradle/AppRestrictionEnforcer/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/AppRestrictionEnforcer/Application/build.gradle
+++ b/prebuilts/gradle/AppRestrictionEnforcer/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/AppRestrictionEnforcerFragment.java b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/AppRestrictionEnforcerFragment.java
index 6db54f65..8b0620fb 100644
--- a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/AppRestrictionEnforcerFragment.java
+++ b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/AppRestrictionEnforcerFragment.java
@@ -22,34 +22,34 @@ import android.content.Context;
import android.content.RestrictionEntry;
import android.content.RestrictionsManager;
import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.Button;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
import android.widget.Switch;
-import android.widget.TextView;
import android.widget.Toast;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
* This fragment provides UI and functionality to set restrictions on the AppRestrictionSchema
* sample.
*/
-public class AppRestrictionEnforcerFragment extends Fragment implements View.OnClickListener,
- CompoundButton.OnCheckedChangeListener {
-
- /**
- * Package name of the AppRestrictionSchema sample.
- */
- private static final String PACKAGE_NAME_APP_RESTRICTION_SCHEMA
- = "com.example.android.apprestrictionschema";
+public class AppRestrictionEnforcerFragment extends Fragment implements
+ CompoundButton.OnCheckedChangeListener, AdapterView.OnItemSelectedListener {
/**
* Key for {@link SharedPreferences}
@@ -62,15 +62,38 @@ public class AppRestrictionEnforcerFragment extends Fragment implements View.OnC
private static final String RESTRICTION_KEY_SAY_HELLO = "can_say_hello";
/**
- * Default boolean value for "can_say_hello" restriction. The actual value is loaded in
- * {@link #loadRestrictions(android.app.Activity)}.
+ * Key for the string restriction in AppRestrictionSchema.
+ */
+ private static final String RESTRICTION_KEY_MESSAGE = "message";
+
+ /**
+ * Key for the integer restriction in AppRestrictionSchema.
+ */
+ private static final String RESTRICTION_KEY_NUMBER = "number";
+
+ /**
+ * Key for the choice restriction in AppRestrictionSchema.
+ */
+ private static final String RESTRICTION_KEY_RANK = "rank";
+
+ /**
+ * Key for the multi-select restriction in AppRestrictionSchema.
*/
- private boolean mDefaultValueRestrictionSayHello;
+ private static final String RESTRICTION_KEY_APPROVALS = "approvals";
+
+ private static final String DELIMETER = ",";
+
+ /**
+ * Current status of the restrictions.
+ */
+ private Bundle mCurrentRestrictions = new Bundle();
// UI Components
- private TextView mTextStatus;
- private Button mButtonUnhide;
private Switch mSwitchSayHello;
+ private EditText mEditMessage;
+ private EditText mEditNumber;
+ private Spinner mSpinnerRank;
+ private LinearLayout mLayoutApprovals;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@@ -80,152 +103,262 @@ public class AppRestrictionEnforcerFragment extends Fragment implements View.OnC
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
- mTextStatus = (TextView) view.findViewById(R.id.status);
- mButtonUnhide = (Button) view.findViewById(R.id.unhide);
+ // Retain references for the UI elements
mSwitchSayHello = (Switch) view.findViewById(R.id.say_hello);
- mButtonUnhide.setOnClickListener(this);
- mSwitchSayHello.setOnCheckedChangeListener(this);
+ mEditMessage = (EditText) view.findViewById(R.id.message);
+ mEditNumber = (EditText) view.findViewById(R.id.number);
+ mSpinnerRank = (Spinner) view.findViewById(R.id.rank);
+ mLayoutApprovals = (LinearLayout) view.findViewById(R.id.approvals);
}
@Override
public void onResume() {
super.onResume();
- updateUi(getActivity());
+ loadRestrictions(getActivity());
}
@Override
- public void onClick(View view) {
- switch (view.getId()) {
- case R.id.unhide: {
- unhideApp(getActivity());
+ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
+ switch (compoundButton.getId()) {
+ case R.id.say_hello: {
+ saveCanSayHello(getActivity(), checked);
+ break;
+ }
+ case R.id.approval: {
+ if (checked) {
+ addApproval(getActivity(), (String) compoundButton.getTag());
+ } else {
+ removeApproval(getActivity(), (String) compoundButton.getTag());
+ }
break;
}
}
}
+ private TextWatcher mWatcherMessage = new EasyTextWatcher() {
+ @Override
+ public void afterTextChanged(Editable s) {
+ saveMessage(getActivity(), s.toString());
+ }
+ };
+
+ private TextWatcher mWatcherNumber = new EasyTextWatcher() {
+ @Override
+ public void afterTextChanged(Editable s) {
+ try {
+ String string = s.toString();
+ if (!TextUtils.isEmpty(string)) {
+ saveNumber(getActivity(), Integer.parseInt(string));
+ }
+ } catch (NumberFormatException e) {
+ Toast.makeText(getActivity(), "Not an integer!", Toast.LENGTH_SHORT).show();
+ }
+ }
+ };
+
@Override
- public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
- switch (compoundButton.getId()) {
- case R.id.say_hello: {
- allowSayHello(getActivity(), checked);
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ switch (parent.getId()) {
+ case R.id.rank: {
+ saveRank(getActivity(), (String) parent.getAdapter().getItem(position));
break;
}
}
}
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ // Nothing to do
+ }
+
/**
- * Updates the UI components according to the current status of AppRestrictionSchema and its
- * restriction.
+ * Loads the restrictions for the AppRestrictionSchema sample. In this implementation, we just
+ * read the default value for the "can_say_hello" restriction.
*
* @param activity The activity
*/
- private void updateUi(Activity activity) {
- PackageManager packageManager = activity.getPackageManager();
- try {
- ApplicationInfo info = packageManager.getApplicationInfo(
- PACKAGE_NAME_APP_RESTRICTION_SCHEMA, PackageManager.GET_UNINSTALLED_PACKAGES);
- DevicePolicyManager devicePolicyManager =
- (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
- if (0 < (info.flags & ApplicationInfo.FLAG_INSTALLED)) {
- if (!devicePolicyManager.isApplicationHidden(
- EnforcerDeviceAdminReceiver.getComponentName(activity),
- PACKAGE_NAME_APP_RESTRICTION_SCHEMA)) {
- // The app is ready
- loadRestrictions(activity);
- mTextStatus.setVisibility(View.GONE);
- mButtonUnhide.setVisibility(View.GONE);
- mSwitchSayHello.setVisibility(View.VISIBLE);
- mSwitchSayHello.setOnCheckedChangeListener(null);
- mSwitchSayHello.setChecked(canSayHello(activity));
- mSwitchSayHello.setOnCheckedChangeListener(this);
- } else {
- // The app is installed but hidden in this profile
- mTextStatus.setText(R.string.status_not_activated);
- mTextStatus.setVisibility(View.VISIBLE);
- mButtonUnhide.setVisibility(View.VISIBLE);
- mSwitchSayHello.setVisibility(View.GONE);
- }
- } else {
- // Need to reinstall the sample app
- mTextStatus.setText(R.string.status_need_reinstall);
- mTextStatus.setVisibility(View.VISIBLE);
- mButtonUnhide.setVisibility(View.GONE);
- mSwitchSayHello.setVisibility(View.GONE);
+ private void loadRestrictions(Activity activity) {
+ RestrictionsManager manager =
+ (RestrictionsManager) activity.getSystemService(Context.RESTRICTIONS_SERVICE);
+ List<RestrictionEntry> restrictions =
+ manager.getManifestRestrictions(Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA);
+ SharedPreferences prefs = activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
+ for (RestrictionEntry restriction : restrictions) {
+ String key = restriction.getKey();
+ if (RESTRICTION_KEY_SAY_HELLO.equals(key)) {
+ updateCanSayHello(prefs.getBoolean(RESTRICTION_KEY_SAY_HELLO,
+ restriction.getSelectedState()));
+ } else if (RESTRICTION_KEY_MESSAGE.equals(key)) {
+ updateMessage(prefs.getString(RESTRICTION_KEY_MESSAGE,
+ restriction.getSelectedString()));
+ } else if (RESTRICTION_KEY_NUMBER.equals(key)) {
+ updateNumber(prefs.getInt(RESTRICTION_KEY_NUMBER,
+ restriction.getIntValue()));
+ } else if (RESTRICTION_KEY_RANK.equals(key)) {
+ updateRank(activity, restriction.getChoiceValues(),
+ prefs.getString(RESTRICTION_KEY_RANK, restriction.getSelectedString()));
+ } else if (RESTRICTION_KEY_APPROVALS.equals(key)) {
+ updateApprovals(activity, restriction.getChoiceValues(),
+ TextUtils.split(prefs.getString(RESTRICTION_KEY_APPROVALS,
+ TextUtils.join(DELIMETER,
+ restriction.getAllSelectedStrings())),
+ DELIMETER));
}
- } catch (PackageManager.NameNotFoundException e) {
- mTextStatus.setText(R.string.status_not_installed);
- mTextStatus.setVisibility(View.VISIBLE);
- mButtonUnhide.setVisibility(View.GONE);
- mSwitchSayHello.setVisibility(View.GONE);
+ }
+ }
+
+ private void updateCanSayHello(boolean canSayHello) {
+ mCurrentRestrictions.putBoolean(RESTRICTION_KEY_SAY_HELLO, canSayHello);
+ mSwitchSayHello.setOnCheckedChangeListener(null);
+ mSwitchSayHello.setChecked(canSayHello);
+ mSwitchSayHello.setOnCheckedChangeListener(this);
+ }
+
+ private void updateMessage(String message) {
+ mCurrentRestrictions.putString(RESTRICTION_KEY_MESSAGE, message);
+ mEditMessage.removeTextChangedListener(mWatcherMessage);
+ mEditMessage.setText(message);
+ mEditMessage.addTextChangedListener(mWatcherMessage);
+ }
+
+ private void updateNumber(int number) {
+ mCurrentRestrictions.putInt(RESTRICTION_KEY_NUMBER, number);
+ mEditNumber.removeTextChangedListener(mWatcherNumber);
+ mEditNumber.setText(String.valueOf(number));
+ mEditNumber.addTextChangedListener(mWatcherNumber);
+ }
+
+ private void updateRank(Context context, String[] ranks, String selectedRank) {
+ mCurrentRestrictions.putString(RESTRICTION_KEY_RANK, selectedRank);
+ mSpinnerRank.setAdapter(new ArrayAdapter<>(context,
+ android.R.layout.simple_spinner_dropdown_item, ranks));
+ mSpinnerRank.setSelection(search(ranks, selectedRank));
+ mSpinnerRank.setOnItemSelectedListener(this);
+ }
+
+ private void updateApprovals(Context context, String[] approvals,
+ String[] selectedApprovals) {
+ mCurrentRestrictions.putStringArray(RESTRICTION_KEY_APPROVALS, selectedApprovals);
+ mLayoutApprovals.removeAllViews();
+ for (String approval : approvals) {
+ Switch sw = new Switch(context);
+ sw.setText(approval);
+ sw.setTag(approval);
+ sw.setChecked(Arrays.asList(selectedApprovals).contains(approval));
+ sw.setOnCheckedChangeListener(this);
+ sw.setId(R.id.approval);
+ mLayoutApprovals.addView(sw);
}
}
/**
- * Unhides the AppRestrictionSchema sample in case it is hidden in this profile.
+ * Saves the value for the "cay_say_hello" restriction of AppRestrictionSchema.
*
* @param activity The activity
+ * @param allow The value to be set for the restriction.
*/
- private void unhideApp(Activity activity) {
- DevicePolicyManager devicePolicyManager =
- (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
- devicePolicyManager.setApplicationHidden(
- EnforcerDeviceAdminReceiver.getComponentName(activity),
- PACKAGE_NAME_APP_RESTRICTION_SCHEMA, false);
- Toast.makeText(activity, "Enabled the app", Toast.LENGTH_SHORT).show();
- updateUi(activity);
+ private void saveCanSayHello(Activity activity, boolean allow) {
+ mCurrentRestrictions.putBoolean(RESTRICTION_KEY_SAY_HELLO, allow);
+ saveRestrictions(activity);
+ // Note that the owner app needs to remember the restrictions on its own.
+ editPreferences(activity).putBoolean(RESTRICTION_KEY_SAY_HELLO, allow).apply();
}
/**
- * Loads the restrictions for the AppRestrictionSchema sample. In this implementation, we just
- * read the default value for the "can_say_hello" restriction.
+ * Saves the value for the "message" restriction of AppRestrictionSchema.
*
* @param activity The activity
+ * @param message The value to be set for the restriction.
*/
- private void loadRestrictions(Activity activity) {
- RestrictionsManager restrictionsManager =
- (RestrictionsManager) activity.getSystemService(Context.RESTRICTIONS_SERVICE);
- List<RestrictionEntry> restrictions =
- restrictionsManager.getManifestRestrictions(PACKAGE_NAME_APP_RESTRICTION_SCHEMA);
- for (RestrictionEntry restriction : restrictions) {
- if (RESTRICTION_KEY_SAY_HELLO.equals(restriction.getKey())) {
- mDefaultValueRestrictionSayHello = restriction.getSelectedState();
- }
- }
+ private void saveMessage(Activity activity, String message) {
+ mCurrentRestrictions.putString(RESTRICTION_KEY_MESSAGE, message);
+ saveRestrictions(activity);
+ editPreferences(activity).putString(RESTRICTION_KEY_MESSAGE, message).apply();
}
/**
- * Returns whether the AppRestrictionSchema is currently allowed to say hello to its user. Note
- * that a profile/device owner needs to remember each restriction value on its own.
+ * Saves the value for the "number" restriction of AppRestrictionSchema.
*
* @param activity The activity
- * @return True if the AppRestrictionSchema is allowed to say hello
+ * @param number The value to be set for the restriction.
*/
- private boolean canSayHello(Activity activity) {
- SharedPreferences prefs = activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
- return prefs.getBoolean(RESTRICTION_KEY_SAY_HELLO, mDefaultValueRestrictionSayHello);
+ private void saveNumber(Activity activity, int number) {
+ mCurrentRestrictions.putInt(RESTRICTION_KEY_NUMBER, number);
+ saveRestrictions(activity);
+ editPreferences(activity).putInt(RESTRICTION_KEY_NUMBER, number).apply();
}
/**
- * Sets the value for the "cay_say_hello" restriction of AppRestrictionSchema.
+ * Saves the value for the "rank" restriction of AppRestrictionSchema.
*
* @param activity The activity
- * @param allow The value to be set for the restriction.
+ * @param rank The value to be set for the restriction.
*/
- private void allowSayHello(Activity activity, boolean allow) {
+ private void saveRank(Activity activity, String rank) {
+ mCurrentRestrictions.putString(RESTRICTION_KEY_RANK, rank);
+ saveRestrictions(activity);
+ editPreferences(activity).putString(RESTRICTION_KEY_RANK, rank).apply();
+ }
+
+ private void addApproval(Activity activity, String approval) {
+ List<String> approvals = new ArrayList<>(Arrays.asList(
+ mCurrentRestrictions.getStringArray(RESTRICTION_KEY_APPROVALS)));
+ if (approvals.contains(approval)) {
+ return;
+ }
+ approvals.add(approval);
+ saveApprovals(activity, approvals.toArray(new String[approvals.size()]));
+ }
+
+ private void removeApproval(Activity activity, String approval) {
+ List<String> approvals = new ArrayList<>(Arrays.asList(
+ mCurrentRestrictions.getStringArray(RESTRICTION_KEY_APPROVALS)));
+ if (!approval.contains(approval)) {
+ return;
+ }
+ approvals.remove(approval);
+ saveApprovals(activity, approvals.toArray(new String[approvals.size()]));
+ }
+
+ /**
+ * Saves the value for the "approvals" restriction of AppRestrictionSchema.
+ *
+ * @param activity The activity
+ * @param approvals The value to be set for the restriction.
+ */
+ private void saveApprovals(Activity activity, String[] approvals) {
+ mCurrentRestrictions.putStringArray(RESTRICTION_KEY_APPROVALS, approvals);
+ saveRestrictions(activity);
+ editPreferences(activity).putString(RESTRICTION_KEY_APPROVALS,
+ TextUtils.join(DELIMETER, approvals)).apply();
+ }
+
+ private void saveRestrictions(Activity activity) {
DevicePolicyManager devicePolicyManager
= (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
- Bundle restrictions = new Bundle();
- restrictions.putBoolean(RESTRICTION_KEY_SAY_HELLO, allow);
devicePolicyManager.setApplicationRestrictions(
EnforcerDeviceAdminReceiver.getComponentName(activity),
- PACKAGE_NAME_APP_RESTRICTION_SCHEMA, restrictions);
- // The profile/device owner needs to remember the current state of restrictions on its own
- activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
- .edit()
- .putBoolean(RESTRICTION_KEY_SAY_HELLO, allow)
- .apply();
- Toast.makeText(activity, allow ? R.string.allowed : R.string.disallowed,
- Toast.LENGTH_SHORT).show();
+ Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA, mCurrentRestrictions);
+ }
+
+ private SharedPreferences.Editor editPreferences(Activity activity) {
+ return activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE).edit();
+ }
+
+ /**
+ * Sequential search
+ *
+ * @param array The string array
+ * @param s The string to search for
+ * @return Index if found. -1 if not found.
+ */
+ private int search(String[] array, String s) {
+ for (int i = 0; i < array.length; ++i) {
+ if (s.equals(array[i])) {
+ return i;
+ }
+ }
+ return -1;
}
}
diff --git a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/Constants.java b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/Constants.java
new file mode 100644
index 00000000..bb4e958c
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/Constants.java
@@ -0,0 +1,27 @@
+/*
+ * 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.apprestrictionenforcer;
+
+public interface Constants {
+
+ /**
+ * Package name of the AppRestrictionSchema sample.
+ */
+ public static final String PACKAGE_NAME_APP_RESTRICTION_SCHEMA
+ = "com.example.android.apprestrictionschema";
+
+}
diff --git a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/EasyTextWatcher.java b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/EasyTextWatcher.java
new file mode 100644
index 00000000..8e0abb44
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/EasyTextWatcher.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.apprestrictionenforcer;
+
+import android.text.TextWatcher;
+
+/**
+ * This is a wrapper around {@link TextWatcher} that overrides
+ * {@link TextWatcher#beforeTextChanged(CharSequence, int, int, int)} and
+ * {@link TextWatcher#onTextChanged(CharSequence, int, int, int)} with empty bodies.
+ */
+public abstract class EasyTextWatcher implements TextWatcher {
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // Do nothing
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ // Do nothing
+ }
+
+}
diff --git a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/MainActivity.java b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/MainActivity.java
index 72224e17..c6b012be 100644
--- a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/MainActivity.java
+++ b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/MainActivity.java
@@ -18,24 +18,44 @@ package com.example.android.apprestrictionenforcer;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
-public class MainActivity extends FragmentActivity {
+public class MainActivity extends FragmentActivity implements StatusFragment.StatusUpdatedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_real);
if (null == savedInstanceState) {
- DevicePolicyManager manager = (DevicePolicyManager)
- getSystemService(Context.DEVICE_POLICY_SERVICE);
- if (manager.isProfileOwnerApp(getApplicationContext().getPackageName())) {
- // If the managed profile is already set up, we show the main screen.
- showMainFragment();
- } else {
- // If not, we show the set up screen.
+ DevicePolicyManager devicePolicyManager =
+ (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+ PackageManager packageManager = getPackageManager();
+ if (!devicePolicyManager.isProfileOwnerApp(getApplicationContext().getPackageName())) {
+ // If the managed profile is not yet set up, we show the setup screen.
showSetupProfile();
+ } else {
+ try {
+ ApplicationInfo info = packageManager.getApplicationInfo(
+ Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA,
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ if (0 == (info.flags & ApplicationInfo.FLAG_INSTALLED)) {
+ // Need to reinstall the sample app
+ showStatusProfile();
+ } else if (devicePolicyManager.isApplicationHidden(
+ EnforcerDeviceAdminReceiver.getComponentName(this),
+ Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA)) {
+ // The app is installed but hidden in this profile
+ showStatusProfile();
+ } else {
+ // Everything is clear; show the main screen
+ showMainFragment();
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ showStatusProfile();
+ }
}
}
}
@@ -46,10 +66,21 @@ public class MainActivity extends FragmentActivity {
.commit();
}
+ private void showStatusProfile() {
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.container, new StatusFragment())
+ .commit();
+ }
+
private void showMainFragment() {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new AppRestrictionEnforcerFragment())
.commit();
}
+ @Override
+ public void onStatusUpdated() {
+ showMainFragment();
+ }
+
}
diff --git a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/StatusFragment.java b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/StatusFragment.java
new file mode 100644
index 00000000..f4a4eb79
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/java/com/example/android/apprestrictionenforcer/StatusFragment.java
@@ -0,0 +1,136 @@
+/*
+ * 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.apprestrictionenforcer;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/**
+ * Provides UI for enabling the target app in this profile. The status of the app can be
+ * uninstalled, hidden, or enabled depending on the situations. This fragment shows suitable
+ * controls for each status.
+ */
+public class StatusFragment extends Fragment implements View.OnClickListener {
+
+ private TextView mTextStatus;
+ private Button mButtonUnhide;
+ private StatusUpdatedListener mListener;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_status, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ mTextStatus = (TextView) view.findViewById(R.id.status);
+ mButtonUnhide = (Button) view.findViewById(R.id.unhide);
+ mButtonUnhide.setOnClickListener(this);
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ mListener = (StatusUpdatedListener) activity;
+ }
+
+ @Override
+ public void onDetach() {
+ mListener = null;
+ super.onDetach();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateUi(getActivity());
+ }
+
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.unhide: {
+ unhideApp(getActivity());
+ break;
+ }
+ }
+ }
+
+ private void updateUi(Activity activity) {
+ PackageManager packageManager = activity.getPackageManager();
+ try {
+ ApplicationInfo info = packageManager.getApplicationInfo(
+ Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA,
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ DevicePolicyManager devicePolicyManager =
+ (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
+ if ((info.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
+ if (!devicePolicyManager.isApplicationHidden(
+ EnforcerDeviceAdminReceiver.getComponentName(activity),
+ Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA)) {
+ // The app is ready to enforce restrictions
+ // This is unlikely to happen in this sample as unhideApp() handles it.
+ mListener.onStatusUpdated();
+ } else {
+ // The app is installed but hidden in this profile
+ mTextStatus.setText(R.string.status_not_activated);
+ mButtonUnhide.setVisibility(View.VISIBLE);
+ }
+ } else {
+ // Need to reinstall the sample app
+ mTextStatus.setText(R.string.status_need_reinstall);
+ mButtonUnhide.setVisibility(View.GONE);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // Need to reinstall the sample app
+ mTextStatus.setText(R.string.status_need_reinstall);
+ mButtonUnhide.setVisibility(View.GONE);
+ }
+ }
+
+ /**
+ * Unhides the AppRestrictionSchema sample in case it is hidden in this profile.
+ *
+ * @param activity The activity
+ */
+ private void unhideApp(Activity activity) {
+ DevicePolicyManager devicePolicyManager =
+ (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
+ devicePolicyManager.setApplicationHidden(
+ EnforcerDeviceAdminReceiver.getComponentName(activity),
+ Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA, false);
+ Toast.makeText(activity, "Enabled the app", Toast.LENGTH_SHORT).show();
+ mListener.onStatusUpdated();
+ }
+
+ public interface StatusUpdatedListener {
+ public void onStatusUpdated();
+ }
+
+}
diff --git a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_app_restriction_enforcer.xml b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_app_restriction_enforcer.xml
index e6c50a24..01181916 100644
--- a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_app_restriction_enforcer.xml
+++ b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_app_restriction_enforcer.xml
@@ -14,31 +14,111 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:paddingBottom="@dimen/vertical_page_margin"
- android:paddingLeft="@dimen/horizontal_page_margin"
- android:paddingRight="@dimen/horizontal_page_margin"
- android:paddingTop="@dimen/vertical_page_margin">
-
- <TextView
- android:id="@+id/status"
+ android:layout_height="match_parent">
+
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/status_not_installed" />
+ android:orientation="vertical"
+ android:paddingBottom="@dimen/vertical_page_margin"
+ android:paddingLeft="@dimen/horizontal_page_margin"
+ android:paddingRight="@dimen/horizontal_page_margin"
+ android:paddingTop="@dimen/vertical_page_margin">
- <Button
- android:id="@+id/unhide"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/unhide" />
- <Switch
- android:id="@+id/say_hello"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/allow_saying_hello" />
+ <Switch
+ android:id="@+id/say_hello"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/allow_saying_hello"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:labelFor="@id/message"
+ android:text="@string/message"/>
+
+ <EditText
+ android:id="@id/message"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:inputType="text"
+ android:maxLines="1"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:labelFor="@id/number"
+ android:text="@string/number"/>
+
+ <EditText
+ android:id="@id/number"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:inputType="number"
+ android:maxLines="1"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/rank"/>
+
+ <Spinner
+ android:id="@+id/rank"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/margin_small"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/approvals"/>
+
+ <LinearLayout
+ android:id="@+id/approvals"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/margin_small"
+ android:orientation="vertical"/>
+
+ </LinearLayout>
+
+ </LinearLayout>
-</LinearLayout>
+</ScrollView>
diff --git a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_status.xml b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_status.xml
new file mode 100644
index 00000000..a2d60eb7
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/fragment_status.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="@dimen/vertical_page_margin"
+ android:paddingLeft="@dimen/horizontal_page_margin"
+ android:paddingRight="@dimen/horizontal_page_margin"
+ android:paddingTop="@dimen/vertical_page_margin">
+
+ <TextView
+ android:id="@+id/status"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/status_not_installed"/>
+
+ <Button
+ android:id="@+id/unhide"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/unhide"/>
+
+</LinearLayout>
diff --git a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/separator.xml b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/separator.xml
new file mode 100644
index 00000000..6927d801
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/layout/separator.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginBottom="@dimen/margin_medium"
+ android:layout_marginTop="@dimen/margin_medium"
+ android:background="#9000"/>
diff --git a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/values/ids.xml b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/values/ids.xml
new file mode 100644
index 00000000..04ba4ec2
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/values/ids.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+<resources>
+ <item name="message" type="id"/>
+ <item name="number" type="id"/>
+ <item name="approval" type="id"/>
+</resources>
diff --git a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/values/strings.xml b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/values/strings.xml
index 3029e046..e35daee3 100644
--- a/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/values/strings.xml
+++ b/prebuilts/gradle/AppRestrictionEnforcer/Application/src/main/res/values/strings.xml
@@ -25,4 +25,8 @@
<string name="allowed">Allowed</string>
<string name="disallowed">Disallowed</string>
<string name="profile_name">AppRestrictionEnforcer </string>
+ <string name="message">Message: </string>
+ <string name="number">Number: </string>
+ <string name="rank">Rank: </string>
+ <string name="approvals">Approvals: </string>
</resources>
diff --git a/prebuilts/gradle/AppRestrictionEnforcer/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/AppRestrictionEnforcer/gradle/wrapper/gradle-wrapper.properties
index 0c71e760..f2e517b2 100644
--- a/prebuilts/gradle/AppRestrictionEnforcer/gradle/wrapper/gradle-wrapper.properties
+++ b/prebuilts/gradle/AppRestrictionEnforcer/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Wed Apr 10 15:27:10 PDT 2013
+#Mon Dec 01 16:00:44 JST 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
diff --git a/prebuilts/gradle/AppRestrictionSchema/Application/build.gradle b/prebuilts/gradle/AppRestrictionSchema/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/AppRestrictionSchema/Application/build.gradle
+++ b/prebuilts/gradle/AppRestrictionSchema/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/AppRestrictionSchema/Application/src/main/java/com/example/android/apprestrictionschema/AppRestrictionSchemaFragment.java b/prebuilts/gradle/AppRestrictionSchema/Application/src/main/java/com/example/android/apprestrictionschema/AppRestrictionSchemaFragment.java
index 76f024f3..7b8dba83 100644
--- a/prebuilts/gradle/AppRestrictionSchema/Application/src/main/java/com/example/android/apprestrictionschema/AppRestrictionSchemaFragment.java
+++ b/prebuilts/gradle/AppRestrictionSchema/Application/src/main/java/com/example/android/apprestrictionschema/AppRestrictionSchemaFragment.java
@@ -17,10 +17,12 @@
package com.example.android.apprestrictionschema;
import android.content.Context;
+import android.content.RestrictionEntry;
import android.content.RestrictionsManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
+import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -30,6 +32,8 @@ import android.widget.Toast;
import com.example.android.common.logger.Log;
+import java.util.List;
+
/**
* Pressing the button on this fragment pops up a simple Toast message. The button is enabled or
* disabled according to the restrictions set by device/profile owner. You can use the
@@ -40,9 +44,21 @@ public class AppRestrictionSchemaFragment extends Fragment implements View.OnCli
// Tag for the logger
private static final String TAG = "AppRestrictionSchemaFragment";
+ private static final String KEY_CAN_SAY_HELLO = "can_say_hello";
+ private static final String KEY_MESSAGE = "message";
+ private static final String KEY_NUMBER = "number";
+ private static final String KEY_RANK = "rank";
+ private static final String KEY_APPROVALS = "approvals";
+
+ // Message to show when the button is clicked (String restriction)
+ private String mMessage;
+
// UI Components
private TextView mTextSayHello;
private Button mButtonSayHello;
+ private TextView mTextNumber;
+ private TextView mTextRank;
+ private TextView mTextApprovals;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@@ -54,48 +70,103 @@ public class AppRestrictionSchemaFragment extends Fragment implements View.OnCli
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
mTextSayHello = (TextView) view.findViewById(R.id.say_hello_explanation);
mButtonSayHello = (Button) view.findViewById(R.id.say_hello);
+ mTextNumber = (TextView) view.findViewById(R.id.your_number);
+ mTextRank = (TextView) view.findViewById(R.id.your_rank);
+ mTextApprovals = (TextView) view.findViewById(R.id.approvals_you_have);
mButtonSayHello.setOnClickListener(this);
}
@Override
public void onResume() {
super.onResume();
- // Update the UI according to the configured restrictions
- RestrictionsManager restrictionsManager =
+ resolveRestrictions();
+ }
+
+ private void resolveRestrictions() {
+ RestrictionsManager manager =
(RestrictionsManager) getActivity().getSystemService(Context.RESTRICTIONS_SERVICE);
- Bundle restrictions = restrictionsManager.getApplicationRestrictions();
- updateUI(restrictions);
+ Bundle restrictions = manager.getApplicationRestrictions();
+ List<RestrictionEntry> entries = manager.getManifestRestrictions(getActivity().getApplicationContext().getPackageName());
+ for (RestrictionEntry entry : entries) {
+ String key = entry.getKey();
+ Log.d(TAG, "key: " + key);
+ if (key.equals(KEY_CAN_SAY_HELLO)) {
+ updateCanSayHello(entry, restrictions);
+ } else if (key.equals(KEY_MESSAGE)) {
+ updateMessage(entry, restrictions);
+ } else if (key.equals(KEY_NUMBER)) {
+ updateNumber(entry, restrictions);
+ } else if (key.equals(KEY_RANK)) {
+ updateRank(entry, restrictions);
+ } else if (key.equals(KEY_APPROVALS)) {
+ updateApprovals(entry, restrictions);
+ }
+ }
+ }
+
+ private void updateCanSayHello(RestrictionEntry entry, Bundle restrictions) {
+ boolean canSayHello;
+ if (restrictions == null || !restrictions.containsKey(KEY_CAN_SAY_HELLO)) {
+ canSayHello = entry.getSelectedState();
+ } else {
+ canSayHello = restrictions.getBoolean(KEY_CAN_SAY_HELLO);
+ }
+ mTextSayHello.setText(canSayHello ?
+ R.string.explanation_can_say_hello_true :
+ R.string.explanation_can_say_hello_false);
+ mButtonSayHello.setEnabled(canSayHello);
}
- private void updateUI(Bundle restrictions) {
- if (canSayHello(restrictions)) {
- mTextSayHello.setText(R.string.explanation_can_say_hello_true);
- mButtonSayHello.setEnabled(true);
+ private void updateMessage(RestrictionEntry entry, Bundle restrictions) {
+ if (restrictions == null || !restrictions.containsKey(KEY_MESSAGE)) {
+ mMessage = entry.getSelectedString();
} else {
- mTextSayHello.setText(R.string.explanation_can_say_hello_false);
- mButtonSayHello.setEnabled(false);
+ mMessage = restrictions.getString(KEY_MESSAGE);
}
}
- /**
- * Returns the current status of the restriction.
- *
- * @param restrictions The application restrictions
- * @return True if the app is allowed to say hello
- */
- private boolean canSayHello(Bundle restrictions) {
- final boolean defaultValue = false;
- boolean canSayHello = restrictions == null ? defaultValue :
- restrictions.getBoolean("can_say_hello", defaultValue);
- Log.d(TAG, "canSayHello: " + canSayHello);
- return canSayHello;
+ private void updateNumber(RestrictionEntry entry, Bundle restrictions) {
+ int number;
+ if (restrictions == null || !restrictions.containsKey(KEY_NUMBER)) {
+ number = entry.getIntValue();
+ } else {
+ number = restrictions.getInt(KEY_NUMBER);
+ }
+ mTextNumber.setText(getString(R.string.your_number, number));
+ }
+
+ private void updateRank(RestrictionEntry entry, Bundle restrictions) {
+ String rank;
+ if (restrictions == null || !restrictions.containsKey(KEY_RANK)) {
+ rank = entry.getSelectedString();
+ } else {
+ rank = restrictions.getString(KEY_RANK);
+ }
+ mTextRank.setText(getString(R.string.your_rank, rank));
+ }
+
+ private void updateApprovals(RestrictionEntry entry, Bundle restrictions) {
+ String[] approvals;
+ if (restrictions == null || !restrictions.containsKey(KEY_APPROVALS)) {
+ approvals = entry.getAllSelectedStrings();
+ } else {
+ approvals = restrictions.getStringArray(KEY_APPROVALS);
+ }
+ String text;
+ if (approvals == null || approvals.length == 0) {
+ text = getString(R.string.none);
+ } else {
+ text = TextUtils.join(", ", approvals);
+ }
+ mTextApprovals.setText(getString(R.string.approvals_you_have, text));
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.say_hello: {
- Toast.makeText(getActivity(), R.string.message_hello, Toast.LENGTH_SHORT).show();
+ Toast.makeText(getActivity(), getString(R.string.message, mMessage),
+ Toast.LENGTH_SHORT).show();
break;
}
}
diff --git a/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/layout/fragment_app_restriction_schema.xml b/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/layout/fragment_app_restriction_schema.xml
index fc5e23dc..18ca0a4d 100644
--- a/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/layout/fragment_app_restriction_schema.xml
+++ b/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/layout/fragment_app_restriction_schema.xml
@@ -14,24 +14,60 @@ 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="vertical"
- android:padding="@dimen/margin_medium">
-
- <TextView
- android:id="@+id/say_hello_explanation"
+
+
+<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">
+
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/explanation_can_say_hello_true"
- android:textAppearance="?android:attr/textAppearanceMedium" />
+ android:orientation="vertical"
+ android:padding="@dimen/margin_medium">
- <Button
- android:id="@+id/say_hello"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/margin_medium"
- android:text="@string/action_can_say_hello" />
+ <TextView
+ android:id="@+id/say_hello_explanation"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ tools:text="@string/explanation_can_say_hello_true"/>
+
+ <Button
+ android:id="@+id/say_hello"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/margin_medium"
+ android:text="@string/action_can_say_hello"/>
+
+ <include layout="@layout/separator"/>
+
+ <TextView
+ android:id="@+id/your_number"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ tools:text="@string/your_number"/>
+
+ <include layout="@layout/separator"/>
+
+ <TextView
+ android:id="@+id/your_rank"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ tools:text="@string/your_rank"/>
+
+ <include layout="@layout/separator"/>
+
+ <TextView
+ android:id="@+id/approvals_you_have"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ tools:text="@string/approvals_you_have"/>
+
+ </LinearLayout>
-</LinearLayout>
+</ScrollView>
diff --git a/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/layout/separator.xml b/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/layout/separator.xml
new file mode 100644
index 00000000..6927d801
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/layout/separator.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginBottom="@dimen/margin_medium"
+ android:layout_marginTop="@dimen/margin_medium"
+ android:background="#9000"/>
diff --git a/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/values/restriction_values.xml b/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/values/restriction_values.xml
new file mode 100644
index 00000000..558d097f
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/values/restriction_values.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+<resources>
+
+ <!-- Bool restriction -->
+ <string name="title_can_say_hello">Can say hello</string>
+ <string name="description_can_say_hello">Whether the app can say hello to the user</string>
+ <bool name="default_can_say_hello">false</bool>
+
+ <!-- String restriction -->
+ <string name="title_message">Message</string>
+ <string name="description_message">A message string to show</string>
+ <string name="default_message">Hello!</string>
+
+ <!-- Integer restriction -->
+ <string name="title_number">Number</string>
+ <string name="description_number">Sample integer value</string>
+ <integer name="default_number">32582657</integer>
+
+ <!-- Choice restriction -->
+ <string name="title_rank">Rank</string>
+ <string name="description_rank">Rank of the user</string>
+ <string-array name="entries_rank">
+ <item>Apprentice</item>
+ <item>Intermediate</item>
+ <item>Master</item>
+ </string-array>
+ <string name="entry_value_rank_apprentice">apprentice</string>
+ <string name="entry_value_rank_intermediate">intermediate</string>
+ <string name="entry_value_rank_master">master</string>
+ <string-array name="entry_values_rank">
+ <item>@string/entry_value_rank_apprentice</item>
+ <item>@string/entry_value_rank_intermediate</item>
+ <item>@string/entry_value_rank_master</item>
+ </string-array>
+ <string name="default_rank">@string/entry_value_rank_apprentice</string>
+
+ <!-- Multi-select restriction -->
+ <string name="title_approvals">Approvals</string>
+ <string name="description_approvals">Approvals</string>
+ <string-array name="entries_approvals">
+ <item>Read</item>
+ <item>Write</item>
+ <item>Execute</item>
+ </string-array>
+ <string name="entry_value_approvals_read">read</string>
+ <string name="entry_value_approvals_write">write</string>
+ <string name="entry_value_approvals_execute">execute</string>
+ <string-array name="entry_values_approvals">
+ <item>@string/entry_value_approvals_read</item>
+ <item>@string/entry_value_approvals_write</item>
+ <item>@string/entry_value_approvals_execute</item>
+ </string-array>
+ <string-array name="default_approvals">
+ <!-- Empty -->
+ </string-array>
+
+ <!-- Hidden restriction -->
+ <string name="title_secret_code">Secret code</string>
+ <string name="description_secret_code">This restriction is hidden and will not be shown to the administrator.</string>
+ <string name="default_secret_code">(Hidden restriction must have some default value)</string>
+
+</resources>
diff --git a/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/values/strings.xml b/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/values/strings.xml
index b8ef110b..6dce123f 100644
--- a/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/values/strings.xml
+++ b/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/values/strings.xml
@@ -16,11 +16,14 @@ limitations under the License.
-->
<resources>
- <string name="title_can_say_hello">Can say hello</string>
- <string name="description_can_say_hello">Whether the app can say hello to the user</string>
<string name="explanation_can_say_hello_true">I can say hello to you.</string>
<string name="explanation_can_say_hello_false">I am restricted from saying hello to you.</string>
<string name="action_can_say_hello">Say hello</string>
- <string name="message_hello">Hello!</string>
+ <string name="message">All I can say is \"%s\".</string>
-</resources> \ No newline at end of file
+ <string name="your_number">Your number: %d</string>
+ <string name="your_rank">Your rank: %s</string>
+ <string name="approvals_you_have">Approvals you have: %s</string>
+ <string name="none">none</string>
+
+</resources>
diff --git a/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/xml/app_restrictions.xml b/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/xml/app_restrictions.xml
index 409527fc..9e47f458 100644
--- a/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/xml/app_restrictions.xml
+++ b/prebuilts/gradle/AppRestrictionSchema/Application/src/main/res/xml/app_restrictions.xml
@@ -16,11 +16,55 @@ limitations under the License.
-->
<restrictions xmlns:android="http://schemas.android.com/apk/res/android">
+ <!--
+ Refer to the javadoc of RestrictionsManager for detail of this file.
+ https://developer.android.com/reference/android/content/RestrictionsManager.html
+ -->
+
<restriction
- android:defaultValue="false"
+ android:defaultValue="@bool/default_can_say_hello"
android:description="@string/description_can_say_hello"
android:key="can_say_hello"
android:restrictionType="bool"
- android:title="@string/title_can_say_hello" />
+ android:title="@string/title_can_say_hello"/>
+
+ <restriction
+ android:defaultValue="@string/default_message"
+ android:description="@string/description_message"
+ android:key="message"
+ android:restrictionType="string"
+ android:title="@string/title_message"/>
+
+ <restriction
+ android:defaultValue="@integer/default_number"
+ android:description="@string/description_number"
+ android:key="number"
+ android:restrictionType="integer"
+ android:title="@string/title_number"/>
+
+ <restriction
+ android:defaultValue="@string/default_rank"
+ android:description="@string/description_rank"
+ android:entries="@array/entries_rank"
+ android:entryValues="@array/entry_values_rank"
+ android:key="rank"
+ android:restrictionType="choice"
+ android:title="@string/title_rank"/>
+
+ <restriction
+ android:defaultValue="@array/default_approvals"
+ android:description="@string/description_approvals"
+ android:entries="@array/entries_approvals"
+ android:entryValues="@array/entry_values_approvals"
+ android:key="approvals"
+ android:restrictionType="multi-select"
+ android:title="@string/title_approvals"/>
+
+ <restriction
+ android:defaultValue="@string/default_secret_code"
+ android:description="@string/description_secret_code"
+ android:key="secret_code"
+ android:restrictionType="hidden"
+ android:title="@string/title_secret_code"/>
</restrictions>
diff --git a/prebuilts/gradle/AppRestrictionSchema/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/AppRestrictionSchema/gradle/wrapper/gradle-wrapper.properties
index 0c71e760..fb79885e 100644
--- a/prebuilts/gradle/AppRestrictionSchema/gradle/wrapper/gradle-wrapper.properties
+++ b/prebuilts/gradle/AppRestrictionSchema/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Wed Apr 10 15:27:10 PDT 2013
+#Mon Dec 01 11:44:58 JST 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
diff --git a/prebuilts/gradle/AppRestrictions/Application/build.gradle b/prebuilts/gradle/AppRestrictions/Application/build.gradle
index f3cacbe1..3859b3ee 100644
--- a/prebuilts/gradle/AppRestrictions/Application/build.gradle
+++ b/prebuilts/gradle/AppRestrictions/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/AppUsageStatistics/.google/packaging.yaml b/prebuilts/gradle/AppUsageStatistics/.google/packaging.yaml
new file mode 100644
index 00000000..7e39ed2b
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/.google/packaging.yaml
@@ -0,0 +1,17 @@
+# GOOGLE SAMPLE PACKAGING DATA
+#
+# This file is used by Google as part of our samples packaging process.
+# End users may safely ignore this file. It has no relevance to other systems.
+---
+status: DRAFT
+technologies: [Android]
+categories: [System]
+languages: [Java]
+solutions: [Mobile]
+github: android-AppUsageStatistics
+level: INTERMEDIATE
+icon: screenshots/web-icon.png
+apiRefs:
+ - android:android.app.usage.UsageStats
+ - android:android.app.usage.UsageStatsManager
+license: apache2
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/build.gradle b/prebuilts/gradle/AppUsageStatistics/Application/build.gradle
new file mode 100644
index 00000000..aecc5fd6
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/build.gradle
@@ -0,0 +1,72 @@
+buildscript {
+ repositories {
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+ }
+}
+
+apply plugin: 'com.android.application'
+
+repositories {
+ jcenter()
+}
+
+
+dependencies {
+
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
+
+ compile "com.android.support:recyclerview-v7:+"
+ compile "com.android.support:appcompat-v7:21.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.1"
+
+ defaultConfig {
+ minSdkVersion 21
+ targetSdkVersion 21
+ }
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ androidTest.setRoot('tests')
+ androidTest.java.srcDirs = ['tests/src']
+
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/AndroidManifest.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..2726b4a2
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.appusagestatistics"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/Theme.AppCompat.Light">
+
+ <activity android:name=".AppUsageStatisticsActivity"
+ 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/prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/AppUsageStatisticsActivity.java b/prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/AppUsageStatisticsActivity.java
new file mode 100644
index 00000000..4def465f
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/AppUsageStatisticsActivity.java
@@ -0,0 +1,37 @@
+/*
+* 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.
+*/
+
+package com.example.android.appusagestatistics;
+
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+
+/**
+ * Launcher Activity for the App Usage Statistics sample app.
+ */
+public class AppUsageStatisticsActivity extends ActionBarActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_app_usage_statistics);
+ if (savedInstanceState == null) {
+ getSupportFragmentManager().beginTransaction()
+ .add(R.id.container, AppUsageStatisticsFragment.newInstance())
+ .commit();
+ }
+ }
+} \ No newline at end of file
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/AppUsageStatisticsFragment.java b/prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/AppUsageStatisticsFragment.java
new file mode 100644
index 00000000..50a72e77
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/AppUsageStatisticsFragment.java
@@ -0,0 +1,230 @@
+/*
+* 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.
+*/
+
+package com.example.android.appusagestatistics;
+
+import android.app.usage.UsageStats;
+import android.app.usage.UsageStatsManager;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.v4.app.Fragment;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.Spinner;
+import android.widget.SpinnerAdapter;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Fragment that demonstrates how to use App Usage Statistics API.
+ */
+public class AppUsageStatisticsFragment extends Fragment {
+
+ private static final String TAG = AppUsageStatisticsFragment.class.getSimpleName();
+
+ //VisibleForTesting for variables below
+ UsageStatsManager mUsageStatsManager;
+ UsageListAdapter mUsageListAdapter;
+ RecyclerView mRecyclerView;
+ RecyclerView.LayoutManager mLayoutManager;
+ Button mOpenUsageSettingButton;
+ Spinner mSpinner;
+
+ /**
+ * Use this factory method to create a new instance of
+ * this fragment using the provided parameters.
+ *
+ * @return A new instance of fragment {@link AppUsageStatisticsFragment}.
+ */
+ public static AppUsageStatisticsFragment newInstance() {
+ AppUsageStatisticsFragment fragment = new AppUsageStatisticsFragment();
+ return fragment;
+ }
+
+ public AppUsageStatisticsFragment() {
+ // Required empty public constructor
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mUsageStatsManager = (UsageStatsManager) getActivity()
+ .getSystemService("usagestats"); //Context.USAGE_STATS_SERVICE
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_app_usage_statistics, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View rootView, Bundle savedInstanceState) {
+ super.onViewCreated(rootView, savedInstanceState);
+
+ mLayoutManager = new LinearLayoutManager(getActivity());
+ mUsageListAdapter = new UsageListAdapter();
+ mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview_app_usage);
+ mRecyclerView.setLayoutManager(mLayoutManager);
+ mRecyclerView.scrollToPosition(0);
+ mRecyclerView.setAdapter(mUsageListAdapter);
+ mOpenUsageSettingButton = (Button) rootView.findViewById(R.id.button_open_usage_setting);
+ mSpinner = (Spinner) rootView.findViewById(R.id.spinner_time_span);
+ SpinnerAdapter spinnerAdapter = ArrayAdapter.createFromResource(getActivity(),
+ R.array.action_list, android.R.layout.simple_spinner_dropdown_item);
+ mSpinner.setAdapter(spinnerAdapter);
+ mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+
+ String[] strings = getResources().getStringArray(R.array.action_list);
+
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ StatsUsageInterval statsUsageInterval = StatsUsageInterval.getValue(strings[position]);
+ if (statsUsageInterval != null ) {
+ List<UsageStats> usageStatsList =
+ getUsageStatistics(statsUsageInterval.mInterval);
+ Collections.sort(usageStatsList, new LastTimeLaunchedComparatorDesc());
+ updateAppsList(usageStatsList);
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ }
+ });
+ getUsageStatistics(UsageStatsManager.INTERVAL_DAILY);
+ }
+
+ /**
+ * Returns the {@link #mRecyclerView} sorted by the timestamp of the last time used
+ * including the time span specified by the intervalType argument.
+ *
+ * @param intervalType The time interval by which the stats are aggregated.
+ * Corresponding to the value of {@link UsageStatsManager}.
+ * E.g. {@link UsageStatsManager#INTERVAL_DAILY}, {@link
+ * UsageStatsManager#INTERVAL_WEEKLY},
+ */
+ public List<UsageStats> getUsageStatistics(int intervalType) {
+ // Get the app statistics since one year ago from the current time.
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.YEAR, -1);
+
+ List<UsageStats> queryUsageStats = mUsageStatsManager
+ .queryUsageStats(intervalType, cal.getTimeInMillis(),
+ System.currentTimeMillis());
+
+ if (queryUsageStats.size() == 0) {
+ Log.i(TAG, "The user may not allow the access to apps usage. ");
+ Toast.makeText(getActivity(),
+ getString(R.string.explanation_access_to_appusage_is_not_enabled),
+ Toast.LENGTH_LONG).show();
+ mOpenUsageSettingButton.setVisibility(View.VISIBLE);
+ mOpenUsageSettingButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
+ }
+ });
+ }
+ return queryUsageStats;
+ }
+
+ /**
+ * Updates the {@link #mRecyclerView} with the list of {@link UsageStats} passed as an argument.
+ *
+ * @param usageStatsList A list of {@link UsageStats} from which update the
+ * {@link #mRecyclerView}.
+ */
+ void updateAppsList(List<UsageStats> usageStatsList) {
+ List<CustomUsageStats> customUsageStatsList = new ArrayList<>();
+ for (int i = 0; i < usageStatsList.size(); i++) {
+ CustomUsageStats customUsageStats = new CustomUsageStats();
+ customUsageStats.usageStats = usageStatsList.get(i);
+ try {
+ Drawable appIcon = getActivity().getPackageManager()
+ .getApplicationIcon(customUsageStats.usageStats.getPackageName());
+ customUsageStats.appIcon = appIcon;
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, String.format("App Icon is not found for %s",
+ customUsageStats.usageStats.getPackageName()));
+ customUsageStats.appIcon = getActivity()
+ .getDrawable(R.drawable.ic_default_app_launcher);
+ }
+ customUsageStatsList.add(customUsageStats);
+ }
+ mUsageListAdapter.setCustomUsageStatsList(customUsageStatsList);
+ mUsageListAdapter.notifyDataSetChanged();
+ mRecyclerView.scrollToPosition(0);
+ }
+
+ /**
+ * The {@link Comparator} to sort a collection of {@link UsageStats} sorted by the timestamp
+ * last time the app was used in the descendant order.
+ */
+ private static class LastTimeLaunchedComparatorDesc implements Comparator<UsageStats> {
+
+ @Override
+ public int compare(UsageStats left, UsageStats right) {
+ return (int) (right.getLastTimeUsed() - left.getLastTimeUsed());
+ }
+ }
+
+ /**
+ * Enum represents the intervals for {@link android.app.usage.UsageStatsManager} so that
+ * values for intervals can be found by a String representation.
+ *
+ */
+ //VisibleForTesting
+ static enum StatsUsageInterval {
+ DAILY("Daily", UsageStatsManager.INTERVAL_DAILY),
+ WEEKLY("Weekly", UsageStatsManager.INTERVAL_WEEKLY),
+ MONTHLY("Monthly", UsageStatsManager.INTERVAL_MONTHLY),
+ YEARLY("Yearly", UsageStatsManager.INTERVAL_YEARLY);
+
+ private int mInterval;
+ private String mStringRepresentation;
+
+ StatsUsageInterval(String stringRepresentation, int interval) {
+ mStringRepresentation = stringRepresentation;
+ mInterval = interval;
+ }
+
+ static StatsUsageInterval getValue(String stringRepresentation) {
+ for (StatsUsageInterval statsUsageInterval : values()) {
+ if (statsUsageInterval.mStringRepresentation.equals(stringRepresentation)) {
+ return statsUsageInterval;
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/CustomUsageStats.java b/prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/CustomUsageStats.java
new file mode 100644
index 00000000..b5b15c4e
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/CustomUsageStats.java
@@ -0,0 +1,28 @@
+/*
+* 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.
+*/
+
+package com.example.android.appusagestatistics;
+
+import android.app.usage.UsageStats;
+import android.graphics.drawable.Drawable;
+
+/**
+ * Entity class represents usage stats and app icon.
+ */
+public class CustomUsageStats {
+ public UsageStats usageStats;
+ public Drawable appIcon;
+}
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/UsageListAdapter.java b/prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/UsageListAdapter.java
new file mode 100644
index 00000000..ab1d0376
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/java/com/example/android/appusagestatistics/UsageListAdapter.java
@@ -0,0 +1,95 @@
+/*
+* 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.appusagestatistics;
+
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Provide views to RecyclerView with the directory entries.
+ */
+public class UsageListAdapter extends RecyclerView.Adapter<UsageListAdapter.ViewHolder> {
+
+ private List<CustomUsageStats> mCustomUsageStatsList = new ArrayList<>();
+ private DateFormat mDateFormat = new SimpleDateFormat();
+
+ /**
+ * Provide a reference to the type of views that you are using (custom ViewHolder)
+ */
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+ private final TextView mPackageName;
+ private final TextView mLastTimeUsed;
+ private final ImageView mAppIcon;
+
+ public ViewHolder(View v) {
+ super(v);
+ mPackageName = (TextView) v.findViewById(R.id.textview_package_name);
+ mLastTimeUsed = (TextView) v.findViewById(R.id.textview_last_time_used);
+ mAppIcon = (ImageView) v.findViewById(R.id.app_icon);
+ }
+
+ public TextView getLastTimeUsed() {
+ return mLastTimeUsed;
+ }
+
+ public TextView getPackageName() {
+ return mPackageName;
+ }
+
+ public ImageView getAppIcon() {
+ return mAppIcon;
+ }
+ }
+
+ public UsageListAdapter() {
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
+ View v = LayoutInflater.from(viewGroup.getContext())
+ .inflate(R.layout.usage_row, viewGroup, false);
+ return new ViewHolder(v);
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder viewHolder, final int position) {
+ viewHolder.getPackageName().setText(
+ mCustomUsageStatsList.get(position).usageStats.getPackageName());
+ long lastTimeUsed = mCustomUsageStatsList.get(position).usageStats.getLastTimeUsed();
+ viewHolder.getLastTimeUsed().setText(mDateFormat.format(new Date(lastTimeUsed)));
+ viewHolder.getAppIcon().setImageDrawable(mCustomUsageStatsList.get(position).appIcon);
+ }
+
+ @Override
+ public int getItemCount() {
+ return mCustomUsageStatsList.size();
+ }
+
+ public void setCustomUsageStatsList(List<CustomUsageStats> customUsageStats) {
+ mCustomUsageStatsList = customUsageStats;
+ }
+} \ No newline at end of file
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-hdpi/ic_default_app_launcher.png b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-hdpi/ic_default_app_launcher.png
new file mode 100644
index 00000000..96a442e5
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-hdpi/ic_default_app_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 00000000..3cf5e8b4
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 00000000..13586288
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-mdpi/ic_default_app_launcher.png b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-mdpi/ic_default_app_launcher.png
new file mode 100644
index 00000000..359047df
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-mdpi/ic_default_app_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 00000000..51553c5d
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xhdpi/ic_default_app_launcher.png b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xhdpi/ic_default_app_launcher.png
new file mode 100644
index 00000000..71c6d760
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xhdpi/ic_default_app_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 00000000..52480002
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xxhdpi/ic_default_app_launcher.png b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xxhdpi/ic_default_app_launcher.png
new file mode 100644
index 00000000..4df18946
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xxhdpi/ic_default_app_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 00000000..7f162009
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/activity_app_usage_statistics.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/activity_app_usage_statistics.xml
new file mode 100644
index 00000000..2627c8b7
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/activity_app_usage_statistics.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context="com.example.android.appusagestatistics.AppUsageStatisticsActivity"
+ tools:ignore="MergeRootFrame" />
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/activity_main.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/activity_main.xml
new file mode 100755
index 00000000..be1aa49d
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/fragment_app_usage_statistics.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/fragment_app_usage_statistics.xml
new file mode 100644
index 00000000..1d567b76
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/fragment_app_usage_statistics.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:gravity="center_vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="@dimen/margin_medium">
+
+ <Button android:id="@+id/button_open_usage_setting"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/open_app_usage_setting"
+ android:visibility="gone"
+ />
+
+ <LinearLayout android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/time_span"
+ />
+
+ <Spinner android:id="@+id/spinner_time_span"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ </LinearLayout>
+
+ <android.support.v7.widget.RecyclerView
+ android:id="@+id/recyclerview_app_usage"
+ android:layout_marginLeft="@dimen/margin_small"
+ android:layout_marginRight="@dimen/margin_small"
+ android:scrollbars="vertical"
+ android:drawSelectorOnTop="true"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+
+</LinearLayout>
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/usage_row.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/usage_row.xml
new file mode 100644
index 00000000..c16f039e
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/layout/usage_row.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/usage_row_height"
+ >
+
+ <LinearLayout android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_centerVertical="true"
+ android:gravity="center_vertical"
+ >
+ <ImageView android:id="@+id/app_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ />
+ <LinearLayout android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/margin_medium"
+ android:orientation="vertical"
+ >
+
+ <TextView
+ android:id="@+id/textview_package_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/PackageNameFont"
+ />
+
+ <LinearLayout android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+
+ <TextView
+ android:id="@+id/textview_last_time_used_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/last_time_used"
+ />
+
+ <TextView
+ android:id="@+id/textview_last_time_used"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ />
+ </LinearLayout>
+ </LinearLayout>
+ </LinearLayout>
+
+ <View android:id="@+id/divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="#bbbbbb"/>
+
+</RelativeLayout> \ No newline at end of file
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 00000000..22074a2b
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 00000000..03d19741
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-v11/template-styles.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-v11/template-styles.xml
new file mode 100644
index 00000000..8c1ea66f
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-v21/base-colors.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-v21/base-colors.xml
new file mode 100644
index 00000000..34c9cd13
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-v21/base-colors.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<resources>
+
+
+</resources>
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-v21/base-template-styles.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-v21/base-template-styles.xml
new file mode 100644
index 00000000..0b2948f7
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values-v21/base-template-styles.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<resources>
+
+ <!-- Activity themes -->
+ <style name="Theme.Base" parent="android:Theme.Material.Light">
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/base-strings.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/base-strings.xml
new file mode 100644
index 00000000..9a92da8c
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/base-strings.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<resources>
+ <string name="app_name">AppUsageStatistics</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample explains how to use App usage statistics API, which was introduced
+ in Android 5.0.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/dimens.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/dimens.xml
new file mode 100644
index 00000000..d1741c33
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<resources>
+ <dimen name="usage_row_height">72dp</dimen>
+</resources> \ No newline at end of file
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/navigation_items.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/navigation_items.xml
new file mode 100644
index 00000000..b36a4a58
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/navigation_items.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<resources>
+ <string-array name="action_list">
+ <item>Daily</item>
+ <item>Weekly</item>
+ <item>Monthly</item>
+ <item>Yearly</item>
+ </string-array>
+</resources> \ No newline at end of file
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/strings.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/strings.xml
new file mode 100644
index 00000000..2caaf900
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<resources>
+ <string name="open_app_usage_setting">Open Apps with usage access settings</string>
+ <string name="last_time_used">"Last time used: "</string>
+ <string name="time_span">"Time span: "</string>
+ <string name="explanation_access_to_appusage_is_not_enabled">Failed to retrieve app usage
+ statistics. You may need to enable access "
+ + "for this app through Settings > Security > Apps with usage access
+ </string>
+</resources>
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/styles.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/styles.xml
new file mode 100644
index 00000000..d4002764
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/styles.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<resources>
+ <style name="PackageNameFont" parent="@android:style/TextAppearance.Small">
+ <item name="android:textColor">#000000</item>
+ </style>
+</resources> \ No newline at end of file
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/template-dimens.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/template-dimens.xml
new file mode 100644
index 00000000..39e710b5
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/template-styles.xml b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/template-styles.xml
new file mode 100644
index 00000000..6e7d593d
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/tests/src/com/example/android/appusagestatistics/AppUsageStatisticsActivityTests.java b/prebuilts/gradle/AppUsageStatistics/Application/tests/src/com/example/android/appusagestatistics/AppUsageStatisticsActivityTests.java
new file mode 100644
index 00000000..f2e3ea91
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/tests/src/com/example/android/appusagestatistics/AppUsageStatisticsActivityTests.java
@@ -0,0 +1,70 @@
+/*
+* 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.
+*/
+/*
+* 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.appusagestatistics;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * Tests for {@link AppUsageStatisticsActivity}.
+ */
+public class AppUsageStatisticsActivityTests
+ extends ActivityInstrumentationTestCase2<AppUsageStatisticsActivity> {
+
+ private AppUsageStatisticsActivity mTestActivity;
+ private AppUsageStatisticsFragment mTestFragment;
+
+ public AppUsageStatisticsActivityTests() {
+ super(AppUsageStatisticsActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (AppUsageStatisticsFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(0);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+}
diff --git a/prebuilts/gradle/AppUsageStatistics/Application/tests/src/com/example/android/appusagestatistics/AppUsageStatisticsFragmentTests.java b/prebuilts/gradle/AppUsageStatistics/Application/tests/src/com/example/android/appusagestatistics/AppUsageStatisticsFragmentTests.java
new file mode 100644
index 00000000..d8adb1ce
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/Application/tests/src/com/example/android/appusagestatistics/AppUsageStatisticsFragmentTests.java
@@ -0,0 +1,97 @@
+/*
+* 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.
+*/
+
+package com.example.android.appusagestatistics;
+
+import com.example.android.appusagestatistics.AppUsageStatisticsFragment.StatsUsageInterval;
+
+import android.app.usage.UsageStats;
+import android.app.usage.UsageStatsManager;
+import android.test.ActivityInstrumentationTestCase2;
+
+import java.util.List;
+
+/**
+ * Tests for {@link com.example.android.appusagestatistics.AppUsageStatisticsFragment}.
+ */
+public class AppUsageStatisticsFragmentTests
+ extends ActivityInstrumentationTestCase2<AppUsageStatisticsActivity> {
+
+ private AppUsageStatisticsActivity mTestActivity;
+ private AppUsageStatisticsFragment mTestFragment;
+
+ public AppUsageStatisticsFragmentTests() {
+ super(AppUsageStatisticsActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (AppUsageStatisticsFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(0);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ assertNotNull(mTestFragment.mUsageStatsManager);
+ assertNotNull(mTestFragment.mUsageListAdapter);
+ assertNotNull(mTestFragment.mRecyclerView);
+ assertNotNull(mTestFragment.mLayoutManager);
+ assertNotNull(mTestFragment.mOpenUsageSettingButton);
+ assertNotNull(mTestFragment.mSpinner);
+ }
+
+ public void testStatsUsageInterval_getValue() {
+ assertTrue(StatsUsageInterval.DAILY == StatsUsageInterval.getValue("Daily"));
+ assertTrue(StatsUsageInterval.WEEKLY == StatsUsageInterval.getValue("Weekly"));
+ assertTrue(StatsUsageInterval.MONTHLY == StatsUsageInterval.getValue("Monthly"));
+ assertTrue(StatsUsageInterval.YEARLY == StatsUsageInterval.getValue("Yearly"));
+ assertNull(StatsUsageInterval.getValue("NonExistent"));
+ }
+
+ public void testGetUsageStatistics() {
+ List<UsageStats> usageStatsList = mTestFragment
+ .getUsageStatistics(UsageStatsManager.INTERVAL_DAILY);
+
+ // Whether the usageStatsList has any UsageStats depends on if the app is granted
+ // the access to App usage statistics.
+ // Only check non null here.
+ assertNotNull(usageStatsList);
+ }
+
+ public void testUpdateAppsList() {
+ List<UsageStats> usageStatsList = mTestFragment
+ .getUsageStatistics(UsageStatsManager.INTERVAL_DAILY);
+
+ mTestFragment.updateAppsList(usageStatsList);
+ getInstrumentation().waitForIdleSync();
+
+ // The result depends on if the app is granted the access to App usage statistics.
+ if (usageStatsList.size() == 0) {
+ assertTrue(mTestFragment.mUsageListAdapter.getItemCount() == 0);
+ } else {
+ assertTrue(mTestFragment.mUsageListAdapter.getItemCount() > 0);
+ }
+ }
+}
diff --git a/prebuilts/gradle/AppUsageStatistics/CONTRIBUTING.md b/prebuilts/gradle/AppUsageStatistics/CONTRIBUTING.md
new file mode 100644
index 00000000..faa8b5c6
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/CONTRIBUTING.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://cla.developers.google.com).
+ * 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://cla.developers.google.com).
+
+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/prebuilts/gradle/AppUsageStatistics/LICENSE b/prebuilts/gradle/AppUsageStatistics/LICENSE
new file mode 100644
index 00000000..1af981f5
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/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/prebuilts/gradle/AppUsageStatistics/NOTICE b/prebuilts/gradle/AppUsageStatistics/NOTICE
new file mode 100644
index 00000000..7eede3de
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/NOTICE
@@ -0,0 +1,15 @@
+This sample uses the following software:
+
+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/prebuilts/gradle/AppUsageStatistics/README.md b/prebuilts/gradle/AppUsageStatistics/README.md
new file mode 100644
index 00000000..daeb173c
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/README.md
@@ -0,0 +1,96 @@
+Android AppUsageStatistics Sample
+===================================
+
+A basic app showing how to use App usage statistics API to let users collect statistics related
+to usage of the applications.
+
+Introduction
+------------
+
+The [App usage statistics][1] API allows app developers to collect statistics related to usage of
+the applications. This API provides more detailed usage information than the deprecated
+[getRecentTasks()][2] method.
+
+This example illustrates how to use the App usage statistics API by showing the applications sorted
+by the timestamp of the last time each app was used.
+
+To use this API, you must first declare the `android.permission.PACKAGE_USAGE_STATS` permission
+in your manifest. The user must also enable access for this app through
+`Settings > Security > Apps with usage access`.
+
+To collect the statistics of the app usage, you need to first get the instance of
+[UsageStatsManager][3] by the following code:
+
+```java
+mUsageStatsManager = (UsageStatsManager) getActivity()
+ .getSystemService(Context.USAGE_STATS_SERVICE);
+```
+
+Then you can retrieve the statistics of the app usage by the following method:
+
+```java
+Calendar cal = Calendar.getInstance();
+cal.add(Calendar.YEAR, -1);
+List<UsageStats> queryUsageStats = mUsageStatsManager
+ .queryUsageStats(UsageStatsManager.INTERVAL_DAILY, cal.getTimeInMillis(),
+ System.currentTimeMillis());
+```
+
+The first argument of the [queryUsageStats()][4] is used for the time interval by which the
+stats are aggregated. The second and the third arguments are used for specifying the beginning
+and the end of the range of the stats to include in the results.
+
+[1]: https://developer.android.com/reference/android/app/usage/package-summary.html
+[2]: https://developer.android.com/reference/android/app/ActivityManager.html#getRecentTasks(int%2C%20int)
+[3]: https://developer.android.com/reference/android/app/usage/UsageStatsManager.html
+[4]: https://developer.android.com/reference/android/app/usage/UsageStatsManager.html#queryUsageStats(int%2C%20long%2C%20long)
+
+Pre-requisites
+--------------
+
+- Android SDK v21
+- Android Build Tools v21.1.1
+- Android Support Repository
+
+Screenshots
+-------------
+
+<img src="screenshots/screenshot-1.png" height="400" alt="Screenshot"/> <img src="screenshots/screenshot-2.png" height="400" alt="Screenshot"/>
+
+Getting Started
+---------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+Support
+-------
+
+- Google+ Community: https://plus.google.com/communities/105153134372062985968
+- Stack Overflow: http://stackoverflow.com/questions/tagged/android
+
+If you've found an error in this sample, please file an issue:
+https://github.com/googlesamples/android-AppUsageStatistics
+
+Patches are encouraged, and may be submitted by forking this project and
+submitting a pull request through GitHub. Please see CONTRIBUTING.md for more details.
+
+License
+-------
+
+Copyright 2014 The Android Open Source Project, Inc.
+
+Licensed to the Apache Software Foundation (ASF) under one or more contributor
+license agreements. See the NOTICE file distributed with this work for
+additional information regarding copyright ownership. The ASF licenses this
+file to you 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/prebuilts/gradle/AppUsageStatistics/build.gradle b/prebuilts/gradle/AppUsageStatistics/build.gradle
new file mode 100644
index 00000000..1dac6def
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/build.gradle
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/AppUsageStatistics/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/AppUsageStatistics/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..8c0fb64a
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/AppUsageStatistics/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..8a27ebfa
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sun Dec 07 22:52:45 JST 2014
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/prebuilts/gradle/AppUsageStatistics/gradlew b/prebuilts/gradle/AppUsageStatistics/gradlew
new file mode 100755
index 00000000..91a7e269
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/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/prebuilts/gradle/AppUsageStatistics/gradlew.bat b/prebuilts/gradle/AppUsageStatistics/gradlew.bat
new file mode 100644
index 00000000..aec99730
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/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/prebuilts/gradle/AppUsageStatistics/screenshots/screenshot-1.png b/prebuilts/gradle/AppUsageStatistics/screenshots/screenshot-1.png
new file mode 100644
index 00000000..ab0da864
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/screenshots/screenshot-1.png
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/screenshots/screenshot-2.png b/prebuilts/gradle/AppUsageStatistics/screenshots/screenshot-2.png
new file mode 100644
index 00000000..7663ebdf
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/screenshots/screenshot-2.png
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/screenshots/web-icon.png b/prebuilts/gradle/AppUsageStatistics/screenshots/web-icon.png
new file mode 100755
index 00000000..68af9d0e
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/screenshots/web-icon.png
Binary files differ
diff --git a/prebuilts/gradle/AppUsageStatistics/settings.gradle b/prebuilts/gradle/AppUsageStatistics/settings.gradle
new file mode 100644
index 00000000..9464a359
--- /dev/null
+++ b/prebuilts/gradle/AppUsageStatistics/settings.gradle
@@ -0,0 +1 @@
+include 'Application'
diff --git a/prebuilts/gradle/BasicAccessibility/Application/build.gradle b/prebuilts/gradle/BasicAccessibility/Application/build.gradle
index 8380768f..8b72299a 100644
--- a/prebuilts/gradle/BasicAccessibility/Application/build.gradle
+++ b/prebuilts/gradle/BasicAccessibility/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/Application/build.gradle b/prebuilts/gradle/BasicAndroidKeyStore/Application/build.gradle
index f3cacbe1..3859b3ee 100644
--- a/prebuilts/gradle/BasicAndroidKeyStore/Application/build.gradle
+++ b/prebuilts/gradle/BasicAndroidKeyStore/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BasicContactables/.google/packaging.yaml b/prebuilts/gradle/BasicContactables/.google/packaging.yaml
index c17e1fcc..d18be0c2 100644
--- a/prebuilts/gradle/BasicContactables/.google/packaging.yaml
+++ b/prebuilts/gradle/BasicContactables/.google/packaging.yaml
@@ -9,4 +9,12 @@ categories: [Content]
languages: [Java]
solutions: [Mobile]
github: android-BasicContactables
+level: INTERMEDIATE
+icon: screenshots/icon-web.png
+apiRefs:
+ - android:android.app.SearchManager
+ - android:android.widget.SearchView
+ - android:android.app.LoaderManager
+ - android:android.content.CursorLoader
+ - android:android.provider.ContactsContract.CommonDataKinds
license: apache2
diff --git a/prebuilts/gradle/BasicContactables/Application/build.gradle b/prebuilts/gradle/BasicContactables/Application/build.gradle
index f3cacbe1..3859b3ee 100644
--- a/prebuilts/gradle/BasicContactables/Application/build.gradle
+++ b/prebuilts/gradle/BasicContactables/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BasicContactables/README.md b/prebuilts/gradle/BasicContactables/README.md
index 883cd6c3..cd274c94 100644
--- a/prebuilts/gradle/BasicContactables/README.md
+++ b/prebuilts/gradle/BasicContactables/README.md
@@ -1,10 +1,25 @@
Android BasicContactables Sample
===================================
-This sample demonstrates how to use the Contactables table to search for contacts.
+This sample shows how to search for contacts, displaying a SearchView in the Action Bar for user input and implementing a query Cursor with CommonDataKinds.Contactables.
-Query strings sent to the Contactables table will match both contact names and phone numbers,
-reducing the number of queries your application needs to use when searching the contacts database!
+Introduction
+------------
+
+This sample displays a [SearchView][1] in the Action Bar when the search icon is clicked. It then implements the [LoaderManager.LoaderCallbacks][2] interface to query the contacts table, using a [CursorLoader][3].
+
+For details on how to implement the [SearchView][1], refer to the training guide [Setting up the search interface][4].
+
+For details on how to implement the [LoaderManager.LoaderCallbacks][2] interface, refer to the [Using the LoaderManager Callbacks][5] guide.
+
+For details on how to query the contacts provider, refer to the [Contacts Provider Access][6] guide.
+
+[1]: http://developer.android.com/reference/android/widget/SearchView.html
+[2]: http://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html
+[3]: http://developer.android.com/reference/android/content/CursorLoader.html
+[4]: http://developer.android.com/training/search/setup.html
+[5]: http://developer.android.com/guide/components/loaders.html#callback
+[6]: http://developer.android.com/guide/topics/providers/contacts-provider.html#Access
Pre-requisites
--------------
@@ -13,6 +28,11 @@ Pre-requisites
- Android Build Tools v21.1.1
- Android Support Repository
+Screenshots
+-------------
+
+<img src="screenshots/1-main.png" height="400" alt="Screenshot"/> <img src="screenshots/2-search.png" height="400" alt="Screenshot"/> <img src="screenshots/3-results.png" height="400" alt="Screenshot"/>
+
Getting Started
---------------
diff --git a/prebuilts/gradle/BasicContactables/screenshots/1-main.png b/prebuilts/gradle/BasicContactables/screenshots/1-main.png
new file mode 100644
index 00000000..2c11a7d9
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/screenshots/1-main.png
Binary files differ
diff --git a/prebuilts/gradle/BasicContactables/screenshots/2-search.png b/prebuilts/gradle/BasicContactables/screenshots/2-search.png
new file mode 100644
index 00000000..b8b012f4
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/screenshots/2-search.png
Binary files differ
diff --git a/prebuilts/gradle/BasicContactables/screenshots/3-results.png b/prebuilts/gradle/BasicContactables/screenshots/3-results.png
new file mode 100644
index 00000000..48856ce6
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/screenshots/3-results.png
Binary files differ
diff --git a/prebuilts/gradle/BasicContactables/screenshots/icon-web.png b/prebuilts/gradle/BasicContactables/screenshots/icon-web.png
new file mode 100644
index 00000000..8ad9e149
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/screenshots/icon-web.png
Binary files differ
diff --git a/prebuilts/gradle/BasicGestureDetect/Application/build.gradle b/prebuilts/gradle/BasicGestureDetect/Application/build.gradle
index f3cacbe1..3859b3ee 100644
--- a/prebuilts/gradle/BasicGestureDetect/Application/build.gradle
+++ b/prebuilts/gradle/BasicGestureDetect/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BasicImmersiveMode/Application/build.gradle b/prebuilts/gradle/BasicImmersiveMode/Application/build.gradle
index bfed04fa..c6b8c26a 100644
--- a/prebuilts/gradle/BasicImmersiveMode/Application/build.gradle
+++ b/prebuilts/gradle/BasicImmersiveMode/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BasicManagedProfile/Application/build.gradle b/prebuilts/gradle/BasicManagedProfile/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/BasicManagedProfile/Application/build.gradle
+++ b/prebuilts/gradle/BasicManagedProfile/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BasicMediaDecoder/Application/build.gradle b/prebuilts/gradle/BasicMediaDecoder/Application/build.gradle
index 5e57579a..d727e2a8 100644
--- a/prebuilts/gradle/BasicMediaDecoder/Application/build.gradle
+++ b/prebuilts/gradle/BasicMediaDecoder/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BasicMediaRouter/Application/build.gradle b/prebuilts/gradle/BasicMediaRouter/Application/build.gradle
index 5e57579a..d727e2a8 100644
--- a/prebuilts/gradle/BasicMediaRouter/Application/build.gradle
+++ b/prebuilts/gradle/BasicMediaRouter/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BasicMultitouch/Application/build.gradle b/prebuilts/gradle/BasicMultitouch/Application/build.gradle
index 90737fcc..3e25a83b 100644
--- a/prebuilts/gradle/BasicMultitouch/Application/build.gradle
+++ b/prebuilts/gradle/BasicMultitouch/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BasicNetworking/.google/packaging.yaml b/prebuilts/gradle/BasicNetworking/.google/packaging.yaml
index 57f27960..6f178e2d 100644
--- a/prebuilts/gradle/BasicNetworking/.google/packaging.yaml
+++ b/prebuilts/gradle/BasicNetworking/.google/packaging.yaml
@@ -9,4 +9,9 @@ categories: [Connectivity]
languages: [Java]
solutions: [Mobile]
github: android-BasicNetworking
+level: INTERMEDIATE
+icon: screenshots/big_icon.png
+apiRefs:
+ - android:android.net.ConnectivityManager
+ - android:android.net.NetworkInfo
license: apache2
diff --git a/prebuilts/gradle/BasicNetworking/Application/build.gradle b/prebuilts/gradle/BasicNetworking/Application/build.gradle
index 05020be5..76169dee 100644
--- a/prebuilts/gradle/BasicNetworking/Application/build.gradle
+++ b/prebuilts/gradle/BasicNetworking/Application/build.gradle
@@ -17,7 +17,7 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
+ compile "com.android.support:support-v4:21.0.2"
}
diff --git a/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-hdpi/ic_launcher.png
index 22ce6061..fad6812b 100755
--- a/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-hdpi/ic_launcher.png
+++ b/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-mdpi/ic_launcher.png
index f21e17b6..04cf1152 100755
--- a/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-mdpi/ic_launcher.png
+++ b/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-xhdpi/ic_launcher.png
index 64b80590..53736dfe 100755
--- a/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-xhdpi/ic_launcher.png
+++ b/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
index 6b4434a8..6afbfca3 100755
--- a/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
+++ b/prebuilts/gradle/BasicNetworking/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNetworking/Application/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicNetworking/Application/src/main/res/values/base-strings.xml
index 9a86c89d..ddd695f9 100644
--- a/prebuilts/gradle/BasicNetworking/Application/src/main/res/values/base-strings.xml
+++ b/prebuilts/gradle/BasicNetworking/Application/src/main/res/values/base-strings.xml
@@ -20,10 +20,10 @@
<![CDATA[
- This sample demonstrates how to use the ConnectivityManager to determine if you have
- a network connection, and if so, what type of connection it is.
- \n\nA "NetworkInfo" object is retrieved from the ConnectivityManager, which contains information
- on the active connection, and then the connection type is printed to an on-screen console.
+ This sample demonstrates how to use the ConnectivityManager to determine if you have
+ a network connection, and if so, what type of connection it is.
+ \n\nA "NetworkInfo" object is retrieved from the ConnectivityManager, which contains information
+ on the active connection, and then the connection type is printed to an on-screen console.
]]>
diff --git a/prebuilts/gradle/BasicNetworking/README.md b/prebuilts/gradle/BasicNetworking/README.md
index 9a5eeadc..25a04cef 100644
--- a/prebuilts/gradle/BasicNetworking/README.md
+++ b/prebuilts/gradle/BasicNetworking/README.md
@@ -1,12 +1,23 @@
Android BasicNetworking Sample
===================================
-This sample demonstrates how to use the ConnectivityManager to determine if you have
+This sample demonstrates how to check network connectivity with Android APIs.
+
+Introduction
+------------
+
+It utilizes the [`ConnectivityManager`][1] to determine if you have
a network connection, and if so, what type of connection it is.
-A "NetworkInfo" object is retrieved from the ConnectivityManager, which contains information
+A [`NetworkInfo`][2] object is retrieved from the ConnectivityManager, which contains information
on the active connection, and then the connection type is printed to an on-screen console.
+Multiple types of connectivity can be displayed and could be used to take different measures
+in actual production code.
+
+[1]: https://developer.android.com/reference/android/net/ConnectivityManager.html
+[2]: https://developer.android.com/reference/android/net/NetworkInfo.html
+
Pre-requisites
--------------
@@ -14,6 +25,11 @@ Pre-requisites
- Android Build Tools v21.1.1
- Android Support Repository
+Screenshots
+-------------
+
+<img src="screenshots/start.png" height="400" alt="Screenshot"/> <img src="screenshots/tested.png" height="400" alt="Screenshot"/>
+
Getting Started
---------------
diff --git a/prebuilts/gradle/BasicNetworking/screenshots/big_icon.png b/prebuilts/gradle/BasicNetworking/screenshots/big_icon.png
new file mode 100644
index 00000000..a9c88499
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/screenshots/big_icon.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNetworking/screenshots/start.png b/prebuilts/gradle/BasicNetworking/screenshots/start.png
new file mode 100644
index 00000000..e244f189
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/screenshots/start.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNetworking/screenshots/tested.png b/prebuilts/gradle/BasicNetworking/screenshots/tested.png
new file mode 100644
index 00000000..96359c6b
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/screenshots/tested.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/Application/build.gradle b/prebuilts/gradle/BasicNotifications/Application/build.gradle
index 90737fcc..3e25a83b 100644
--- a/prebuilts/gradle/BasicNotifications/Application/build.gradle
+++ b/prebuilts/gradle/BasicNotifications/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BasicRenderScript/Application/build.gradle b/prebuilts/gradle/BasicRenderScript/Application/build.gradle
index 641b05e5..23a18632 100644
--- a/prebuilts/gradle/BasicRenderScript/Application/build.gradle
+++ b/prebuilts/gradle/BasicRenderScript/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
compile files('renderscript-v8.jar')
}
diff --git a/prebuilts/gradle/BasicSyncAdapter/.google/packaging.yaml b/prebuilts/gradle/BasicSyncAdapter/.google/packaging.yaml
index cead24a9..9d07bf6c 100644
--- a/prebuilts/gradle/BasicSyncAdapter/.google/packaging.yaml
+++ b/prebuilts/gradle/BasicSyncAdapter/.google/packaging.yaml
@@ -5,8 +5,17 @@
---
status: PUBLISHED
technologies: [Android]
-categories: [Connectivity]
+categories: [Background, Connectivity]
languages: [Java]
solutions: [Mobile]
github: android-BasicSyncAdapter
+level: INTERMEDIATE
+icon: screenshots/icon-web.png
+apiRefs:
+ - android:android.app.Service
+ - android:android.content.AbstractThreadedSyncAdapter
+ - android:android.content.ContentProvider
+ - android:android.content.ContentResolver
+ - android:android.content.SyncResult
+ - android:android.database.sqlite.SQLiteDatabase
license: apache2
diff --git a/prebuilts/gradle/BasicSyncAdapter/Application/build.gradle b/prebuilts/gradle/BasicSyncAdapter/Application/build.gradle
index c5134fb4..292c2d14 100644
--- a/prebuilts/gradle/BasicSyncAdapter/Application/build.gradle
+++ b/prebuilts/gradle/BasicSyncAdapter/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-hdpi/ic_launcher.png
index a0f7005a..7920c98e 100644
--- a/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-hdpi/ic_launcher.png
+++ b/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-mdpi/ic_launcher.png
index a085462c..1de60fe4 100644
--- a/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-mdpi/ic_launcher.png
+++ b/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-xhdpi/ic_launcher.png
index 4f78eb84..fc4bfebd 100644
--- a/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-xhdpi/ic_launcher.png
+++ b/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
index b198ee3e..646ce941 100644
--- a/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
+++ b/prebuilts/gradle/BasicSyncAdapter/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicSyncAdapter/README.md b/prebuilts/gradle/BasicSyncAdapter/README.md
index fc21471e..c4900092 100644
--- a/prebuilts/gradle/BasicSyncAdapter/README.md
+++ b/prebuilts/gradle/BasicSyncAdapter/README.md
@@ -1,13 +1,28 @@
Android BasicSyncAdapter Sample
===================================
-This sample demonstrates using SyncAdapter to fetch background data for an app that
-doesn't require a user-visible account type or 2-way synchronization.
+This sample demonstrates using SyncAdapter to fetch background
+data for an app. It covers the creation of the required Service
+that the OS uses to initiate the background data sync as well as
+scheduling syncs with background data.
+Introduction
+------------
-This sample periodically downloads the feed from the Android Developer Blog and
-caches the data in a content provider. At runtime, the cached feed data is displayed
-inside a ListView.
+This sample demonstrates using SyncAdapter to fetch background data
+for an app. SyncAdapters can be used to execute your data transfer
+code at configurable intervals, while efficiently using battery and
+other system resources.
+
+This sample implements all the required elements of a sync adapter.
+- Creates a sync adapter class.
+- Creates a bound Service which the OS uses to initiate a sync.
+- Defines the sync adapter properties in an XML resource file.
+- Declares the bound Service in the app manifest.
+
+For more on SyncAdapters refer to [Transferring Data Using Sync Adapters][1]
+
+[1]: http://developer.android.com/training/sync-adapters/index.html
Pre-requisites
--------------
@@ -16,6 +31,11 @@ Pre-requisites
- Android Build Tools v21.1.1
- Android Support Repository
+Screenshots
+-------------
+
+<img src="screenshots/main.png" height="400" alt="Screenshot"/>
+
Getting Started
---------------
diff --git a/prebuilts/gradle/BasicSyncAdapter/screenshots/icon-web.png b/prebuilts/gradle/BasicSyncAdapter/screenshots/icon-web.png
new file mode 100644
index 00000000..7904a13a
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/screenshots/icon-web.png
Binary files differ
diff --git a/prebuilts/gradle/BasicSyncAdapter/screenshots/main.png b/prebuilts/gradle/BasicSyncAdapter/screenshots/main.png
new file mode 100644
index 00000000..c0a9d483
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/screenshots/main.png
Binary files differ
diff --git a/prebuilts/gradle/BasicTransition/Application/build.gradle b/prebuilts/gradle/BasicTransition/Application/build.gradle
index bfed04fa..c6b8c26a 100644
--- a/prebuilts/gradle/BasicTransition/Application/build.gradle
+++ b/prebuilts/gradle/BasicTransition/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BatchStepSensor/Application/build.gradle b/prebuilts/gradle/BatchStepSensor/Application/build.gradle
index bfed04fa..c6b8c26a 100644
--- a/prebuilts/gradle/BatchStepSensor/Application/build.gradle
+++ b/prebuilts/gradle/BatchStepSensor/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BluetoothChat/Application/build.gradle b/prebuilts/gradle/BluetoothChat/Application/build.gradle
index 8380768f..8b72299a 100644
--- a/prebuilts/gradle/BluetoothChat/Application/build.gradle
+++ b/prebuilts/gradle/BluetoothChat/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BluetoothLeGatt/Application/build.gradle b/prebuilts/gradle/BluetoothLeGatt/Application/build.gradle
index f3cacbe1..3859b3ee 100644
--- a/prebuilts/gradle/BluetoothLeGatt/Application/build.gradle
+++ b/prebuilts/gradle/BluetoothLeGatt/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/BorderlessButtons/Application/build.gradle b/prebuilts/gradle/BorderlessButtons/Application/build.gradle
index 0427861a..37884d80 100644
--- a/prebuilts/gradle/BorderlessButtons/Application/build.gradle
+++ b/prebuilts/gradle/BorderlessButtons/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/Camera2Basic/Application/build.gradle b/prebuilts/gradle/Camera2Basic/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/Camera2Basic/Application/build.gradle
+++ b/prebuilts/gradle/Camera2Basic/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/Camera2Video/Application/build.gradle b/prebuilts/gradle/Camera2Video/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/Camera2Video/Application/build.gradle
+++ b/prebuilts/gradle/Camera2Video/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/CardEmulation/Application/build.gradle b/prebuilts/gradle/CardEmulation/Application/build.gradle
index bfed04fa..c6b8c26a 100644
--- a/prebuilts/gradle/CardEmulation/Application/build.gradle
+++ b/prebuilts/gradle/CardEmulation/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/CardReader/Application/build.gradle b/prebuilts/gradle/CardReader/Application/build.gradle
index bfed04fa..c6b8c26a 100644
--- a/prebuilts/gradle/CardReader/Application/build.gradle
+++ b/prebuilts/gradle/CardReader/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/CardView/Application/build.gradle b/prebuilts/gradle/CardView/Application/build.gradle
index 53483bad..13964de1 100644
--- a/prebuilts/gradle/CardView/Application/build.gradle
+++ b/prebuilts/gradle/CardView/Application/build.gradle
@@ -18,7 +18,7 @@ repositories {
dependencies {
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:cardview-v7:21.0.2"
}
// The sample build uses multiple directories to
diff --git a/prebuilts/gradle/ClippingBasic/Application/build.gradle b/prebuilts/gradle/ClippingBasic/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/ClippingBasic/Application/build.gradle
+++ b/prebuilts/gradle/ClippingBasic/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/CustomChoiceList/Application/build.gradle b/prebuilts/gradle/CustomChoiceList/Application/build.gradle
index 05020be5..76169dee 100644
--- a/prebuilts/gradle/CustomChoiceList/Application/build.gradle
+++ b/prebuilts/gradle/CustomChoiceList/Application/build.gradle
@@ -17,7 +17,7 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
+ compile "com.android.support:support-v4:21.0.2"
}
diff --git a/prebuilts/gradle/CustomNotifications/Application/build.gradle b/prebuilts/gradle/CustomNotifications/Application/build.gradle
index 05020be5..76169dee 100644
--- a/prebuilts/gradle/CustomNotifications/Application/build.gradle
+++ b/prebuilts/gradle/CustomNotifications/Application/build.gradle
@@ -17,7 +17,7 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
+ compile "com.android.support:support-v4:21.0.2"
}
diff --git a/prebuilts/gradle/CustomTransition/Application/build.gradle b/prebuilts/gradle/CustomTransition/Application/build.gradle
index bfed04fa..c6b8c26a 100644
--- a/prebuilts/gradle/CustomTransition/Application/build.gradle
+++ b/prebuilts/gradle/CustomTransition/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/DirectorySelection/.google/packaging.yaml b/prebuilts/gradle/DirectorySelection/.google/packaging.yaml
new file mode 100644
index 00000000..a750a88d
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/.google/packaging.yaml
@@ -0,0 +1,17 @@
+# GOOGLE SAMPLE PACKAGING DATA
+#
+# This file is used by Google as part of our samples packaging process.
+# End users may safely ignore this file. It has no relevance to other systems.
+---
+status: DRAFTED
+technologies: [Android]
+categories: [Content]
+languages: [Java]
+solutions: [Mobile]
+github: android-DirectorySelection
+level: INTERMEDIATE
+icon: screenshots/web-icon.png
+apiRefs:
+ - android:android.content.ContentResolver
+ - android:android.provider.DocumentsContract
+license: apache2
diff --git a/prebuilts/gradle/DirectorySelection/Application/build.gradle b/prebuilts/gradle/DirectorySelection/Application/build.gradle
new file mode 100644
index 00000000..6bd132fb
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/build.gradle
@@ -0,0 +1,71 @@
+buildscript {
+ repositories {
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+ }
+}
+
+apply plugin: 'com.android.application'
+
+repositories {
+ jcenter()
+}
+
+
+dependencies {
+
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
+
+ compile "com.android.support:recyclerview-v7:+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.1"
+
+ defaultConfig {
+ minSdkVersion 21
+ targetSdkVersion 21
+ }
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ androidTest.setRoot('tests')
+ androidTest.java.srcDirs = ['tests/src']
+
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/AndroidManifest.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..46cddcfa
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?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.directoryselection"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity android:name=".DirectorySelectionActivity"
+ 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/prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectoryEntry.java b/prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectoryEntry.java
new file mode 100644
index 00000000..04c1c896
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectoryEntry.java
@@ -0,0 +1,25 @@
+/*
+* 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.directoryselection;
+
+/**
+ * Entity class that represents an directory entry.
+ */
+public class DirectoryEntry {
+ public String fileName;
+ public String mimeType;
+}
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectoryEntryAdapter.java b/prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectoryEntryAdapter.java
new file mode 100644
index 00000000..e92c71ec
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectoryEntryAdapter.java
@@ -0,0 +1,100 @@
+/*
+* 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.directoryselection;
+
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.List;
+
+/**
+ * Provide views to RecyclerView with the directory entries.
+ */
+public class DirectoryEntryAdapter extends RecyclerView.Adapter<DirectoryEntryAdapter.ViewHolder> {
+
+ static final String DIRECTORY_MIME_TYPE = "vnd.android.document/directory";
+ private List<DirectoryEntry> mDirectoryEntries;
+
+ /**
+ * Provide a reference to the type of views that you are using (custom ViewHolder)
+ */
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+ private final TextView mFileName;
+ private final TextView mMimeType;
+ private final ImageView mImageView;
+
+ public ViewHolder(View v) {
+ super(v);
+ mFileName = (TextView) v.findViewById(R.id.textview_filename);
+ mMimeType = (TextView) v.findViewById(R.id.textview_mimetype);
+ mImageView = (ImageView) v.findViewById(R.id.entry_image);
+ }
+
+ public TextView getFileName() {
+ return mFileName;
+ }
+
+ public TextView getMimeType() {
+ return mMimeType;
+ }
+
+ public ImageView getImageView() {
+ return mImageView;
+ }
+ }
+
+ /**
+ * Initialize the directory entries of the Adapter.
+ *
+ * @param directoryEntries an array of {@link DirectoryEntry}.
+ */
+ public DirectoryEntryAdapter(List<DirectoryEntry> directoryEntries) {
+ mDirectoryEntries = directoryEntries;
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
+ View v = LayoutInflater.from(viewGroup.getContext())
+ .inflate(R.layout.directory_item, viewGroup, false);
+ return new ViewHolder(v);
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder viewHolder, final int position) {
+ viewHolder.getFileName().setText(mDirectoryEntries.get(position).fileName);
+ viewHolder.getMimeType().setText(mDirectoryEntries.get(position).mimeType);
+
+ if (DIRECTORY_MIME_TYPE.equals(mDirectoryEntries.get(position).mimeType)) {
+ viewHolder.getImageView().setImageResource(R.drawable.ic_folder_grey600_36dp);
+ } else {
+ viewHolder.getImageView().setImageResource(R.drawable.ic_description_grey600_36dp);
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return mDirectoryEntries.size();
+ }
+
+ public void setDirectoryEntries(List<DirectoryEntry> directoryEntries) {
+ mDirectoryEntries = directoryEntries;
+ }
+}
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectorySelectionActivity.java b/prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectorySelectionActivity.java
new file mode 100644
index 00000000..d27ba728
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectorySelectionActivity.java
@@ -0,0 +1,37 @@
+/*
+* 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.
+*/
+
+package com.example.android.directoryselection;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+/**
+ * Launcher Activity for the Directory Selection sample app.
+ */
+public class DirectorySelectionActivity extends FragmentActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_directory_selection);
+ if (savedInstanceState == null) {
+ getSupportFragmentManager().beginTransaction()
+ .add(R.id.container, DirectorySelectionFragment.newInstance())
+ .commit();
+ }
+ }
+}
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectorySelectionFragment.java b/prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectorySelectionFragment.java
new file mode 100644
index 00000000..4af55dbe
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/java/com/example/android/directoryselection/DirectorySelectionFragment.java
@@ -0,0 +1,231 @@
+/*
+* 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.
+*/
+
+package com.example.android.directoryselection;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.ContentResolver;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.support.v4.app.Fragment;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Fragment that demonstrates how to use Directory Selection API.
+ */
+public class DirectorySelectionFragment extends Fragment {
+
+ private static final String TAG = DirectorySelectionFragment.class.getSimpleName();
+
+ public static final int REQUEST_CODE_OPEN_DIRECTORY = 1;
+
+ Uri mCurrentDirectoryUri;
+ TextView mCurrentDirectoryTextView;
+ Button mCreateDirectoryButton;
+ RecyclerView mRecyclerView;
+ DirectoryEntryAdapter mAdapter;
+ RecyclerView.LayoutManager mLayoutManager;
+
+ /**
+ * Use this factory method to create a new instance of
+ * this fragment using the provided parameters.
+ *
+ * @return A new instance of fragment {@link DirectorySelectionFragment}.
+ */
+ public static DirectorySelectionFragment newInstance() {
+ DirectorySelectionFragment fragment = new DirectorySelectionFragment();
+ return fragment;
+ }
+
+ public DirectorySelectionFragment() {
+ // Required empty public constructor
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.fragment_directory_selection, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View rootView, Bundle savedInstanceState) {
+ super.onViewCreated(rootView, savedInstanceState);
+
+ rootView.findViewById(R.id.button_open_directory)
+ .setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
+ startActivityForResult(intent, REQUEST_CODE_OPEN_DIRECTORY);
+ }
+ });
+
+ mCurrentDirectoryTextView = (TextView) rootView
+ .findViewById(R.id.textview_current_directory);
+ mCreateDirectoryButton = (Button) rootView.findViewById(R.id.button_create_directory);
+ mCreateDirectoryButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ final EditText editView = new EditText(getActivity());
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.create_directory)
+ .setView(editView)
+ .setPositiveButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ createDirectory(mCurrentDirectoryUri,
+ editView.getText().toString());
+ updateDirectoryEntries(mCurrentDirectoryUri);
+ }
+ })
+ .setNegativeButton(android.R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ }
+ })
+ .show();
+ }
+ });
+ mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview_directory_entries);
+ mLayoutManager = new LinearLayoutManager(getActivity());
+ mRecyclerView.setLayoutManager(mLayoutManager);
+ mRecyclerView.scrollToPosition(0);
+ mAdapter = new DirectoryEntryAdapter(new ArrayList<DirectoryEntry>());
+ mRecyclerView.setAdapter(mAdapter);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == REQUEST_CODE_OPEN_DIRECTORY && resultCode == Activity.RESULT_OK) {
+ Log.d(TAG, String.format("Open Directory result Uri : %s", data.getData()));
+ updateDirectoryEntries(data.getData());
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+
+
+ /**
+ * Updates the current directory of the uri passed as an argument and its children directories.
+ * And updates the {@link #mRecyclerView} depending on the contents of the children.
+ *
+ * @param uri The uri of the current directory.
+ */
+ //VisibileForTesting
+ void updateDirectoryEntries(Uri uri) {
+ ContentResolver contentResolver = getActivity().getContentResolver();
+ Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri,
+ DocumentsContract.getTreeDocumentId(uri));
+ Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri,
+ DocumentsContract.getTreeDocumentId(uri));
+
+ Cursor docCursor = contentResolver.query(docUri, new String[]{
+ Document.COLUMN_DISPLAY_NAME, Document.COLUMN_MIME_TYPE}, null, null, null);
+ try {
+ while (docCursor.moveToNext()) {
+ Log.d(TAG, "found doc =" + docCursor.getString(0) + ", mime=" + docCursor
+ .getString(1));
+ mCurrentDirectoryUri = uri;
+ mCurrentDirectoryTextView.setText(docCursor.getString(0));
+ mCreateDirectoryButton.setEnabled(true);
+ }
+ } finally {
+ closeQuietly(docCursor);
+ }
+
+ Cursor childCursor = contentResolver.query(childrenUri, new String[]{
+ Document.COLUMN_DISPLAY_NAME, Document.COLUMN_MIME_TYPE}, null, null, null);
+ try {
+ List<DirectoryEntry> directoryEntries = new ArrayList<>();
+ while (childCursor.moveToNext()) {
+ Log.d(TAG, "found child=" + childCursor.getString(0) + ", mime=" + childCursor
+ .getString(1));
+ DirectoryEntry entry = new DirectoryEntry();
+ entry.fileName = childCursor.getString(0);
+ entry.mimeType = childCursor.getString(1);
+ directoryEntries.add(entry);
+ }
+ mAdapter.setDirectoryEntries(directoryEntries);
+ mAdapter.notifyDataSetChanged();
+ } finally {
+ closeQuietly(childCursor);
+ }
+ }
+
+ /**
+ * Creates a directory under the directory represented as the uri in the argument.
+ *
+ * @param uri The uri of the directory under which a new directory is created.
+ * @param directoryName The directory name of a new directory.
+ */
+ //VisibileForTesting
+ void createDirectory(Uri uri, String directoryName) {
+ ContentResolver contentResolver = getActivity().getContentResolver();
+ Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri,
+ DocumentsContract.getTreeDocumentId(uri));
+ Uri directoryUri = DocumentsContract
+ .createDocument(contentResolver, docUri, Document.MIME_TYPE_DIR, directoryName);
+ if (directoryUri != null) {
+ Log.i(TAG, String.format(
+ "Created directory : %s, Document Uri : %s, Created directory Uri : %s",
+ directoryName, docUri, directoryUri));
+ Toast.makeText(getActivity(), String.format("Created a directory [%s]",
+ directoryName), Toast.LENGTH_SHORT).show();
+ } else {
+ Log.w(TAG, String.format("Failed to create a directory : %s, Uri %s", directoryName,
+ docUri));
+ Toast.makeText(getActivity(), String.format("Failed to created a directory [%s] : ",
+ directoryName), Toast.LENGTH_SHORT).show();
+ }
+
+ }
+
+ public void closeQuietly(AutoCloseable closeable) {
+ if (closeable != null) {
+ try {
+ closeable.close();
+ } catch (RuntimeException rethrown) {
+ throw rethrown;
+ } catch (Exception ignored) {
+ }
+ }
+ }
+}
+
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/ic_description_grey600_36dp.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/ic_description_grey600_36dp.png
new file mode 100755
index 00000000..dd7d0734
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/ic_description_grey600_36dp.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/ic_folder_grey600_36dp.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/ic_folder_grey600_36dp.png
new file mode 100755
index 00000000..6c022d46
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/ic_folder_grey600_36dp.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 00000000..49ee8546
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 00000000..13586288
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-mdpi/ic_description_grey600_36dp.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-mdpi/ic_description_grey600_36dp.png
new file mode 100755
index 00000000..ac18b575
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-mdpi/ic_description_grey600_36dp.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-mdpi/ic_folder_grey600_36dp.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-mdpi/ic_folder_grey600_36dp.png
new file mode 100755
index 00000000..e3dccd29
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-mdpi/ic_folder_grey600_36dp.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 00000000..282a00c7
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xhdpi/ic_description_grey600_36dp.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xhdpi/ic_description_grey600_36dp.png
new file mode 100755
index 00000000..50f854ea
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xhdpi/ic_description_grey600_36dp.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xhdpi/ic_folder_grey600_36dp.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xhdpi/ic_folder_grey600_36dp.png
new file mode 100755
index 00000000..6fbc4045
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xhdpi/ic_folder_grey600_36dp.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 00000000..7293ad6e
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xxhdpi/ic_description_grey600_36dp.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xxhdpi/ic_description_grey600_36dp.png
new file mode 100755
index 00000000..33df5d9d
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xxhdpi/ic_description_grey600_36dp.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xxhdpi/ic_folder_grey600_36dp.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xxhdpi/ic_folder_grey600_36dp.png
new file mode 100755
index 00000000..ed2f08e4
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xxhdpi/ic_folder_grey600_36dp.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 00000000..7b618d40
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/activity_directory_selection.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/activity_directory_selection.xml
new file mode 100644
index 00000000..db655838
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/activity_directory_selection.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context="com.example.android.directoryselection.DirectorySelectionActivity"
+ tools:ignore="MergeRootFrame" /> \ No newline at end of file
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/activity_main.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/activity_main.xml
new file mode 100755
index 00000000..be1aa49d
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/directory_item.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/directory_item.xml
new file mode 100644
index 00000000..0763cff6
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/directory_item.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/directory_item_height"
+ >
+
+ <LinearLayout android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_centerVertical="true"
+ android:gravity="center_vertical"
+ >
+ <ImageView android:id="@+id/entry_image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_folder_grey600_36dp"
+ />
+ <LinearLayout android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/margin_medium"
+ android:orientation="vertical"
+ >
+ <View android:id="@+id/divisor"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="#aaaaaa"/>
+
+ <TextView
+ android:id="@+id/textview_filename"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/DirectoryEntryNameFont"
+ />
+ <TextView
+ android:id="@+id/textview_mimetype"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ </LinearLayout>
+ </LinearLayout>
+</RelativeLayout>
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/fragment_directory_selection.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/fragment_directory_selection.xml
new file mode 100644
index 00000000..d63219c5
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/layout/fragment_directory_selection.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:gravity="center_vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="@dimen/margin_medium">
+
+ <LinearLayout android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
+
+ <Button android:id="@+id/button_open_directory"
+ android:text="@string/open_directory"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <Button android:id="@+id/button_create_directory"
+ android:text="@string/create_directory"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:enabled="false"
+ />
+ </LinearLayout>
+
+ <LinearLayout android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_marginLeft="@dimen/margin_small"
+ android:layout_marginRight="@dimen/margin_small"
+ >
+
+ <TextView android:id="@+id/label_current_directory"
+ android:text="@string/selected_directory"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <TextView android:id="@+id/textview_current_directory"
+ android:enabled="false"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/DirectoryEntryNameFont"
+ />
+
+ </LinearLayout>
+
+ <android.support.v7.widget.RecyclerView
+ android:id="@+id/recyclerview_directory_entries"
+ android:layout_marginLeft="@dimen/margin_small"
+ android:layout_marginRight="@dimen/margin_small"
+ android:scrollbars="vertical"
+ android:drawSelectorOnTop="true"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+
+</LinearLayout>
+
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/menu/main.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/menu/main.xml
new file mode 100644
index 00000000..e9b5e0b1
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/menu/main.xml
@@ -0,0 +1,16 @@
+<!--
+ 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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android" />
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 00000000..22074a2b
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 00000000..03d19741
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-v11/template-styles.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-v11/template-styles.xml
new file mode 100644
index 00000000..8c1ea66f
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-v21/base-colors.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-v21/base-colors.xml
new file mode 100644
index 00000000..34c9cd13
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-v21/base-colors.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<resources>
+
+
+</resources>
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-v21/base-template-styles.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-v21/base-template-styles.xml
new file mode 100644
index 00000000..0b2948f7
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values-v21/base-template-styles.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<resources>
+
+ <!-- Activity themes -->
+ <style name="Theme.Base" parent="android:Theme.Material.Light">
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/base-strings.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/base-strings.xml
new file mode 100644
index 00000000..782c64aa
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/base-strings.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<resources>
+ <string name="app_name">DirectorySelection</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample explains how to use Directory selection API, which was introduced
+ in Android 5.0.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/dimens.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/dimens.xml
new file mode 100644
index 00000000..53d0182c
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/dimens.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<resources>
+ <dimen name="directory_item_height">72dp</dimen>
+</resources> \ No newline at end of file
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/strings.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/strings.xml
new file mode 100644
index 00000000..24d59dde
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<resources>
+ <string name="open_directory">Open directory</string>
+ <string name="create_directory">Create Directory</string>
+ <string name="selected_directory">"Selected Directory : "</string>
+</resources>
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/styles.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/styles.xml
new file mode 100644
index 00000000..38441f38
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/styles.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<resources>
+ <style name="DirectoryEntryNameFont" parent="@android:style/TextAppearance.Medium">
+ <item name="android:textColor">#000000</item>
+ </style>
+</resources> \ No newline at end of file
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/template-dimens.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/template-dimens.xml
new file mode 100644
index 00000000..39e710b5
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/template-styles.xml b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/template-styles.xml
new file mode 100644
index 00000000..6e7d593d
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/DirectorySelection/Application/tests/src/com/example/android/directoryselection/DirectoryEntryAdapterTest.java b/prebuilts/gradle/DirectorySelection/Application/tests/src/com/example/android/directoryselection/DirectoryEntryAdapterTest.java
new file mode 100644
index 00000000..97b26293
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/tests/src/com/example/android/directoryselection/DirectoryEntryAdapterTest.java
@@ -0,0 +1,82 @@
+/*
+* 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.
+*/
+/*
+* 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.directoryselection;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link DirectorySelectionFragment}.
+ */
+public class DirectoryEntryAdapterTest
+ extends ActivityInstrumentationTestCase2<DirectorySelectionActivity> {
+
+ private static final String FILE1 = "file1";
+ private static final String MIME_TYPE1 = "text/appliaction";
+ private static final String DIRECTORY1 = "directory1";
+
+ private DirectorySelectionActivity mTestActivity;
+ private DirectorySelectionFragment mTestFragment;
+ private DirectoryEntryAdapter mAdapter;
+ private List<DirectoryEntry> mDirectoryEntries;
+
+ public DirectoryEntryAdapterTest() {
+ super(DirectorySelectionActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mTestActivity = getActivity();
+ mTestFragment = (DirectorySelectionFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(0);
+ mDirectoryEntries = new ArrayList<>();
+
+ DirectoryEntry file = new DirectoryEntry();
+ file.fileName = FILE1;
+ file.mimeType = MIME_TYPE1;
+ mDirectoryEntries.add(file);
+
+ DirectoryEntry directory = new DirectoryEntry();
+ directory.fileName = DIRECTORY1;
+ directory.mimeType = DirectoryEntryAdapter.DIRECTORY_MIME_TYPE;
+ mDirectoryEntries.add(directory);
+ }
+
+ public void testGetItemCount() {
+ mTestFragment.mAdapter.setDirectoryEntries(mDirectoryEntries);
+
+ assertEquals(2, mTestFragment.mAdapter.getItemCount());
+ }
+}
diff --git a/prebuilts/gradle/DirectorySelection/Application/tests/src/com/example/android/directoryselection/DirectorySelectionActivityTest.java b/prebuilts/gradle/DirectorySelection/Application/tests/src/com/example/android/directoryselection/DirectorySelectionActivityTest.java
new file mode 100644
index 00000000..8f767aef
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/tests/src/com/example/android/directoryselection/DirectorySelectionActivityTest.java
@@ -0,0 +1,56 @@
+/*
+* 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.
+*/
+
+package com.example.android.directoryselection;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * Tests for {@link DirectorySelectionActivity}.
+ */
+public class DirectorySelectionActivityTest
+ extends ActivityInstrumentationTestCase2<DirectorySelectionActivity> {
+
+ private DirectorySelectionActivity mTestActivity;
+ private DirectorySelectionFragment mTestFragment;
+
+ public DirectorySelectionActivityTest() {
+ super(DirectorySelectionActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (DirectorySelectionFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(0);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+}
diff --git a/prebuilts/gradle/DirectorySelection/Application/tests/src/com/example/android/directoryselection/DirectorySelectionFragmentTest.java b/prebuilts/gradle/DirectorySelection/Application/tests/src/com/example/android/directoryselection/DirectorySelectionFragmentTest.java
new file mode 100644
index 00000000..90cd30f7
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/Application/tests/src/com/example/android/directoryselection/DirectorySelectionFragmentTest.java
@@ -0,0 +1,68 @@
+/*
+* 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.
+*/
+/*
+* 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.directoryselection;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * Tests for {@link com.example.android.directoryselection.DirectorySelectionFragment}.
+ */
+public class DirectorySelectionFragmentTest
+ extends ActivityInstrumentationTestCase2<DirectorySelectionActivity> {
+
+ private DirectorySelectionActivity mTestActivity;
+ private DirectorySelectionFragment mTestFragment;
+
+ public DirectorySelectionFragmentTest() {
+ super(DirectorySelectionActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (DirectorySelectionFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(0);
+ }
+
+ public void testPreconditions() {
+ assertNotNull(mTestFragment.mCurrentDirectoryTextView);
+ assertNotNull(mTestFragment.mCreateDirectoryButton);
+ assertNotNull(mTestFragment.mRecyclerView);
+ assertNotNull(mTestFragment.mAdapter);
+ assertNotNull(mTestFragment.mLayoutManager);
+ }
+}
diff --git a/prebuilts/gradle/DirectorySelection/CONTRIBUTING.md b/prebuilts/gradle/DirectorySelection/CONTRIBUTING.md
new file mode 100644
index 00000000..faa8b5c6
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/CONTRIBUTING.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://cla.developers.google.com).
+ * 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://cla.developers.google.com).
+
+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/prebuilts/gradle/DirectorySelection/LICENSE b/prebuilts/gradle/DirectorySelection/LICENSE
new file mode 100644
index 00000000..1af981f5
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/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/prebuilts/gradle/DirectorySelection/NOTICE b/prebuilts/gradle/DirectorySelection/NOTICE
new file mode 100644
index 00000000..7eede3de
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/NOTICE
@@ -0,0 +1,15 @@
+This sample uses the following software:
+
+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/prebuilts/gradle/DirectorySelection/README.md b/prebuilts/gradle/DirectorySelection/README.md
new file mode 100644
index 00000000..1d3fb33c
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/README.md
@@ -0,0 +1,154 @@
+Android DirectorySelection Sample
+===================================
+
+A basic app showing how to use Directory Selection API to let users
+select an entire directory subtree, which extends the Storage Access Framework
+introduced in Android 4.4 (API level 19).
+
+Introduction
+------------
+
+The [Directory Selection][1] API, which was introduced in Android 5.0 (API level 21)
+extends the [Storage Access Framework][2] to let users select an entire directory subtree,
+giving apps read/write access to all contained documents without requiring user
+confirmation for each item.
+
+To select a directory subtree, build and send an [OPEN_DOCUMENT_TREE intent][3] like in the
+following code:
+
+```java
+Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
+startActivityForResult(intent, REQUEST_CODE_OPEN_DIRECTORY);
+```
+
+The system displays all [DocumentsProvider][4] instances that support subtree selection,
+ letting the user browse and select a directory.
+
+The returned URI represents access to the selected subtree. You can then use
+[buildChildDocumentsUriUsingTree()][5] to access to the child documents and
+[buildDocumentUriUsingTree()][6] to access to the selected directory itself along with [query()][7]
+to explore the subtree.
+
+This example explores the child documents and the selected document by following code:
+
+```java
+@Override
+public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == REQUEST_CODE_OPEN_DIRECTORY && resultCode == Activity.RESULT_OK) {
+ updateDirectoryEntries(data.getData());
+ }
+}
+
+void updateDirectoryEntries(Uri uri) {
+ ContentResolver contentResolver = getActivity().getContentResolver();
+ Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri,
+ DocumentsContract.getTreeDocumentId(uri));
+ Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri,
+ DocumentsContract.getTreeDocumentId(uri));
+
+ Cursor docCursor = contentResolver.query(docUri, new String[]{
+ Document.COLUMN_DISPLAY_NAME, Document.COLUMN_MIME_TYPE}, null, null, null);
+ try {
+ while (docCursor.moveToNext()) {
+ Log.d(TAG, "found doc =" + docCursor.getString(0) + ", mime=" + docCursor
+ .getString(1));
+ mCurrentDirectoryUri = uri;
+ mCurrentDirectoryTextView.setText(docCursor.getString(0));
+ mCreateDirectoryButton.setEnabled(true);
+ }
+ } finally {
+ closeQuietly(docCursor);
+ }
+
+ Cursor childCursor = contentResolver.query(childrenUri, new String[]{
+ Document.COLUMN_DISPLAY_NAME, Document.COLUMN_MIME_TYPE}, null, null, null);
+ try {
+ List<DirectoryEntry> directoryEntries = new ArrayList<>();
+ while (childCursor.moveToNext()) {
+ Log.d(TAG, "found child=" + childCursor.getString(0) + ", mime=" + childCursor
+ .getString(1));
+ DirectoryEntry entry = new DirectoryEntry();
+ entry.fileName = childCursor.getString(0);
+ entry.mimeType = childCursor.getString(1);
+ directoryEntries.add(entry);
+ }
+ mAdapter.setDirectoryEntries(directoryEntries);
+ mAdapter.notifyDataSetChanged();
+ } finally {
+ closeQuietly(childCursor);
+ }
+}
+```
+
+Also, the new [createDocument()][8] method lets you create new documents or directories
+anywhere under the subtree.
+
+This example creates a new directory by following code:
+
+```java
+ContentResolver contentResolver = getActivity().getContentResolver();
+Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri,
+ DocumentsContract.getTreeDocumentId(uri));
+Uri directoryUri = DocumentsContract
+ .createDocument(contentResolver, docUri, Document.MIME_TYPE_DIR, directoryName);
+```
+
+[1]: https://developer.android.com/about/versions/android-5.0.html#Storage
+[2]: https://developer.android.com/guide/topics/providers/document-provider.html
+[3]: https://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT_TREE
+[4]: https://developer.android.com/reference/android/provider/DocumentsProvider.html
+[5]: https://developer.android.com/reference/android/provider/DocumentsContract.html#buildChildDocumentsUriUsingTree(android.net.Uri%2C%20java.lang.String)
+[6]: https://developer.android.com/reference/android/provider/DocumentsContract.html#buildDocumentUriUsingTree(android.net.Uri%2C%20java.lang.String)
+[7]: https://developer.android.com/reference/android/content/ContentResolver.html#query(android.net.Uri%2C%20java.lang.String%5B%5D%2C%20java.lang.String%2C%20java.lang.String%5B%5D%2C%20java.lang.String)
+[8]: https://developer.android.com/reference/android/provider/DocumentsContract.html#createDocument(android.content.ContentResolver%2C%20android.net.Uri%2C%20java.lang.String%2C%20java.lang.String)
+
+Pre-requisites
+--------------
+
+- Android SDK v21
+- Android Build Tools v21.1.1
+- Android Support Repository
+
+Screenshots
+-------------
+
+<img src="screenshots/screenshot-1.png" height="400" alt="Screenshot"/> <img src="screenshots/screenshot-2.png" height="400" alt="Screenshot"/> <img src="screenshots/screenshot-3.png" height="400" alt="Screenshot"/>
+
+Getting Started
+---------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+Support
+-------
+
+- Google+ Community: https://plus.google.com/communities/105153134372062985968
+- Stack Overflow: http://stackoverflow.com/questions/tagged/android
+
+If you've found an error in this sample, please file an issue:
+https://github.com/googlesamples/android-DirectorySelection
+
+Patches are encouraged, and may be submitted by forking this project and
+submitting a pull request through GitHub. Please see CONTRIBUTING.md for more details.
+
+License
+-------
+
+Copyright 2014 The Android Open Source Project, Inc.
+
+Licensed to the Apache Software Foundation (ASF) under one or more contributor
+license agreements. See the NOTICE file distributed with this work for
+additional information regarding copyright ownership. The ASF licenses this
+file to you 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/prebuilts/gradle/DirectorySelection/build.gradle b/prebuilts/gradle/DirectorySelection/build.gradle
new file mode 100644
index 00000000..1dac6def
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/build.gradle
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/DirectorySelection/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/DirectorySelection/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..8c0fb64a
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/DirectorySelection/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..3e37868a
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Dec 03 14:12:05 JST 2014
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/prebuilts/gradle/DirectorySelection/gradlew b/prebuilts/gradle/DirectorySelection/gradlew
new file mode 100755
index 00000000..91a7e269
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/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/prebuilts/gradle/DirectorySelection/gradlew.bat b/prebuilts/gradle/DirectorySelection/gradlew.bat
new file mode 100644
index 00000000..aec99730
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/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/prebuilts/gradle/DirectorySelection/screenshots/screenshot-1.png b/prebuilts/gradle/DirectorySelection/screenshots/screenshot-1.png
new file mode 100644
index 00000000..a4310dc7
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/screenshots/screenshot-1.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/screenshots/screenshot-2.png b/prebuilts/gradle/DirectorySelection/screenshots/screenshot-2.png
new file mode 100644
index 00000000..cd275075
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/screenshots/screenshot-2.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/screenshots/screenshot-3.png b/prebuilts/gradle/DirectorySelection/screenshots/screenshot-3.png
new file mode 100644
index 00000000..07954754
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/screenshots/screenshot-3.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/screenshots/web-icon.png b/prebuilts/gradle/DirectorySelection/screenshots/web-icon.png
new file mode 100755
index 00000000..f0a573f6
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/screenshots/web-icon.png
Binary files differ
diff --git a/prebuilts/gradle/DirectorySelection/settings.gradle b/prebuilts/gradle/DirectorySelection/settings.gradle
new file mode 100644
index 00000000..9464a359
--- /dev/null
+++ b/prebuilts/gradle/DirectorySelection/settings.gradle
@@ -0,0 +1 @@
+include 'Application'
diff --git a/prebuilts/gradle/DisplayingBitmaps/Application/build.gradle b/prebuilts/gradle/DisplayingBitmaps/Application/build.gradle
index c5134fb4..292c2d14 100644
--- a/prebuilts/gradle/DisplayingBitmaps/Application/build.gradle
+++ b/prebuilts/gradle/DisplayingBitmaps/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/DocumentCentricApps/Application/build.gradle b/prebuilts/gradle/DocumentCentricApps/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/DocumentCentricApps/Application/build.gradle
+++ b/prebuilts/gradle/DocumentCentricApps/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/DocumentCentricRelinquishIdentity/Application/build.gradle b/prebuilts/gradle/DocumentCentricRelinquishIdentity/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/DocumentCentricRelinquishIdentity/Application/build.gradle
+++ b/prebuilts/gradle/DocumentCentricRelinquishIdentity/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/DoneBar/Application/build.gradle b/prebuilts/gradle/DoneBar/Application/build.gradle
index 0427861a..37884d80 100644
--- a/prebuilts/gradle/DoneBar/Application/build.gradle
+++ b/prebuilts/gradle/DoneBar/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/DrawableTinting/Application/build.gradle b/prebuilts/gradle/DrawableTinting/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/DrawableTinting/Application/build.gradle
+++ b/prebuilts/gradle/DrawableTinting/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/ElevationBasic/Application/build.gradle b/prebuilts/gradle/ElevationBasic/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/ElevationBasic/Application/build.gradle
+++ b/prebuilts/gradle/ElevationBasic/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/ElevationDrag/Application/build.gradle b/prebuilts/gradle/ElevationDrag/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/ElevationDrag/Application/build.gradle
+++ b/prebuilts/gradle/ElevationDrag/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/ElizaChat/Application/build.gradle b/prebuilts/gradle/ElizaChat/Application/build.gradle
index f3cacbe1..3859b3ee 100644
--- a/prebuilts/gradle/ElizaChat/Application/build.gradle
+++ b/prebuilts/gradle/ElizaChat/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/FloatingActionButtonBasic/Application/build.gradle b/prebuilts/gradle/FloatingActionButtonBasic/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/FloatingActionButtonBasic/Application/build.gradle
+++ b/prebuilts/gradle/FloatingActionButtonBasic/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/FragmentTransition/Application/build.gradle b/prebuilts/gradle/FragmentTransition/Application/build.gradle
index bfed04fa..c6b8c26a 100644
--- a/prebuilts/gradle/FragmentTransition/Application/build.gradle
+++ b/prebuilts/gradle/FragmentTransition/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/HdrViewfinder/Application/build.gradle b/prebuilts/gradle/HdrViewfinder/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/HdrViewfinder/Application/build.gradle
+++ b/prebuilts/gradle/HdrViewfinder/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/HorizontalPaging/Application/build.gradle b/prebuilts/gradle/HorizontalPaging/Application/build.gradle
index 8380768f..8b72299a 100644
--- a/prebuilts/gradle/HorizontalPaging/Application/build.gradle
+++ b/prebuilts/gradle/HorizontalPaging/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/ImmersiveMode/Application/build.gradle b/prebuilts/gradle/ImmersiveMode/Application/build.gradle
index 05020be5..76169dee 100644
--- a/prebuilts/gradle/ImmersiveMode/Application/build.gradle
+++ b/prebuilts/gradle/ImmersiveMode/Application/build.gradle
@@ -17,7 +17,7 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
+ compile "com.android.support:support-v4:21.0.2"
}
diff --git a/prebuilts/gradle/Interpolator/Application/build.gradle b/prebuilts/gradle/Interpolator/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/Interpolator/Application/build.gradle
+++ b/prebuilts/gradle/Interpolator/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/JobScheduler/Application/build.gradle b/prebuilts/gradle/JobScheduler/Application/build.gradle
index f3cacbe1..3859b3ee 100644
--- a/prebuilts/gradle/JobScheduler/Application/build.gradle
+++ b/prebuilts/gradle/JobScheduler/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/JumpingJack/.google/packaging.yaml b/prebuilts/gradle/JumpingJack/.google/packaging.yaml
index 618c275b..b2c99852 100644
--- a/prebuilts/gradle/JumpingJack/.google/packaging.yaml
+++ b/prebuilts/gradle/JumpingJack/.google/packaging.yaml
@@ -9,4 +9,9 @@ categories: [Wearable]
languages: [Java]
solutions: [Mobile]
github: android-JumpingJack
+level: INTERMEDIATE
+icon: screenshots/web-icon.png
+apiRefs:
+ - android:android.hardware.SensorEvent
+ - android:android.hardware.SensorEventManager
license: apache2
diff --git a/prebuilts/gradle/JumpingJack/README.md b/prebuilts/gradle/JumpingJack/README.md
index d87e86fb..f2c82c3e 100644
--- a/prebuilts/gradle/JumpingJack/README.md
+++ b/prebuilts/gradle/JumpingJack/README.md
@@ -1,7 +1,44 @@
Android JumpingJack Sample
===================================
-Uses the Gravity sensor to count how many jumping jacks you have performed.
+A basic sample showing how to use the Gravity sensor on the wearable device
+by counting how many jumping jacks you have performed.
+
+Introduction
+------------
+
+[SensorEventListener][1] offers you methods used for receiving notifications from the
+[SensorManager][2] when sensor values have changed.
+
+This example counts how many times Jumping Jakcs are performed by detecting the value
+of the Gravity sensor by the following code:
+
+```java
+@Override
+public void onSensorChanged(SensorEvent event) {
+ detectJump(event.values[0], event.timestamp);
+}
+
+private void detectJump(float xValue, long timestamp) {
+ if ((Math.abs(xValue) > GRAVITY_THRESHOLD)) {
+ if(timestamp - mLastTime < TIME_THRESHOLD_NS && mUp != (xValue > 0)) {
+ onJumpDetected(!mUp);
+ }
+ mUp = xValue > 0;
+ mLastTime = timestamp;
+ }
+}
+```
+
+The detectJump method above assumes that when a person is wearing the watch, the x-component of gravity
+as measured by the Gravity Sensor is +9.8 when the hand is downward and -9.8 when the hand
+is upward (signs are reversed if the watch is worn on the right hand). Since the upward or
+downward may not be completely accurate, we leave some room and instead of 9.8, we use
+GRAVITY_THRESHOLD (7.0f). We also consider the up <-> down movement successful if it takes less than
+TIME_THRESHOLD_NS (2000000000 nanoseconds).
+
+[1]: http://developer.android.com/reference/android/hardware/SensorEventListener.html
+[2]: http://developer.android.com/reference/android/hardware/SensorManager.html
Pre-requisites
--------------
@@ -10,6 +47,11 @@ Pre-requisites
- Android Build Tools v21.1.1
- Android Support Repository
+Screenshots
+-------------
+
+<img src="screenshots/jumping_jack.gif" height="400" alt="Screenshot"/>
+
Getting Started
---------------
diff --git a/prebuilts/gradle/JumpingJack/screenshots/web-icon.png b/prebuilts/gradle/JumpingJack/screenshots/web-icon.png
new file mode 100644
index 00000000..da3c00a9
--- /dev/null
+++ b/prebuilts/gradle/JumpingJack/screenshots/web-icon.png
Binary files differ
diff --git a/prebuilts/gradle/LNotifications/Application/build.gradle b/prebuilts/gradle/LNotifications/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/LNotifications/Application/build.gradle
+++ b/prebuilts/gradle/LNotifications/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/MediaBrowserService/.google/packaging.yaml b/prebuilts/gradle/MediaBrowserService/.google/packaging.yaml
index a126b516..09141fd3 100644
--- a/prebuilts/gradle/MediaBrowserService/.google/packaging.yaml
+++ b/prebuilts/gradle/MediaBrowserService/.google/packaging.yaml
@@ -9,4 +9,12 @@ categories: [Media]
languages: [Java]
solutions: [Mobile]
github: android-MediaBrowserService
+level: ADVANCED
+icon: screenshots/icon-web.png
+apiRefs:
+ - android:android.service.media.MediaBrowserService
+ - android:android.media.browse.MediaBrowser
+ - android:android.media.session.MediaSession
+ - android:android.media.session.MediaController
+ - android:android.app.Notification.MediaStyle
license: apache2
diff --git a/prebuilts/gradle/MediaBrowserService/Application/build.gradle b/prebuilts/gradle/MediaBrowserService/Application/build.gradle
index 07e791da..bfccf049 100644
--- a/prebuilts/gradle/MediaBrowserService/Application/build.gradle
+++ b/prebuilts/gradle/MediaBrowserService/Application/build.gradle
@@ -13,9 +13,9 @@ apply plugin: 'com.android.application'
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/MediaBrowserService/Application/src/main/java/com/example/android/mediabrowserservice/MediaNotification.java b/prebuilts/gradle/MediaBrowserService/Application/src/main/java/com/example/android/mediabrowserservice/MediaNotification.java
index 4456fdac..68727239 100644
--- a/prebuilts/gradle/MediaBrowserService/Application/src/main/java/com/example/android/mediabrowserservice/MediaNotification.java
+++ b/prebuilts/gradle/MediaBrowserService/Application/src/main/java/com/example/android/mediabrowserservice/MediaNotification.java
@@ -37,7 +37,6 @@ import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.os.AsyncTask;
import android.util.LruCache;
-import android.util.SparseArray;
import com.example.android.mediabrowserservice.utils.BitmapHelper;
import com.example.android.mediabrowserservice.utils.LogHelper;
@@ -65,7 +64,6 @@ public class MediaNotification extends BroadcastReceiver {
private MediaSession.Token mSessionToken;
private MediaController mController;
private MediaController.TransportControls mTransportControls;
- private final SparseArray<PendingIntent> mIntents = new SparseArray<PendingIntent>();
private final LruCache<String, Bitmap> mAlbumArtCache;
private PlaybackState mPlaybackState;
@@ -75,6 +73,8 @@ public class MediaNotification extends BroadcastReceiver {
private NotificationManager mNotificationManager;
private Notification.Action mPlayPauseAction;
+ private PendingIntent mPauseIntent, mPlayIntent, mPreviousIntent, mNextIntent;
+
private String mCurrentAlbumArt;
private int mNotificationColor;
@@ -99,14 +99,14 @@ public class MediaNotification extends BroadcastReceiver {
.getSystemService(Context.NOTIFICATION_SERVICE);
String pkg = mService.getPackageName();
- mIntents.put(R.drawable.ic_pause_white_24dp, PendingIntent.getBroadcast(mService, 100,
- new Intent(ACTION_PAUSE).setPackage(pkg), PendingIntent.FLAG_CANCEL_CURRENT));
- mIntents.put(R.drawable.ic_play_arrow_white_24dp, PendingIntent.getBroadcast(mService, 100,
- new Intent(ACTION_PLAY).setPackage(pkg), PendingIntent.FLAG_CANCEL_CURRENT));
- mIntents.put(R.drawable.ic_skip_previous_white_24dp, PendingIntent.getBroadcast(mService, 100,
- new Intent(ACTION_PREV).setPackage(pkg), PendingIntent.FLAG_CANCEL_CURRENT));
- mIntents.put(R.drawable.ic_skip_next_white_24dp, PendingIntent.getBroadcast(mService, 100,
- new Intent(ACTION_NEXT).setPackage(pkg), PendingIntent.FLAG_CANCEL_CURRENT));
+ mPauseIntent = PendingIntent.getBroadcast(mService, 100,
+ new Intent(ACTION_PAUSE).setPackage(pkg), PendingIntent.FLAG_CANCEL_CURRENT);
+ mPlayIntent = PendingIntent.getBroadcast(mService, 100,
+ new Intent(ACTION_PLAY).setPackage(pkg), PendingIntent.FLAG_CANCEL_CURRENT);
+ mPreviousIntent = PendingIntent.getBroadcast(mService, 100,
+ new Intent(ACTION_PREV).setPackage(pkg), PendingIntent.FLAG_CANCEL_CURRENT);
+ mNextIntent = PendingIntent.getBroadcast(mService, 100,
+ new Intent(ACTION_NEXT).setPackage(pkg), PendingIntent.FLAG_CANCEL_CURRENT);
}
protected int getNotificationColor() {
@@ -241,8 +241,7 @@ public class MediaNotification extends BroadcastReceiver {
if ((mPlaybackState.getActions() & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0) {
mNotificationBuilder
.addAction(R.drawable.ic_skip_previous_white_24dp,
- mService.getString(R.string.label_previous),
- mIntents.get(R.drawable.ic_skip_previous_white_24dp));
+ mService.getString(R.string.label_previous), mPreviousIntent);
playPauseActionIndex = 1;
}
@@ -251,8 +250,7 @@ public class MediaNotification extends BroadcastReceiver {
// If skip to next action is enabled
if ((mPlaybackState.getActions() & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) {
mNotificationBuilder.addAction(R.drawable.ic_skip_next_white_24dp,
- mService.getString(R.string.label_next),
- mIntents.get(R.drawable.ic_skip_next_white_24dp));
+ mService.getString(R.string.label_next), mNextIntent);
}
MediaDescription description = mMetadata.getDescription();
@@ -294,22 +292,24 @@ public class MediaNotification extends BroadcastReceiver {
private void updatePlayPauseAction() {
LogHelper.d(TAG, "updatePlayPauseAction");
- String playPauseLabel = "";
- int playPauseIcon;
+ String label;
+ int icon;
+ PendingIntent intent;
if (mPlaybackState.getState() == PlaybackState.STATE_PLAYING) {
- playPauseLabel = mService.getString(R.string.label_pause);
- playPauseIcon = R.drawable.ic_pause_white_24dp;
+ label = mService.getString(R.string.label_pause);
+ icon = R.drawable.ic_pause_white_24dp;
+ intent = mPauseIntent;
} else {
- playPauseLabel = mService.getString(R.string.label_play);
- playPauseIcon = R.drawable.ic_play_arrow_white_24dp;
+ label = mService.getString(R.string.label_play);
+ icon = R.drawable.ic_play_arrow_white_24dp;
+ intent = mPlayIntent;
}
if (mPlayPauseAction == null) {
- mPlayPauseAction = new Notification.Action(playPauseIcon, playPauseLabel,
- mIntents.get(playPauseIcon));
+ mPlayPauseAction = new Notification.Action(icon, label, intent);
} else {
- mPlayPauseAction.icon = playPauseIcon;
- mPlayPauseAction.title = playPauseLabel;
- mPlayPauseAction.actionIntent = mIntents.get(playPauseIcon);
+ mPlayPauseAction.icon = icon;
+ mPlayPauseAction.title = label;
+ mPlayPauseAction.actionIntent = intent;
}
}
diff --git a/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-hdpi/ic_launcher.png
index 47d6854e..05ef6f65 100644
--- a/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-hdpi/ic_launcher.png
+++ b/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-mdpi/ic_launcher.png
index 01b53fd5..f894fb84 100644
--- a/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-mdpi/ic_launcher.png
+++ b/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xhdpi/ic_launcher.png
index af762f2b..43ade5e6 100644
--- a/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xhdpi/ic_launcher.png
+++ b/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
index eef47aa3..3058c27f 100644
--- a/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
+++ b/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xxxhdpi/ic_launcher.png b/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xxxhdpi/ic_launcher.png
new file mode 100644
index 00000000..6b4e4a21
--- /dev/null
+++ b/prebuilts/gradle/MediaBrowserService/Application/src/main/res/drawable-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MediaBrowserService/README.md b/prebuilts/gradle/MediaBrowserService/README.md
index 0072d93a..d3426511 100644
--- a/prebuilts/gradle/MediaBrowserService/README.md
+++ b/prebuilts/gradle/MediaBrowserService/README.md
@@ -12,6 +12,62 @@ connected to Android Auto, the same service provides data and callback
to the Android Auto UI in the same manner as it provides them to the
local UI.
+Introduction
+------------
+
+To implement a MediaBrowserService, you need to:
+
+- Extend android.service.media.MediaBrowserService, implementing the media
+ browsing related methods onGetRoot and onLoadChildren;
+
+- In onCreate, start a new MediaSession and call super.setSessionToken() with
+ this MediaSession's token;
+
+- Set a MediaSession.Callback class on the MediaSession. The callback class
+ will receive all the user's actions, like play, pause, etc;
+
+- Handle all the actual music playing using any method your app prefers
+ (for example, the Android MediaPlayer class)
+
+- Whenever it changes, update info about the playing item and the playing
+ queue using MediaSession corresponding methods (setMetadata,
+ setPlaybackState, setQueue, setQueueTitle, etc)
+
+- Handle AudioManager focus change events and react appropriately
+ (e.g. pause when audio focus is lost)
+
+
+To make it compatible with Android Auto, you also need to:
+
+- Declare a meta-data tag in AndroidManifest.xml linking to a xml resource
+ with a automotiveApp root element. For a media app, this must include
+ an &lt;uses name="media"/&gt; element as a child.
+
+ For example, in AndroidManifest.xml:
+```
+ <meta-data android:name="com.google.android.gms.car.application"
+ android:resource="@xml/automotive_app_desc"/>
+```
+
+ And in res/xml/automotive\_app\_desc.xml:
+```
+ <?xml version="1.0" encoding="utf-8"?>
+ <automotiveApp>
+ <uses name="media"/>
+ </automotiveApp>
+```
+
+- Declare and export the service in AndroidManifest.xml:
+```
+ <service
+ android:name=".service.MusicService"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.media.browse.MediaBrowserService" />
+ </intent-filter>
+ </service>
+```
+
Pre-requisites
--------------
@@ -19,6 +75,11 @@ Pre-requisites
- Android Build Tools v21.1.1
- Android Support Repository
+Screenshots
+-------------
+
+<img src="screenshots/1-main.png" height="400" alt="Screenshot"/> <img src="screenshots/2-music-play.png" height="400" alt="Screenshot"/> <img src="screenshots/3-music-notification.png" height="400" alt="Screenshot"/>
+
Getting Started
---------------
diff --git a/prebuilts/gradle/MediaBrowserService/screenshots/1-main.png b/prebuilts/gradle/MediaBrowserService/screenshots/1-main.png
new file mode 100644
index 00000000..1b17d0e7
--- /dev/null
+++ b/prebuilts/gradle/MediaBrowserService/screenshots/1-main.png
Binary files differ
diff --git a/prebuilts/gradle/MediaBrowserService/screenshots/2-music-play.png b/prebuilts/gradle/MediaBrowserService/screenshots/2-music-play.png
new file mode 100644
index 00000000..1c1439cf
--- /dev/null
+++ b/prebuilts/gradle/MediaBrowserService/screenshots/2-music-play.png
Binary files differ
diff --git a/prebuilts/gradle/MediaBrowserService/screenshots/3-music-notification.png b/prebuilts/gradle/MediaBrowserService/screenshots/3-music-notification.png
new file mode 100644
index 00000000..c86c045f
--- /dev/null
+++ b/prebuilts/gradle/MediaBrowserService/screenshots/3-music-notification.png
Binary files differ
diff --git a/prebuilts/gradle/MediaBrowserService/screenshots/icon-web.png b/prebuilts/gradle/MediaBrowserService/screenshots/icon-web.png
new file mode 100644
index 00000000..99928a86
--- /dev/null
+++ b/prebuilts/gradle/MediaBrowserService/screenshots/icon-web.png
Binary files differ
diff --git a/prebuilts/gradle/MediaEffects/Application/build.gradle b/prebuilts/gradle/MediaEffects/Application/build.gradle
index 0427861a..37884d80 100644
--- a/prebuilts/gradle/MediaEffects/Application/build.gradle
+++ b/prebuilts/gradle/MediaEffects/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/MediaRecorder/Application/build.gradle b/prebuilts/gradle/MediaRecorder/Application/build.gradle
index 0427861a..37884d80 100644
--- a/prebuilts/gradle/MediaRecorder/Application/build.gradle
+++ b/prebuilts/gradle/MediaRecorder/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/MediaRouter/Application/build.gradle b/prebuilts/gradle/MediaRouter/Application/build.gradle
index f2fbc366..254d247b 100644
--- a/prebuilts/gradle/MediaRouter/Application/build.gradle
+++ b/prebuilts/gradle/MediaRouter/Application/build.gradle
@@ -17,12 +17,12 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
- compile "com.android.support:appcompat-v7:20.+"
- compile "com.android.support:mediarouter-v7:20.+"
+ compile "com.android.support:appcompat-v7:21.0.2"
+ compile "com.android.support:mediarouter-v7:21.0.2"
}
// The sample build uses multiple directories to
diff --git a/prebuilts/gradle/MessagingService/Application/build.gradle b/prebuilts/gradle/MessagingService/Application/build.gradle
index 07e791da..bfccf049 100644
--- a/prebuilts/gradle/MessagingService/Application/build.gradle
+++ b/prebuilts/gradle/MessagingService/Application/build.gradle
@@ -13,9 +13,9 @@ apply plugin: 'com.android.application'
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-hdpi/ic_launcher.png
index 06d85f16..506cbc5a 100644
--- a/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-hdpi/ic_launcher.png
+++ b/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-mdpi/ic_launcher.png
index 4e1cc86b..6296a036 100644
--- a/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-mdpi/ic_launcher.png
+++ b/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-xhdpi/ic_launcher.png
index 92f1e2dd..52d3c5ec 100644
--- a/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-xhdpi/ic_launcher.png
+++ b/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
index 2476cbdd..444fb390 100644
--- a/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
+++ b/prebuilts/gradle/MessagingService/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MessagingService/README.md b/prebuilts/gradle/MessagingService/README.md
index bc7a3657..698adf40 100644
--- a/prebuilts/gradle/MessagingService/README.md
+++ b/prebuilts/gradle/MessagingService/README.md
@@ -9,16 +9,38 @@ Each unread conversation from a user is sent as a distinct notification.
Introduction
------------
-This sample shows a simple service that sends [notifications][1] using
-NotificationCompat.
-
-In addition to sending a notification, it also extends
-the notification with a [CarExtender][2] to make it compatible with Android Auto.
-
-Each unread conversation from a user is sent as a distinct notification.
-
-[1]: https://developer.android.com/guide/topics/ui/notifiers/notifications.html
-[2]: https://developer.android.com/reference/android/support/v4/app/NotificationCompat.CarExtender.html
+#### Checklist while building a messaging app that supports Android Auto:
+1. Ensure that Message notifications are extended using
+NotificationCompat.Builder.extend(new CarExtender()...)
+2. Declare a meta-data tag to your AndroidManifest.xml to specify that your app
+is automotive enabled.
+
+example: AndroidManifest.xml
+
+```
+ <meta-data android:name="com.google.android.gms.car.application"
+ android:resource="@xml/automotive_app_desc"/>
+```
+
+Include the following to indicate that the application wants to show notifications on
+the Android Auto overview screen.
+
+example: res/xml/automotive\_app\_desc.xml
+```
+ <automotiveApp>
+ <uses name="notification"/>
+ </automotiveApp>
+```
+
+#### Flow
+MessagingFragment is shown to the user. Depending on the button clicked, the MessagingService is
+sent a message. MessagingService in turn creates notifications which can be viewed either on the
+device or in the messaging-simulator.
+
+When a message is read, the associated PendingIntent is triggered and MessageReadReceiver is called
+with the appropriate conversationId. Similarly, when a reply is received, the MessageReplyReceiver
+is called with the appropriate conversationId. MessageLogger logs each event and shows them in a
+TextView in MessagingFragment for correlation.
Pre-requisites
--------------
diff --git a/prebuilts/gradle/MessagingService/screenshots/icon-web.png b/prebuilts/gradle/MessagingService/screenshots/icon-web.png
index 2476cbdd..3dfd2ec8 100644
--- a/prebuilts/gradle/MessagingService/screenshots/icon-web.png
+++ b/prebuilts/gradle/MessagingService/screenshots/icon-web.png
Binary files differ
diff --git a/prebuilts/gradle/NavigationDrawer/Application/build.gradle b/prebuilts/gradle/NavigationDrawer/Application/build.gradle
index c68979c3..bff2be09 100644
--- a/prebuilts/gradle/NavigationDrawer/Application/build.gradle
+++ b/prebuilts/gradle/NavigationDrawer/Application/build.gradle
@@ -18,10 +18,10 @@ repositories {
dependencies {
- compile "com.android.support:support-v13:20.+"
- compile "com.android.support:appcompat-v7:20.+"
- compile "com.android.support:recyclerview-v7:+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:appcompat-v7:21.0.2"
+ compile "com.android.support:recyclerview-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
// The sample build uses multiple directories to
diff --git a/prebuilts/gradle/NetworkConnect/Application/build.gradle b/prebuilts/gradle/NetworkConnect/Application/build.gradle
index 90737fcc..3e25a83b 100644
--- a/prebuilts/gradle/NetworkConnect/Application/build.gradle
+++ b/prebuilts/gradle/NetworkConnect/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/PdfRendererBasic/Application/build.gradle b/prebuilts/gradle/PdfRendererBasic/Application/build.gradle
index e77578c4..e86efa99 100644
--- a/prebuilts/gradle/PdfRendererBasic/Application/build.gradle
+++ b/prebuilts/gradle/PdfRendererBasic/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/PermissionRequest/.google/packaging.yaml b/prebuilts/gradle/PermissionRequest/.google/packaging.yaml
new file mode 100644
index 00000000..fc79469a
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/.google/packaging.yaml
@@ -0,0 +1,18 @@
+# GOOGLE SAMPLE PACKAGING DATA
+#
+# This file is used by Google as part of our samples packaging process.
+# End users may safely ignore this file. It has no relevance to other systems.
+---
+status: PUBLISHED
+technologies: [Android]
+categories: [Content]
+languages: [Java]
+solutions: [Mobile]
+github: android-PermissionRequest
+level: INTERMEDIATE
+icon: screenshots/icon_web.png
+apiRefs:
+ - android:android.webkit.PermissionRequest
+ - android:android.webkit.WebView
+ - android:android.webkit.WebChromeClient
+license: apache2
diff --git a/prebuilts/gradle/PermissionRequest/Application/build.gradle b/prebuilts/gradle/PermissionRequest/Application/build.gradle
new file mode 100644
index 00000000..71ddf508
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/build.gradle
@@ -0,0 +1,70 @@
+buildscript {
+ repositories {
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+ }
+}
+
+apply plugin: 'com.android.application'
+
+repositories {
+ jcenter()
+}
+
+
+dependencies {
+
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
+
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.1"
+
+ defaultConfig {
+ minSdkVersion 21
+ targetSdkVersion 21
+ }
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ androidTest.setRoot('tests')
+ androidTest.java.srcDirs = ['tests/src']
+
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/AndroidManifest.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..f8fd050c
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.permissionrequest"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.CAMERA"/>
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ 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>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/assets/sample.css b/prebuilts/gradle/PermissionRequest/Application/src/main/assets/sample.css
new file mode 100644
index 00000000..9d1364ce
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/assets/sample.css
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+body {
+ text-align: center;
+}
+
+div {
+ margin-bottom: 8px;
+}
+
+button {
+ height: 48px;
+ width: 80px;
+ font-weight: bold;
+ font-size: 14pt;
+}
+
+video {
+ width: 240px;
+ height: 180px;
+ transform: scaleX(-1); /* Mirror */
+}
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/assets/sample.html b/prebuilts/gradle/PermissionRequest/Application/src/main/assets/sample.html
new file mode 100644
index 00000000..a9729a33
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/assets/sample.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!--
+ 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.
+-->
+<html>
+<head>
+ <title>sample</title>
+ <link rel="stylesheet" href="sample.css">
+</head>
+<body>
+
+<div>
+ <button id="toggle">Start</button>
+</div>
+<video id="video" autoplay></video>
+
+<script src="sample.js"></script>
+</body>
+</html>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/assets/sample.js b/prebuilts/gradle/PermissionRequest/Application/src/main/assets/sample.js
new file mode 100644
index 00000000..e2806a0d
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/assets/sample.js
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+(function () {
+ "use strict";
+
+ navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
+ window.URL = window.URL || window.webkitURL;
+
+ window.onload = function () {
+
+ var video = document.querySelector('#video'),
+ toggle = document.querySelector('#toggle'),
+ stream = null;
+
+ if (!navigator.getUserMedia) {
+ console.error('getUserMedia not supported');
+ }
+
+ toggle.addEventListener('click', function () {
+ if (null === stream) {
+ // This call to "getUserMedia" initiates a PermissionRequest in the WebView.
+ navigator.getUserMedia({ video: true }, function (s) {
+ stream = s;
+ video.src = window.URL.createObjectURL(stream);
+ toggle.innerText = 'Stop';
+ console.log('Started');
+ }, function (error) {
+ console.error('Error starting camera. Denied.');
+ });
+ } else {
+ stream.stop();
+ stream = null;
+ toggle.innerText = 'Start';
+ console.log('Stopped');
+ }
+ });
+
+ console.log('Page loaded');
+
+ };
+
+})();
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 00000000..3228927b
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* 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.
+*/
+
+package com.example.android.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 00000000..17503c56
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 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.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 00000000..b302acd4
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* 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.
+*/
+/*
+ * 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.
+ */
+
+package com.example.android.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+} \ No newline at end of file
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 00000000..bc37cabc
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 00000000..c01542b9
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 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.
+ */
+package com.example.android.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 00000000..16a9e7ba
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 00000000..19967dcd
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 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.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/ConfirmationDialogFragment.java b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/ConfirmationDialogFragment.java
new file mode 100644
index 00000000..7dae56ef
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/ConfirmationDialogFragment.java
@@ -0,0 +1,79 @@
+/*
+ * 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.permissionrequest;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.text.TextUtils;
+
+/**
+ * Prompts the user to confirm permission request.
+ */
+public class ConfirmationDialogFragment extends DialogFragment {
+
+ private static final String ARG_RESOURCES = "resources";
+
+ /**
+ * Creates a new instance of ConfirmationDialogFragment.
+ *
+ * @param resources The list of resources requested by PermissionRequeste.
+ * @return A new instance.
+ */
+ public static ConfirmationDialogFragment newInstance(String[] resources) {
+ ConfirmationDialogFragment fragment = new ConfirmationDialogFragment();
+ Bundle args = new Bundle();
+ args.putStringArray(ARG_RESOURCES, resources);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ String[] resources = getArguments().getStringArray(ARG_RESOURCES);
+ return new AlertDialog.Builder(getActivity())
+ .setMessage(getString(R.string.confirmation, TextUtils.join("\n", resources)))
+ .setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ ((Listener) getParentFragment()).onConfirmation(false);
+ }
+ })
+ .setPositiveButton(R.string.allow, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ ((Listener) getParentFragment()).onConfirmation(true);
+ }
+ })
+ .create();
+ }
+
+ /**
+ * Callback for the user's response.
+ */
+ public interface Listener {
+
+ /**
+ * Called when the PermissoinRequest is allowed or denied by the user.
+ *
+ * @param allowed True if the user allowed the request.
+ */
+ public void onConfirmation(boolean allowed);
+ }
+
+}
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/MainActivity.java b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/MainActivity.java
new file mode 100644
index 00000000..a11849fc
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/MainActivity.java
@@ -0,0 +1,109 @@
+/*
+* 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.
+*/
+
+package com.example.android.permissionrequest;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ViewAnimator;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description, sample log and a custom
+ * {@link android.support.v4.app.Fragment} which can display a view.
+ * <p>
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ // Whether the Log Fragment is currently shown
+ private boolean mLogShown;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ if (savedInstanceState == null) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ PermissionRequestFragment fragment = new PermissionRequestFragment();
+ transaction.replace(R.id.sample_content_fragment, fragment);
+ transaction.commit();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+ logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+ logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+ return super.onPrepareOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case R.id.menu_toggle_log:
+ mLogShown = !mLogShown;
+ ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+ if (mLogShown) {
+ output.setDisplayedChild(1);
+ } else {
+ output.setDisplayedChild(0);
+ }
+ supportInvalidateOptionsMenu();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/PermissionRequestFragment.java b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/PermissionRequestFragment.java
new file mode 100644
index 00000000..44f1d6ec
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/PermissionRequestFragment.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.permissionrequest;
+
+import android.annotation.SuppressLint;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.ConsoleMessage;
+import android.webkit.PermissionRequest;
+import android.webkit.WebChromeClient;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+
+import com.example.android.common.logger.Log;
+
+/**
+ * This fragment shows a {@link WebView} and loads a web app from the {@link SimpleWebServer}.
+ */
+public class PermissionRequestFragment extends Fragment
+ implements ConfirmationDialogFragment.Listener {
+
+ private static final String TAG = PermissionRequestFragment.class.getSimpleName();
+
+ private static final String FRAGMENT_DIALOG = "dialog";
+
+ /**
+ * We use this web server to serve HTML files in the assets folder. This is because we cannot
+ * use the JavaScript method "getUserMedia" from "file:///android_assets/..." URLs.
+ */
+ private SimpleWebServer mWebServer;
+
+ /**
+ * A reference to the {@link WebView}.
+ */
+ private WebView mWebView;
+
+ /**
+ * This field stores the {@link PermissionRequest} from the web application until it is allowed
+ * or denied by user.
+ */
+ private PermissionRequest mPermissionRequest;
+
+ /**
+ * For testing.
+ */
+ private ConsoleMonitor mConsoleMonitor;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_permission_request, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ mWebView = (WebView) view.findViewById(R.id.web_view);
+ // Here, we use #mWebChromeClient with implementation for handling PermissionRequests.
+ mWebView.setWebChromeClient(mWebChromeClient);
+ configureWebSettings(mWebView.getSettings());
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ final int port = 8080;
+ mWebServer = new SimpleWebServer(port, getResources().getAssets());
+ mWebServer.start();
+ mWebView.loadUrl("http://localhost:" + port + "/sample.html");
+ }
+
+ @Override
+ public void onPause() {
+ mWebServer.stop();
+ super.onPause();
+ }
+
+ @SuppressLint("SetJavaScriptEnabled")
+ private static void configureWebSettings(WebSettings settings) {
+ settings.setJavaScriptEnabled(true);
+ }
+
+ /**
+ * This {@link WebChromeClient} has implementation for handling {@link PermissionRequest}.
+ */
+ private WebChromeClient mWebChromeClient = new WebChromeClient() {
+
+ // This method is called when the web content is requesting permission to access some
+ // resources.
+ @Override
+ public void onPermissionRequest(PermissionRequest request) {
+ Log.i(TAG, "onPermissionRequest");
+ mPermissionRequest = request;
+ ConfirmationDialogFragment.newInstance(request.getResources())
+ .show(getChildFragmentManager(), FRAGMENT_DIALOG);
+ }
+
+ // This method is called when the permission request is canceled by the web content.
+ @Override
+ public void onPermissionRequestCanceled(PermissionRequest request) {
+ Log.i(TAG, "onPermissionRequestCanceled");
+ // We dismiss the prompt UI here as the request is no longer valid.
+ mPermissionRequest = null;
+ DialogFragment fragment = (DialogFragment) getChildFragmentManager()
+ .findFragmentByTag(FRAGMENT_DIALOG);
+ if (null != fragment) {
+ fragment.dismiss();
+ }
+ }
+
+ @Override
+ public boolean onConsoleMessage(@NonNull ConsoleMessage message) {
+ switch (message.messageLevel()) {
+ case TIP:
+ Log.v(TAG, message.message());
+ break;
+ case LOG:
+ Log.i(TAG, message.message());
+ break;
+ case WARNING:
+ Log.w(TAG, message.message());
+ break;
+ case ERROR:
+ Log.e(TAG, message.message());
+ break;
+ case DEBUG:
+ Log.d(TAG, message.message());
+ break;
+ }
+ if (null != mConsoleMonitor) {
+ mConsoleMonitor.onConsoleMessage(message);
+ }
+ return true;
+ }
+
+ };
+
+ @Override
+ public void onConfirmation(boolean allowed) {
+ if (allowed) {
+ mPermissionRequest.grant(mPermissionRequest.getResources());
+ Log.d(TAG, "Permission granted.");
+ } else {
+ mPermissionRequest.deny();
+ Log.d(TAG, "Permission request denied.");
+ }
+ mPermissionRequest = null;
+ }
+
+ public void setConsoleMonitor(ConsoleMonitor monitor) {
+ mConsoleMonitor = monitor;
+ }
+
+ /**
+ * For testing.
+ */
+ public interface ConsoleMonitor {
+ public void onConsoleMessage(ConsoleMessage message);
+ }
+
+}
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/SimpleWebServer.java b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/SimpleWebServer.java
new file mode 100644
index 00000000..36b7c469
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/java/com/example/android/permissionrequest/SimpleWebServer.java
@@ -0,0 +1,222 @@
+/*
+ * 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.permissionrequest;
+
+import android.content.res.AssetManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+
+/**
+ * Implementation of a very basic HTTP server. The contents are loaded from the assets folder. This
+ * server handles one request at a time. It only supports GET method.
+ */
+public class SimpleWebServer implements Runnable {
+
+ private static final String TAG = "SimpleWebServer";
+
+ /**
+ * The port number we listen to
+ */
+ private final int mPort;
+
+ /**
+ * {@link android.content.res.AssetManager} for loading files to serve.
+ */
+ private final AssetManager mAssets;
+
+ /**
+ * True if the server is running.
+ */
+ private boolean mIsRunning;
+
+ /**
+ * The {@link java.net.ServerSocket} that we listen to.
+ */
+ private ServerSocket mServerSocket;
+
+ /**
+ * WebServer constructor.
+ */
+ public SimpleWebServer(int port, AssetManager assets) {
+ mPort = port;
+ mAssets = assets;
+ }
+
+ /**
+ * This method starts the web server listening to the specified port.
+ */
+ public void start() {
+ mIsRunning = true;
+ new Thread(this).start();
+ }
+
+ /**
+ * This method stops the web server
+ */
+ public void stop() {
+ try {
+ mIsRunning = false;
+ if (null != mServerSocket) {
+ mServerSocket.close();
+ mServerSocket = null;
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Error closing the server socket.", e);
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+ mServerSocket = new ServerSocket(mPort);
+ while (mIsRunning) {
+ Socket socket = mServerSocket.accept();
+ handle(socket);
+ socket.close();
+ }
+ } catch (SocketException e) {
+ // The server was stopped; ignore.
+ } catch (IOException e) {
+ Log.e(TAG, "Web server error.", e);
+ }
+ }
+
+ /**
+ * Respond to a request from a client.
+ *
+ * @param socket The client socket.
+ * @throws IOException
+ */
+ private void handle(Socket socket) throws IOException {
+ BufferedReader reader = null;
+ PrintStream output = null;
+ try {
+ String route = null;
+
+ // Read HTTP headers and parse out the route.
+ reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ String line;
+ while (!TextUtils.isEmpty(line = reader.readLine())) {
+ if (line.startsWith("GET /")) {
+ int start = line.indexOf('/') + 1;
+ int end = line.indexOf(' ', start);
+ route = line.substring(start, end);
+ break;
+ }
+ }
+
+ // Output stream that we send the response to
+ output = new PrintStream(socket.getOutputStream());
+
+ // Prepare the content to send.
+ if (null == route) {
+ writeServerError(output);
+ return;
+ }
+ byte[] bytes = loadContent(route);
+ if (null == bytes) {
+ writeServerError(output);
+ return;
+ }
+
+ // Send out the content.
+ output.println("HTTP/1.0 200 OK");
+ output.println("Content-Type: " + detectMimeType(route));
+ output.println("Content-Length: " + bytes.length);
+ output.println();
+ output.write(bytes);
+ output.flush();
+ } finally {
+ if (null != output) {
+ output.close();
+ }
+ if (null != reader) {
+ reader.close();
+ }
+ }
+ }
+
+ /**
+ * Writes a server error response (HTTP/1.0 500) to the given output stream.
+ *
+ * @param output The output stream.
+ */
+ private void writeServerError(PrintStream output) {
+ output.println("HTTP/1.0 500 Internal Server Error");
+ output.flush();
+ }
+
+ /**
+ * Loads all the content of {@code fileName}.
+ *
+ * @param fileName The name of the file.
+ * @return The content of the file.
+ * @throws IOException
+ */
+ private byte[] loadContent(String fileName) throws IOException {
+ InputStream input = null;
+ try {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ input = mAssets.open(fileName);
+ byte[] buffer = new byte[1024];
+ int size;
+ while (-1 != (size = input.read(buffer))) {
+ output.write(buffer, 0, size);
+ }
+ output.flush();
+ return output.toByteArray();
+ } catch (FileNotFoundException e) {
+ return null;
+ } finally {
+ if (null != input) {
+ input.close();
+ }
+ }
+ }
+
+ /**
+ * Detects the MIME type from the {@code fileName}.
+ *
+ * @param fileName The name of the file.
+ * @return A MIME type.
+ */
+ private String detectMimeType(String fileName) {
+ if (TextUtils.isEmpty(fileName)) {
+ return null;
+ } else if (fileName.endsWith(".html")) {
+ return "text/html";
+ } else if (fileName.endsWith(".js")) {
+ return "application/javascript";
+ } else if (fileName.endsWith(".css")) {
+ return "text/css";
+ } else {
+ return "application/octet-stream";
+ }
+ }
+
+}
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 00000000..4dae25b0
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 00000000..13586288
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 00000000..e896d49b
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 00000000..5309f55e
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 00000000..61b137b8
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/layout-w720dp/activity_main.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/layout-w720dp/activity_main.xml
new file mode 100755
index 00000000..c9a52f62
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+ 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <LinearLayout
+ android:id="@+id/sample_output"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <FrameLayout
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/margin_medium"
+ android:paddingRight="@dimen/margin_medium"
+ android:paddingTop="@dimen/margin_large"
+ android:paddingBottom="@dimen/margin_large"
+ android:text="@string/intro_message" />
+ </FrameLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="0px"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/layout/activity_main.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/layout/activity_main.xml
new file mode 100755
index 00000000..1ae4f981
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+ 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <ViewAnimator
+ android:id="@+id/sample_output"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1">
+
+ <ScrollView
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/horizontal_page_margin"
+ android:paddingRight="@dimen/horizontal_page_margin"
+ android:paddingTop="@dimen/vertical_page_margin"
+ android:paddingBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </ScrollView>
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </ViewAnimator>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="match_parent"
+ android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/layout/fragment_permission_request.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/layout/fragment_permission_request.xml
new file mode 100644
index 00000000..2e97a0ae
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/layout/fragment_permission_request.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <WebView
+ android:id="@+id/web_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+
+</LinearLayout>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/menu/main.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/menu/main.xml
new file mode 100644
index 00000000..b49c2c52
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_toggle_log"
+ android:showAsAction="always"
+ android:title="@string/sample_show_log" />
+</menu>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 00000000..22074a2b
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 00000000..03d19741
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-v11/template-styles.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-v11/template-styles.xml
new file mode 100644
index 00000000..8c1ea66f
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-v21/base-colors.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-v21/base-colors.xml
new file mode 100644
index 00000000..34c9cd13
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-v21/base-colors.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<resources>
+
+
+</resources>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-v21/base-template-styles.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-v21/base-template-styles.xml
new file mode 100644
index 00000000..0b2948f7
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values-v21/base-template-styles.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<resources>
+
+ <!-- Activity themes -->
+ <style name="Theme.Base" parent="android:Theme.Material.Light">
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/base-strings.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/base-strings.xml
new file mode 100644
index 00000000..c66a246a
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/base-strings.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<resources>
+ <string name="app_name">PermissionRequest</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample shows how to handle PermissionRequest coming from web apps inside of a
+ WebView.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/fragmentview_strings.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/fragmentview_strings.xml
new file mode 100755
index 00000000..7b9d9ec4
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/fragmentview_strings.xml
@@ -0,0 +1,19 @@
+<!--
+ 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.
+-->
+<resources>
+ <string name="sample_show_log">Show Log</string>
+ <string name="sample_hide_log">Hide Log</string>
+</resources>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/strings.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/strings.xml
new file mode 100644
index 00000000..c3e5574d
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<resources>
+ <string name="confirmation">This web page wants to use following resources:\n\n%s</string>
+ <string name="allow">Allow</string>
+ <string name="deny">Deny</string>
+</resources>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/template-dimens.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/template-dimens.xml
new file mode 100644
index 00000000..39e710b5
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/template-styles.xml b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/template-styles.xml
new file mode 100644
index 00000000..6e7d593d
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/PermissionRequest/Application/tests/src/com/example/android/permissionrequest/test/SampleTests.java b/prebuilts/gradle/PermissionRequest/Application/tests/src/com/example/android/permissionrequest/test/SampleTests.java
new file mode 100644
index 00000000..a88589b3
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/Application/tests/src/com/example/android/permissionrequest/test/SampleTests.java
@@ -0,0 +1,196 @@
+/*
+* 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.permissionrequest.test;
+
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.MotionEvent;
+import android.view.View;
+import android.webkit.ConsoleMessage;
+import android.webkit.WebView;
+
+import com.example.android.permissionrequest.ConfirmationDialogFragment;
+import com.example.android.permissionrequest.MainActivity;
+import com.example.android.permissionrequest.PermissionRequestFragment;
+import com.example.android.permissionrequest.R;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * Tests for PermissionRequest sample.
+ */
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private PermissionRequestFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTestActivity = getActivity();
+ mTestFragment = (PermissionRequestFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ public void testWebView_grantPermissionRequest() throws Throwable {
+ View view = mTestFragment.getView();
+ assertNotNull(view);
+ final WebView webView = (WebView) view.findViewById(R.id.web_view);
+ assertNotNull(webView);
+
+ final ConsoleMonitor monitor = new ConsoleMonitor();
+ mTestFragment.setConsoleMonitor(monitor);
+
+ // Click the "Start" button
+ assertTrue(monitor.waitForKeyword("Page loaded", 2000));
+ clickToggle(webView);
+
+ // Wait for the dialog
+ ConfirmationDialogFragment dialogFragment = waitForDialog();
+ assertNotNull(dialogFragment);
+
+ // Click "Allow"
+ monitor.reset();
+ clickDialogButton(dialogFragment, android.R.id.button1);
+
+ assertTrue(monitor.waitForKeyword("Started", 2000));
+
+ // Click the "Stop" button
+ monitor.reset();
+ clickToggle(webView);
+ assertTrue(monitor.waitForKeyword("Stopped", 2000));
+
+ // Click the "Start" button
+ monitor.reset();
+ clickToggle(webView);
+
+ // Wait for the dialog
+ dialogFragment = waitForDialog();
+ assertNotNull(dialogFragment);
+
+ // Click "Deny"
+ monitor.reset();
+ clickDialogButton(dialogFragment, android.R.id.button2);
+ assertTrue(monitor.waitForKeyword("Denied", 2000));
+ }
+
+ /**
+ * Click the Start/Stop button.
+ *
+ * @param webView The {@link WebView}.
+ * @throws Throwable
+ */
+ private void clickToggle(final WebView webView) throws Throwable {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Rect rect = new Rect();
+ webView.getHitRect(rect);
+ int x = rect.width() / 2;
+ int y = 100;
+ MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(),
+ SystemClock.uptimeMillis() + 100, MotionEvent.ACTION_DOWN, x, y, 0);
+ webView.dispatchTouchEvent(event);
+ event = MotionEvent.obtain(SystemClock.uptimeMillis(),
+ SystemClock.uptimeMillis() + 100, MotionEvent.ACTION_UP, x, y, 0);
+ webView.dispatchTouchEvent(event);
+ }
+ });
+ }
+
+ /**
+ * Wait for the dialog for 2 seconds (100 ms * 20 trials).
+ *
+ * @return The dialog.
+ * @throws InterruptedException
+ */
+ private ConfirmationDialogFragment waitForDialog() throws InterruptedException {
+ int count = 20;
+ ConfirmationDialogFragment dialog = null;
+ while (0 < count) {
+ dialog = (ConfirmationDialogFragment) mTestFragment.getChildFragmentManager()
+ .findFragmentByTag("dialog");
+ if (null != dialog) {
+ break;
+ }
+ Thread.sleep(100);
+ --count;
+ }
+ return dialog;
+ }
+
+ /**
+ * Press the specified button on the dialog.
+ *
+ * @param dialogFragment The dialog.
+ * @param buttonId The resource ID of the button to press.
+ * @throws Throwable
+ */
+ private void clickDialogButton(final ConfirmationDialogFragment dialogFragment,
+ final int buttonId) throws Throwable {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ dialogFragment.getDialog().findViewById(buttonId).performClick();
+ assertFalse(dialogFragment.isVisible());
+ }
+ });
+ }
+
+ private class ConsoleMonitor implements PermissionRequestFragment.ConsoleMonitor {
+
+ private final ConcurrentLinkedQueue<String> mMessages = new ConcurrentLinkedQueue<String>();
+
+ @Override
+ public void onConsoleMessage(ConsoleMessage message) {
+ mMessages.offer(message.message());
+ }
+
+ public boolean waitForKeyword(String keyword, long timeoutMs) throws InterruptedException {
+ long time = 0;
+ while (time < timeoutMs) {
+ String message;
+ while (null != (message = mMessages.poll())) {
+ if (message.contains(keyword)) {
+ return true;
+ }
+ }
+ Thread.sleep(100);
+ time += 100;
+ }
+ return false;
+ }
+
+ public void reset() {
+ mMessages.clear();
+ }
+
+ }
+
+}
diff --git a/prebuilts/gradle/PermissionRequest/CONTRIBUTING.md b/prebuilts/gradle/PermissionRequest/CONTRIBUTING.md
new file mode 100644
index 00000000..faa8b5c6
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/CONTRIBUTING.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://cla.developers.google.com).
+ * 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://cla.developers.google.com).
+
+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/prebuilts/gradle/PermissionRequest/LICENSE b/prebuilts/gradle/PermissionRequest/LICENSE
new file mode 100644
index 00000000..1af981f5
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/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/prebuilts/gradle/PermissionRequest/NOTICE b/prebuilts/gradle/PermissionRequest/NOTICE
new file mode 100644
index 00000000..7eede3de
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/NOTICE
@@ -0,0 +1,15 @@
+This sample uses the following software:
+
+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/prebuilts/gradle/PermissionRequest/README.md b/prebuilts/gradle/PermissionRequest/README.md
new file mode 100644
index 00000000..841159cb
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/README.md
@@ -0,0 +1,93 @@
+Android PermissionRequest Sample
+===================================
+
+This sample demonstrates how to use the PermissionRequest API to
+securely provide access to restricted system features (such as a
+camera or microphone) from within a WebView. In this example, a dialog
+is created to allow users to explicitly approve or reject each
+request.
+
+Introduction
+------------
+
+PermissionRequest can be used by setting up a custom WebChromeClient.
+
+```java
+mWebView.setWebChromeClient(mWebChromeClient);
+```
+
+In you WebChromeClient implementation, you need to override
+[onPermissionRequest][1]. This method is called when the web content
+is requesting permission to access some resources, providing an
+opportunity to approve or reject the request. In this implementation,
+we display a dialog to allow the user to approve or reject any
+request. In other applications, you may want to implement a whitelist
+of allowed APIs. Also, override [onPermissionRequestCanceled][2] for
+handling cancellation of the PermissionRequest by the web content.
+
+When the user confirms or denies the request, you can respond back to
+the web content by [grant][3] or [deny][4] respectively.
+
+```java
+mPermissionRequest.grant(mPermissionRequest.getResources());
+```
+
+This sample provides the web content from the assets folder in the
+app. Since WebView is not allowed to use getUserMedia from a "file://"
+URL, the app uses the SimpleWebServer class to provide the content via
+"http://localhost".
+
+[1]: http://developer.android.com/reference/android/webkit/WebChromeClient.html#onPermissionRequest(android.webkit.PermissionRequest)
+[2]: http://developer.android.com/reference/android/webkit/WebChromeClient.html#onPermissionRequestCanceled(android.webkit.PermissionRequest)
+[3]: http://developer.android.com/reference/android/webkit/PermissionRequest.html#grant(java.lang.String[])
+[4]: http://developer.android.com/reference/android/webkit/PermissionRequest.html#deny()
+
+Pre-requisites
+--------------
+
+- Android SDK v21
+- Android Build Tools v21.1.1
+- Android Support Repository
+
+Screenshots
+-------------
+
+<img src="screenshots/main.png" height="400" alt="Screenshot"/>
+
+Getting Started
+---------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+Support
+-------
+
+- Google+ Community: https://plus.google.com/communities/105153134372062985968
+- Stack Overflow: http://stackoverflow.com/questions/tagged/android
+
+If you've found an error in this sample, please file an issue:
+https://github.com/googlesamples/android-PermissionRequest
+
+Patches are encouraged, and may be submitted by forking this project and
+submitting a pull request through GitHub. Please see CONTRIBUTING.md for more details.
+
+License
+-------
+
+Copyright 2014 The Android Open Source Project, Inc.
+
+Licensed to the Apache Software Foundation (ASF) under one or more contributor
+license agreements. See the NOTICE file distributed with this work for
+additional information regarding copyright ownership. The ASF licenses this
+file to you 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/prebuilts/gradle/PermissionRequest/build.gradle b/prebuilts/gradle/PermissionRequest/build.gradle
new file mode 100644
index 00000000..1dac6def
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/build.gradle
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/PermissionRequest/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/PermissionRequest/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..8c0fb64a
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/PermissionRequest/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/PermissionRequest/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..4eda7c51
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Tue Dec 09 18:05:08 JST 2014
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/prebuilts/gradle/PermissionRequest/gradlew b/prebuilts/gradle/PermissionRequest/gradlew
new file mode 100755
index 00000000..91a7e269
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/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/prebuilts/gradle/PermissionRequest/gradlew.bat b/prebuilts/gradle/PermissionRequest/gradlew.bat
new file mode 100644
index 00000000..aec99730
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/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/prebuilts/gradle/PermissionRequest/screenshots/icon_web.png b/prebuilts/gradle/PermissionRequest/screenshots/icon_web.png
new file mode 100644
index 00000000..4a8c2f10
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/screenshots/icon_web.png
Binary files differ
diff --git a/prebuilts/gradle/PermissionRequest/screenshots/image1.png b/prebuilts/gradle/PermissionRequest/screenshots/image1.png
new file mode 100644
index 00000000..9ce9fc85
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/screenshots/image1.png
Binary files differ
diff --git a/prebuilts/gradle/PermissionRequest/screenshots/image2.png b/prebuilts/gradle/PermissionRequest/screenshots/image2.png
new file mode 100644
index 00000000..e919bd1a
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/screenshots/image2.png
Binary files differ
diff --git a/prebuilts/gradle/PermissionRequest/settings.gradle b/prebuilts/gradle/PermissionRequest/settings.gradle
new file mode 100644
index 00000000..9464a359
--- /dev/null
+++ b/prebuilts/gradle/PermissionRequest/settings.gradle
@@ -0,0 +1 @@
+include 'Application'
diff --git a/prebuilts/gradle/RecipeAssistant/Application/build.gradle b/prebuilts/gradle/RecipeAssistant/Application/build.gradle
index f3cacbe1..3859b3ee 100644
--- a/prebuilts/gradle/RecipeAssistant/Application/build.gradle
+++ b/prebuilts/gradle/RecipeAssistant/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/RecyclerView/Application/build.gradle b/prebuilts/gradle/RecyclerView/Application/build.gradle
index 616b2413..2dcaf29f 100644
--- a/prebuilts/gradle/RecyclerView/Application/build.gradle
+++ b/prebuilts/gradle/RecyclerView/Application/build.gradle
@@ -17,11 +17,11 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
- compile "com.android.support:recyclerview-v7:+"
+ compile "com.android.support:recyclerview-v7:21.0.2"
}
// The sample build uses multiple directories to
diff --git a/prebuilts/gradle/RecyclerView/Application/src/main/java/com/example/android/recyclerview/RecyclerViewFragment.java b/prebuilts/gradle/RecyclerView/Application/src/main/java/com/example/android/recyclerview/RecyclerViewFragment.java
index 019657ff..1c0fdede 100644
--- a/prebuilts/gradle/RecyclerView/Application/src/main/java/com/example/android/recyclerview/RecyclerViewFragment.java
+++ b/prebuilts/gradle/RecyclerView/Application/src/main/java/com/example/android/recyclerview/RecyclerViewFragment.java
@@ -80,7 +80,7 @@ public class RecyclerViewFragment extends Fragment {
if (savedInstanceState != null) {
// Restore saved layout manager type.
mCurrentLayoutManagerType = (LayoutManagerType) savedInstanceState
- .getSerializable(LAYOUT_MANAGER_KEY);
+ .getSerializable(KEY_LAYOUT_MANAGER);
}
setRecyclerViewLayoutManager(mCurrentLayoutManagerType);
@@ -143,7 +143,7 @@ public class RecyclerViewFragment extends Fragment {
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save currently selected layout manager.
- savedInstanceState.putSerializable(LAYOUT_MANAGER_KEY, mCurrentLayoutManagerType);
+ savedInstanceState.putSerializable(KEY_LAYOUT_MANAGER, mCurrentLayoutManagerType);
super.onSaveInstanceState(savedInstanceState);
}
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/Application/build.gradle b/prebuilts/gradle/RenderScriptIntrinsic/Application/build.gradle
index fd0410df..7d56123c 100644
--- a/prebuilts/gradle/RenderScriptIntrinsic/Application/build.gradle
+++ b/prebuilts/gradle/RenderScriptIntrinsic/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
compile files('renderscript-v8.jar')
}
diff --git a/prebuilts/gradle/RepeatingAlarm/Application/build.gradle b/prebuilts/gradle/RepeatingAlarm/Application/build.gradle
index 05020be5..76169dee 100644
--- a/prebuilts/gradle/RepeatingAlarm/Application/build.gradle
+++ b/prebuilts/gradle/RepeatingAlarm/Application/build.gradle
@@ -17,7 +17,7 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
+ compile "com.android.support:support-v4:21.0.2"
}
diff --git a/prebuilts/gradle/RevealEffectBasic/Application/build.gradle b/prebuilts/gradle/RevealEffectBasic/Application/build.gradle
index 20561c2a..71ddf508 100644
--- a/prebuilts/gradle/RevealEffectBasic/Application/build.gradle
+++ b/prebuilts/gradle/RevealEffectBasic/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/ScreenCapture/.google/packaging.yaml b/prebuilts/gradle/ScreenCapture/.google/packaging.yaml
new file mode 100644
index 00000000..d33e2776
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/.google/packaging.yaml
@@ -0,0 +1,18 @@
+# GOOGLE SAMPLE PACKAGING DATA
+#
+# This file is used by Google as part of our samples packaging process.
+# End users may safely ignore this file. It has no relevance to other systems.
+---
+status: PUBLISHED
+technologies: [Android]
+categories: [Media]
+languages: [Java]
+solutions: [Mobile]
+github: android-ScreenCapture
+level: INTERMEDIATE
+icon: screenshots/icon-web.png
+apiRefs:
+ - android:android.media.projection.MediaProjection
+ - android:android.media.projection.MediaProjectionManager
+ - android:android.hardware.display.VirtualDisplay
+license: apache2
diff --git a/prebuilts/gradle/ScreenCapture/Application/build.gradle b/prebuilts/gradle/ScreenCapture/Application/build.gradle
new file mode 100644
index 00000000..71ddf508
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/build.gradle
@@ -0,0 +1,70 @@
+buildscript {
+ repositories {
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.0.0'
+ }
+}
+
+apply plugin: 'com.android.application'
+
+repositories {
+ jcenter()
+}
+
+
+dependencies {
+
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
+
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 21
+ buildToolsVersion "21.1.1"
+
+ defaultConfig {
+ minSdkVersion 21
+ targetSdkVersion 21
+ }
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ androidTest.setRoot('tests')
+ androidTest.java.srcDirs = ['tests/src']
+
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/AndroidManifest.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..2dfd4f70
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.screencapture">
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ 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>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 00000000..3228927b
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* 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.
+*/
+
+package com.example.android.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 00000000..17503c56
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 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.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 00000000..b302acd4
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* 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.
+*/
+/*
+ * 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.
+ */
+
+package com.example.android.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+} \ No newline at end of file
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 00000000..bc37cabc
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 00000000..c01542b9
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 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.
+ */
+package com.example.android.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 00000000..16a9e7ba
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 00000000..19967dcd
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 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.
+ */
+package com.example.android.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/screencapture/MainActivity.java b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/screencapture/MainActivity.java
new file mode 100644
index 00000000..67ae9e89
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/screencapture/MainActivity.java
@@ -0,0 +1,109 @@
+/*
+* 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.
+*/
+
+package com.example.android.screencapture;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ViewAnimator;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description, sample log and a custom
+ * {@link android.support.v4.app.Fragment} which can display a view.
+ * <p>
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ // Whether the Log Fragment is currently shown
+ private boolean mLogShown;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ if (savedInstanceState == null) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ ScreenCaptureFragment fragment = new ScreenCaptureFragment();
+ transaction.replace(R.id.sample_content_fragment, fragment);
+ transaction.commit();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+ logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+ logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+ return super.onPrepareOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case R.id.menu_toggle_log:
+ mLogShown = !mLogShown;
+ ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+ if (mLogShown) {
+ output.setDisplayedChild(1);
+ } else {
+ output.setDisplayedChild(0);
+ }
+ supportInvalidateOptionsMenu();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/screencapture/ScreenCaptureFragment.java b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/screencapture/ScreenCaptureFragment.java
new file mode 100644
index 00000000..f1345792
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/java/com/example/android/screencapture/ScreenCaptureFragment.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.screencapture;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.media.projection.MediaProjection;
+import android.media.projection.MediaProjectionManager;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.util.DisplayMetrics;
+import android.view.LayoutInflater;
+import android.view.Surface;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.Toast;
+
+import com.example.android.common.logger.Log;
+
+/**
+ * Provides UI for the screen capture.
+ */
+public class ScreenCaptureFragment extends Fragment implements View.OnClickListener {
+
+ private static final String TAG = "ScreenCaptureFragment";
+
+ private static final String STATE_RESULT_CODE = "result_code";
+ private static final String STATE_RESULT_DATA = "result_data";
+
+ private static final int REQUEST_MEDIA_PROJECTION = 1;
+
+ private int mScreenDensity;
+
+ private int mResultCode;
+ private Intent mResultData;
+
+ private Surface mSurface;
+ private MediaProjection mMediaProjection;
+ private VirtualDisplay mVirtualDisplay;
+ private MediaProjectionManager mMediaProjectionManager;
+ private Button mButtonToggle;
+ private SurfaceView mSurfaceView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (savedInstanceState != null) {
+ mResultCode = savedInstanceState.getInt(STATE_RESULT_CODE);
+ mResultData = savedInstanceState.getParcelable(STATE_RESULT_DATA);
+ }
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_screen_capture, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ mSurfaceView = (SurfaceView) view.findViewById(R.id.surface);
+ mSurface = mSurfaceView.getHolder().getSurface();
+ mButtonToggle = (Button) view.findViewById(R.id.toggle);
+ mButtonToggle.setOnClickListener(this);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ Activity activity = getActivity();
+ DisplayMetrics metrics = new DisplayMetrics();
+ activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
+ mScreenDensity = metrics.densityDpi;
+ mMediaProjectionManager = (MediaProjectionManager)
+ activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ if (mResultData != null) {
+ outState.putInt(STATE_RESULT_CODE, mResultCode);
+ outState.putParcelable(STATE_RESULT_DATA, mResultData);
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.toggle:
+ if (mVirtualDisplay == null) {
+ startScreenCapture();
+ } else {
+ stopScreenCapture();
+ }
+ break;
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_MEDIA_PROJECTION) {
+ if (resultCode != Activity.RESULT_OK) {
+ Log.i(TAG, "User cancelled");
+ Toast.makeText(getActivity(), R.string.user_cancelled, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ Activity activity = getActivity();
+ if (activity == null) {
+ return;
+ }
+ Log.i(TAG, "Starting screen capture");
+ mResultCode = resultCode;
+ mResultData = data;
+ setUpMediaProjection();
+ setUpVirtualDisplay();
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ stopScreenCapture();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ tearDownMediaProjection();
+ }
+
+ private void setUpMediaProjection() {
+ mMediaProjection = mMediaProjectionManager.getMediaProjection(mResultCode, mResultData);
+ }
+
+ private void tearDownMediaProjection() {
+ if (mMediaProjection != null) {
+ mMediaProjection.stop();
+ mMediaProjection = null;
+ }
+ }
+
+ private void startScreenCapture() {
+ Activity activity = getActivity();
+ if (mSurface == null || activity == null) {
+ return;
+ }
+ if (mMediaProjection != null) {
+ setUpVirtualDisplay();
+ } else if (mResultCode != 0 && mResultData != null) {
+ setUpMediaProjection();
+ setUpVirtualDisplay();
+ } else {
+ Log.i(TAG, "Requesting confirmation");
+ // This initiates a prompt dialog for the user to confirm screen projection.
+ startActivityForResult(
+ mMediaProjectionManager.createScreenCaptureIntent(),
+ REQUEST_MEDIA_PROJECTION);
+ }
+ }
+
+ private void setUpVirtualDisplay() {
+ Log.i(TAG, "Setting up a VirtualDisplay: " +
+ mSurfaceView.getWidth() + "x" + mSurfaceView.getHeight() +
+ " (" + mScreenDensity + ")");
+ mVirtualDisplay = mMediaProjection.createVirtualDisplay("ScreenCapture",
+ mSurfaceView.getWidth(), mSurfaceView.getHeight(), mScreenDensity,
+ DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
+ mSurface, null, null);
+ mButtonToggle.setText(R.string.stop);
+ }
+
+ private void stopScreenCapture() {
+ if (mVirtualDisplay == null) {
+ return;
+ }
+ mVirtualDisplay.release();
+ mVirtualDisplay = null;
+ mButtonToggle.setText(R.string.start);
+ }
+
+}
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 00000000..69d518c6
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 00000000..13586288
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 00000000..c107f97a
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 00000000..a4d33c2c
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 00000000..fe23a075
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/layout-w720dp/activity_main.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/layout-w720dp/activity_main.xml
new file mode 100755
index 00000000..c9a52f62
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+ 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <LinearLayout
+ android:id="@+id/sample_output"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <FrameLayout
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/margin_medium"
+ android:paddingRight="@dimen/margin_medium"
+ android:paddingTop="@dimen/margin_large"
+ android:paddingBottom="@dimen/margin_large"
+ android:text="@string/intro_message" />
+ </FrameLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="0px"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/layout/activity_main.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/layout/activity_main.xml
new file mode 100755
index 00000000..1ae4f981
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+ 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <ViewAnimator
+ android:id="@+id/sample_output"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1">
+
+ <ScrollView
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/horizontal_page_margin"
+ android:paddingRight="@dimen/horizontal_page_margin"
+ android:paddingTop="@dimen/vertical_page_margin"
+ android:paddingBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </ScrollView>
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </ViewAnimator>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="match_parent"
+ android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/layout/fragment_screen_capture.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/layout/fragment_screen_capture.xml
new file mode 100644
index 00000000..343c920c
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/layout/fragment_screen_capture.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+
+ <SurfaceView
+ android:id="@+id/surface"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"/>
+
+ <Button
+ android:id="@+id/toggle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:text="@string/start"/>
+
+</LinearLayout>
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/menu/main.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/menu/main.xml
new file mode 100644
index 00000000..b49c2c52
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_toggle_log"
+ android:showAsAction="always"
+ android:title="@string/sample_show_log" />
+</menu>
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 00000000..22074a2b
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 00000000..03d19741
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-v11/template-styles.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-v11/template-styles.xml
new file mode 100644
index 00000000..8c1ea66f
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-v11/template-styles.xml
@@ -0,0 +1,22 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+</resources>
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-v21/base-colors.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-v21/base-colors.xml
new file mode 100644
index 00000000..34c9cd13
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-v21/base-colors.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<resources>
+
+
+</resources>
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-v21/base-template-styles.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-v21/base-template-styles.xml
new file mode 100644
index 00000000..0b2948f7
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values-v21/base-template-styles.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<resources>
+
+ <!-- Activity themes -->
+ <style name="Theme.Base" parent="android:Theme.Material.Light">
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/base-strings.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/base-strings.xml
new file mode 100644
index 00000000..79880f0b
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/base-strings.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<resources>
+ <string name="app_name">ScreenCapture</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+This sample demonstrates how to use Media Projection API introduced in Android 5.0 Lollipop. Press
+"Start" to start capturing the screen.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/fragmentview_strings.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/fragmentview_strings.xml
new file mode 100755
index 00000000..7b9d9ec4
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/fragmentview_strings.xml
@@ -0,0 +1,19 @@
+<!--
+ 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.
+-->
+<resources>
+ <string name="sample_show_log">Show Log</string>
+ <string name="sample_hide_log">Hide Log</string>
+</resources>
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/strings.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/strings.xml
new file mode 100644
index 00000000..70597e66
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+<resources>
+ <string name="start">Start</string>
+ <string name="stop">Stop</string>
+ <string name="user_cancelled">User denied screen sharing permission</string>
+</resources>
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/template-dimens.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/template-dimens.xml
new file mode 100644
index 00000000..39e710b5
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/template-styles.xml b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/template-styles.xml
new file mode 100644
index 00000000..6e7d593d
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ScreenCapture/Application/tests/src/com/example/android/screencapture/test/SampleTests.java b/prebuilts/gradle/ScreenCapture/Application/tests/src/com/example/android/screencapture/test/SampleTests.java
new file mode 100644
index 00000000..f3f79975
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/Application/tests/src/com/example/android/screencapture/test/SampleTests.java
@@ -0,0 +1,62 @@
+/*
+ * 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.screencapture.test;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.View;
+import android.widget.Button;
+
+import com.example.android.screencapture.MainActivity;
+import com.example.android.screencapture.R;
+import com.example.android.screencapture.ScreenCaptureFragment;
+
+/**
+ * Tests for ScreenCapture sample.
+ */
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private ScreenCaptureFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTestActivity = getActivity();
+ mTestFragment = (ScreenCaptureFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ public void testButtonToggle() throws Throwable {
+ final View view = mTestFragment.getView();
+ assertNotNull(view);
+ final Button buttonToggle = (Button) view.findViewById(R.id.toggle);
+ assertNotNull(buttonToggle);
+ }
+
+}
diff --git a/prebuilts/gradle/ScreenCapture/CONTRIBUTING.md b/prebuilts/gradle/ScreenCapture/CONTRIBUTING.md
new file mode 100644
index 00000000..faa8b5c6
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/CONTRIBUTING.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://cla.developers.google.com).
+ * 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://cla.developers.google.com).
+
+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/prebuilts/gradle/ScreenCapture/LICENSE b/prebuilts/gradle/ScreenCapture/LICENSE
new file mode 100644
index 00000000..1af981f5
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/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/prebuilts/gradle/ScreenCapture/NOTICE b/prebuilts/gradle/ScreenCapture/NOTICE
new file mode 100644
index 00000000..7eede3de
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/NOTICE
@@ -0,0 +1,15 @@
+This sample uses the following software:
+
+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/prebuilts/gradle/ScreenCapture/README.md b/prebuilts/gradle/ScreenCapture/README.md
new file mode 100644
index 00000000..ec99efd1
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/README.md
@@ -0,0 +1,73 @@
+Android ScreenCapture Sample
+===================================
+
+This sample demonstrates how to use Media Projection API to capture device screen in real time and
+show it on a SurfaceView.
+
+Introduction
+------------
+
+Media Projection API lets you capture the current screen through Surface.
+
+To start media projection, you need to get an instance of [MediaProjection][1]. For this, you have
+to call startActivityForResult with an Intent from
+[MediaProjectionManager.createScreenCaptureIntent()][2]. This shows a confirmation dialog to the
+user. When user confirms it, you will get a result code and data in onActivityResult, so pass those
+to [getMediaProjection][3].
+
+Once you get a MediaProjection, use [createVirtualDisplay][4] and bind it to a Surface.
+
+[1]: https://developer.android.com/reference/android/media/projection/MediaProjection.html
+[2]: https://developer.android.com/reference/android/media/projection/MediaProjectionManager.html#createScreenCaptureIntent()
+[3]: https://developer.android.com/reference/android/media/projection/MediaProjectionManager.html#getMediaProjection(int, android.content.Intent)
+[4]: https://developer.android.com/reference/android/media/projection/MediaProjection.html#createVirtualDisplay(java.lang.String, int, int, int, int, android.view.Surface, android.hardware.display.VirtualDisplay.Callback, android.os.Handler)
+
+Pre-requisites
+--------------
+
+- Android SDK v21
+- Android Build Tools v21.1.1
+- Android Support Repository
+
+Screenshots
+-------------
+
+<img src="screenshots/main.png" height="400" alt="Screenshot"/>
+
+Getting Started
+---------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+Support
+-------
+
+- Google+ Community: https://plus.google.com/communities/105153134372062985968
+- Stack Overflow: http://stackoverflow.com/questions/tagged/android
+
+If you've found an error in this sample, please file an issue:
+https://github.com/googlesamples/android-ScreenCapture
+
+Patches are encouraged, and may be submitted by forking this project and
+submitting a pull request through GitHub. Please see CONTRIBUTING.md for more details.
+
+License
+-------
+
+Copyright 2014 The Android Open Source Project, Inc.
+
+Licensed to the Apache Software Foundation (ASF) under one or more contributor
+license agreements. See the NOTICE file distributed with this work for
+additional information regarding copyright ownership. The ASF licenses this
+file to you 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/prebuilts/gradle/ScreenCapture/build.gradle b/prebuilts/gradle/ScreenCapture/build.gradle
new file mode 100644
index 00000000..1dac6def
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/build.gradle
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ScreenCapture/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/ScreenCapture/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..8c0fb64a
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/ScreenCapture/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/ScreenCapture/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..0c71e760
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/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=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/prebuilts/gradle/ScreenCapture/gradlew b/prebuilts/gradle/ScreenCapture/gradlew
new file mode 100755
index 00000000..91a7e269
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/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/prebuilts/gradle/ScreenCapture/gradlew.bat b/prebuilts/gradle/ScreenCapture/gradlew.bat
new file mode 100644
index 00000000..aec99730
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/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/prebuilts/gradle/ScreenCapture/screenshots/icon-web.png b/prebuilts/gradle/ScreenCapture/screenshots/icon-web.png
new file mode 100644
index 00000000..6d41a89f
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/screenshots/icon-web.png
Binary files differ
diff --git a/prebuilts/gradle/ScreenCapture/screenshots/main.png b/prebuilts/gradle/ScreenCapture/screenshots/main.png
new file mode 100644
index 00000000..79fca656
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/screenshots/main.png
Binary files differ
diff --git a/prebuilts/gradle/ScreenCapture/settings.gradle b/prebuilts/gradle/ScreenCapture/settings.gradle
new file mode 100644
index 00000000..9464a359
--- /dev/null
+++ b/prebuilts/gradle/ScreenCapture/settings.gradle
@@ -0,0 +1 @@
+include 'Application'
diff --git a/prebuilts/gradle/SlidingTabsBasic/Application/build.gradle b/prebuilts/gradle/SlidingTabsBasic/Application/build.gradle
index 05020be5..76169dee 100644
--- a/prebuilts/gradle/SlidingTabsBasic/Application/build.gradle
+++ b/prebuilts/gradle/SlidingTabsBasic/Application/build.gradle
@@ -17,7 +17,7 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
+ compile "com.android.support:support-v4:21.0.2"
}
diff --git a/prebuilts/gradle/SlidingTabsColors/Application/build.gradle b/prebuilts/gradle/SlidingTabsColors/Application/build.gradle
index 05020be5..76169dee 100644
--- a/prebuilts/gradle/SlidingTabsColors/Application/build.gradle
+++ b/prebuilts/gradle/SlidingTabsColors/Application/build.gradle
@@ -17,7 +17,7 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
+ compile "com.android.support:support-v4:21.0.2"
}
diff --git a/prebuilts/gradle/StorageClient/Application/build.gradle b/prebuilts/gradle/StorageClient/Application/build.gradle
index 05020be5..76169dee 100644
--- a/prebuilts/gradle/StorageClient/Application/build.gradle
+++ b/prebuilts/gradle/StorageClient/Application/build.gradle
@@ -17,7 +17,7 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
+ compile "com.android.support:support-v4:21.0.2"
}
diff --git a/prebuilts/gradle/StorageProvider/Application/build.gradle b/prebuilts/gradle/StorageProvider/Application/build.gradle
index bfed04fa..c6b8c26a 100644
--- a/prebuilts/gradle/StorageProvider/Application/build.gradle
+++ b/prebuilts/gradle/StorageProvider/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:support-v13:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:support-v13:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/SwipeRefreshLayoutBasic/Application/build.gradle b/prebuilts/gradle/SwipeRefreshLayoutBasic/Application/build.gradle
index 544e46b8..18c0d15c 100644
--- a/prebuilts/gradle/SwipeRefreshLayoutBasic/Application/build.gradle
+++ b/prebuilts/gradle/SwipeRefreshLayoutBasic/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/SwipeRefreshListFragment/Application/build.gradle b/prebuilts/gradle/SwipeRefreshListFragment/Application/build.gradle
index 544e46b8..18c0d15c 100644
--- a/prebuilts/gradle/SwipeRefreshListFragment/Application/build.gradle
+++ b/prebuilts/gradle/SwipeRefreshListFragment/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/SwipeRefreshMultipleViews/Application/build.gradle b/prebuilts/gradle/SwipeRefreshMultipleViews/Application/build.gradle
index 544e46b8..18c0d15c 100644
--- a/prebuilts/gradle/SwipeRefreshMultipleViews/Application/build.gradle
+++ b/prebuilts/gradle/SwipeRefreshMultipleViews/Application/build.gradle
@@ -17,9 +17,9 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
- compile "com.android.support:gridlayout-v7:21.+"
- compile "com.android.support:cardview-v7:21.+"
+ compile "com.android.support:support-v4:21.0.2"
+ compile "com.android.support:gridlayout-v7:21.0.2"
+ compile "com.android.support:cardview-v7:21.0.2"
}
diff --git a/prebuilts/gradle/SynchronizedNotifications/.google/packaging.yaml b/prebuilts/gradle/SynchronizedNotifications/.google/packaging.yaml
index bfa7a3c6..a930c527 100644
--- a/prebuilts/gradle/SynchronizedNotifications/.google/packaging.yaml
+++ b/prebuilts/gradle/SynchronizedNotifications/.google/packaging.yaml
@@ -9,4 +9,10 @@ categories: [Wearable]
languages: [Java]
solutions: [Mobile]
github: android-SynchronizedNotifications
+level: INTERMEDIATE
+icon: screenshots/web-icon.png
+apiRefs:
+ - android:com.google.android.gms.wearable.DataApi
+ - android:com.google.android.gms.wearable.Wearable
+ - android:com.google.android.gms.wearable.WearableListenerService
license: apache2
diff --git a/prebuilts/gradle/SynchronizedNotifications/README.md b/prebuilts/gradle/SynchronizedNotifications/README.md
index 98b20529..66cded4f 100644
--- a/prebuilts/gradle/SynchronizedNotifications/README.md
+++ b/prebuilts/gradle/SynchronizedNotifications/README.md
@@ -1,8 +1,51 @@
Android SynchronizedNotifications Sample
===================================
-This sample creates simple or synchronized notifications on a
-device and an Android Wear watch.
+A basic sample showing how to use simple or synchronized notifications.
+This allows users to dismiss events from either their phone or wearable device simultaneously.
+
+Introduction
+------------
+
+The [DataAPI][1] exposes an API for components to read or write data items and assets between
+the handhelds and wearables. A [DataItem][2] is synchronized across all devices in an Android Wear network.
+It is possible to set data items while not connected to any nodes. Those data items will be synchronized
+when the nodes eventually come online.
+
+This example presents three buttons that would trigger three different combinations of
+notifications on the handset and the watch:
+
+1. The first button builds a simple local-only notification on the handset.
+2. The second one creates a wearable-only notification by putting a data item in the shared data
+store and having a [com.google.android.gms.wearable.WearableListenerService][3] listen for
+that on the wearable.
+3. The third one creates a local notification and a wearable notification by combining the above
+two. It, however, demonstrates how one can set things up so that the dismissal of one
+notification results in the dismissal of the other one.
+
+In the #2 and #3 items, the following code is used to synchronize the data between the handheld
+and the wearable devices using DataAPI.
+
+```java
+PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(path);
+putDataMapRequest.getDataMap().putString(Constants.KEY_CONTENT, content);
+putDataMapRequest.getDataMap().putString(Constants.KEY_TITLE, title);
+PutDataRequest request = putDataMapRequest.asPutDataRequest();
+Wearable.DataApi.putDataItem(mGoogleApiClient, request)
+ .setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
+ @Override
+ public void onResult(DataApi.DataItemResult dataItemResult) {
+ if (!dataItemResult.getStatus().isSuccess()) {
+ Log.e(TAG, "buildWatchOnlyNotification(): Failed to set the data, "
+ + "status: " + dataItemResult.getStatus().getStatusCode());
+ }
+ }
+ });
+```
+
+[1]: http://developer.android.com/reference/com/google/android/gms/wearable/DataApi.html#putDataItem(com.google.android.gms.common.api.GoogleApiClient%2C%20com.google.android.gms.wearable.PutDataRequest)
+[2]: http://developer.android.com/reference/com/google/android/gms/wearable/DataItem.html
+[3]: https://developer.android.com/reference/com/google/android/gms/wearable/WearableListenerService.html
Pre-requisites
--------------
@@ -11,6 +54,11 @@ Pre-requisites
- Android Build Tools v21.1.1
- Android Support Repository
+Screenshots
+-------------
+
+<img src="screenshots/different_notifications_phone.png" height="400" alt="Screenshot"/> <img src="screenshots/different_notifications_wearable.png" height="400" alt="Screenshot"/> <img src="screenshots/notification_options.png" height="400" alt="Screenshot"/> <img src="screenshots/watch_only_notification.png" height="400" alt="Screenshot"/>
+
Getting Started
---------------
diff --git a/prebuilts/gradle/SynchronizedNotifications/screenshots/web-icon.png b/prebuilts/gradle/SynchronizedNotifications/screenshots/web-icon.png
new file mode 100755
index 00000000..2f5f7093
--- /dev/null
+++ b/prebuilts/gradle/SynchronizedNotifications/screenshots/web-icon.png
Binary files differ
diff --git a/prebuilts/gradle/TextLinkify/Application/build.gradle b/prebuilts/gradle/TextLinkify/Application/build.gradle
index 05020be5..76169dee 100644
--- a/prebuilts/gradle/TextLinkify/Application/build.gradle
+++ b/prebuilts/gradle/TextLinkify/Application/build.gradle
@@ -17,7 +17,7 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
+ compile "com.android.support:support-v4:21.0.2"
}
diff --git a/prebuilts/gradle/TextSwitcher/Application/build.gradle b/prebuilts/gradle/TextSwitcher/Application/build.gradle
index 05020be5..76169dee 100644
--- a/prebuilts/gradle/TextSwitcher/Application/build.gradle
+++ b/prebuilts/gradle/TextSwitcher/Application/build.gradle
@@ -17,7 +17,7 @@ repositories {
dependencies {
- compile "com.android.support:support-v4:21.+"
+ compile "com.android.support:support-v4:21.0.2"
}
diff --git a/prebuilts/gradle/WatchFace/Wearable/src/main/AndroidManifest.xml b/prebuilts/gradle/WatchFace/Wearable/src/main/AndroidManifest.xml
index ee906b76..5d4f208f 100644
--- a/prebuilts/gradle/WatchFace/Wearable/src/main/AndroidManifest.xml
+++ b/prebuilts/gradle/WatchFace/Wearable/src/main/AndroidManifest.xml
@@ -47,7 +47,7 @@
android:name="com.google.android.wearable.watchface.preview"
android:resource="@drawable/preview_analog" />
<meta-data
- android:name="com.google.android.clockwork.home.preview_circular"
+ android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="@drawable/preview_analog_circular" />
<meta-data
android:name="com.google.android.wearable.watchface.companionConfigurationAction"
@@ -71,7 +71,7 @@
android:name="com.google.android.wearable.watchface.preview"
android:resource="@drawable/preview_analog" />
<meta-data
- android:name="com.google.android.clockwork.home.preview_circular"
+ android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="@drawable/preview_analog_circular" />
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
@@ -92,7 +92,7 @@
android:name="com.google.android.wearable.watchface.preview"
android:resource="@drawable/preview_tilt" />
<meta-data
- android:name="com.google.android.clockwork.home.preview_circular"
+ android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="@drawable/preview_tilt_circular" />
<meta-data
android:name="com.google.android.wearable.watchface.companionConfigurationAction"
@@ -117,7 +117,7 @@
android:name="com.google.android.wearable.watchface.preview"
android:resource="@drawable/preview_card_bounds" />
<meta-data
- android:name="com.google.android.clockwork.home.preview_circular"
+ android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="@drawable/preview_card_bounds_circular" />
<meta-data
android:name="com.google.android.wearable.watchface.companionConfigurationAction"
@@ -141,7 +141,7 @@
android:name="com.google.android.wearable.watchface.preview"
android:resource="@drawable/preview_digital" />
<meta-data
- android:name="com.google.android.clockwork.home.preview_circular"
+ android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="@drawable/preview_digital_circular" />
<meta-data
android:name="com.google.android.wearable.watchface.companionConfigurationAction"
@@ -182,7 +182,7 @@
android:name="com.google.android.wearable.watchface.preview"
android:resource="@drawable/preview_calendar" />
<meta-data
- android:name="com.google.android.clockwork.home.preview_circular"
+ android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="@drawable/preview_calendar_circular" />
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />