diff options
332 files changed, 10090 insertions, 8388 deletions
diff --git a/Android.mk b/Android.mk index 18d9c69c0bc2..840fda01c7cf 100644 --- a/Android.mk +++ b/Android.mk @@ -1020,35 +1020,35 @@ LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk include $(BUILD_DROIDDOC) -# ==== docs for the ndk ======================= +# ==== site updates for docs (on the androiddevdocs app engine server) ======================= include $(CLEAR_VARS) + LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES) LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES) LOCAL_STATIC_JAVA_LIBRARIES:=$(framework_docs_LOCAL_STATIC_JAVA_LIBRARIES) LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES) LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS) LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH) -LOCAL_DROIDDOC_HTML_DIR:=docs/html-ndk +LOCAL_DROIDDOC_HTML_DIR:=$(framework_docs_LOCAL_DROIDDOC_HTML_DIR) LOCAL_ADDITIONAL_JAVA_DIR:=$(framework_docs_LOCAL_ADDITIONAL_JAVA_DIR) LOCAL_ADDITIONAL_DEPENDENCIES:=$(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES) -# specify a second html input dir and an output path relative to OUT_DIR) -LOCAL_ADDITIONAL_HTML_DIR:=docs/html-intl/intl / +LOCAL_ADDITIONAL_HTML_DIR:=docs/html-intl / -LOCAL_MODULE := online-ndk +LOCAL_MODULE := online-sdk-dev LOCAL_DROIDDOC_OPTIONS:= \ $(framework_docs_LOCAL_DROIDDOC_OPTIONS) \ -toroot / \ -hdf android.whichdoc online \ $(sample_groups) \ + -useUpdatedTemplates \ -hdf android.hasSamples true \ -samplesdir $(samples_dir) -LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk +LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk-dev include $(BUILD_DROIDDOC) - # ==== docs that have all of the stuff that's @hidden ======================= include $(CLEAR_VARS) diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 87d52e4ee07e..77a7c691e7d3 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -186,7 +186,7 @@ import java.util.Set; * * <p>There are a variety of standard Intent action and category constants * defined in the Intent class, but applications can also define their own. - * These strings use java style scoping, to ensure they are unique -- for + * These strings use Java-style scoping, to ensure they are unique -- for * example, the standard {@link #ACTION_VIEW} is called * "android.intent.action.VIEW".</p> * diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index e0a61f51bfe9..e9b1f017b7db 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1359,7 +1359,7 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and - * {@link #hasSystemFeature}: The heart rate sensor on this device is an Electrocargiogram. + * {@link #hasSystemFeature}: The heart rate sensor on this device is an Electrocardiogram. */ @SdkConstant(SdkConstantType.FEATURE) public static final String FEATURE_SENSOR_HEART_RATE_ECG = diff --git a/docs/html-intl/intl/es/design/index.jd b/docs/html-intl/intl/es/design/index.jd deleted file mode 100644 index d4030e8b872b..000000000000 --- a/docs/html-intl/intl/es/design/index.jd +++ /dev/null @@ -1,186 +0,0 @@ -page.title=Material Design para Android -page.tags=Material,design -page.type=diseño -page.image=images/cards/design-material-for-android_2x.jpg - -@jd:body - -<!-- developer docs box --> -<a class="notice-developers right" href="{@docRoot}training/material/index.html"> - <div> - <h3>Documentos para desarrolladores</h3> - <p>Creación de aplicaciones con Material Design</p> - </div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw"> -<div> - <h3>Video</h3> - <p>Introducción a Material Design</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw"> -<div> - <h3>Video</h3> - <p>Papel y tinta: los materiales más importantes</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc"> -<div> - <h3>Video</h3> - <p>Material Design en la aplicación Google I/O</p> -</div> -</a> - - - -<p itemprop="description">Material Design es una guía integral para el diseño visual, de movimientos y -de interacción en distintas plataformas y dispositivos. Android ahora es compatible con las aplicaciones de -Material Design. Para usar Material Design en tus aplicaciones de Android, sigue las pautas descritas -en la <a href="http://www.google.com/design/spec">especificación de Material Design</a> y usa los -nuevos componentes y funcionalidades disponibles en Android 5.0 (nivel de API 21) y versiones posteriores.</p> - -<p>En Android, se proporcionan los siguientes elementos que te permitirán crear aplicaciones en Material Design:</p> - -<ul> - <li>un tema nuevo;</li> - <li>nuevos widgets para vistas complejas;</li> - <li>nuevas API (interfaces de programación de aplicaciones) para sombras y animaciones personalizadas.</li> -</ul> - -<p>Para obtener más información sobre la implementación de Material Design en Android, consulta -<a href="{@docRoot}training/material/index.html">Creación de aplicaciones con Material Design</a>.</p> - - -<h3>Tema Material</h3> - -<p>El tema Material te ofrece un nuevo estilo para tu aplicación, widgets del sistema que te permiten configurar -la paleta de colores y animaciones predeterminadas para información táctil y transiciones de actividades.</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">Tema Dark Material</p> - </div> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">Tema Light Material</p> - </div> -</div> -<br style="clear:left"/> -</div> - -<p>Para obtener más información, consulta <a href="{@docRoot}training/material/theme.html">Uso del tema -Material</a>.</p> - - -<h3>Listas y tarjetas</h3> - -<p>Android proporciona dos widgets nuevos para mostrar listas y tarjetas con estilos y -animaciones de Material Design:</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" /> - <p>El nuevo widget <code>RecyclerView</code> es una versión más acoplable de <code>ListView</code> - que admite diferentes tipos de diseños y proporciona mejoras en el rendimiento.</p> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> - <p>El nuevo widget <code>CardView</code> te permite mostrar extractos de información importante dentro de - tarjetas que tienen apariencia y estilo coherentes.</p> -</div> -<br style="clear:left"/> -</div> - -<p>Para obtener más información, consulta <a href="{@docRoot}training/material/lists-cards.html">Creación de listas -y tarjetas</a>.</p> - - -<h3>Visualización de sombras</h3> - -<p>Además de las propiedades X e Y, las vistas de Android ahora poseen una -propiedad Z. Esta propiedad nueva representa la elevación de una vista, que determina lo siguiente:</p> - -<ul> -<li>El tamaño de la sombra: las vistas con valores Z más elevados proyectan sombras más grandes.</li> -<li>El orden del dibujo: las vistas con valores Z más elevados aparecen sobre las otras vistas.</li> -</ul> - -<div style="width:290px;margin-left:35px;float:right"> - <div class="framed-nexus5-port-span-5"> - <video class="play-on-hover" autoplay> - <source src="{@docRoot}design/material/videos/ContactsAnim.mp4"/> - <source src="{@docRoot}design/videos/ContactsAnim.webm"/> - <source src="{@docRoot}design/videos/ContactsAnim.ogv"/> - </video> - </div> - <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> - <em>Para volver a reproducir la película, haz clic en la pantalla del dispositivo.</em> - </div> -</div> - -<p>Para obtener más información, consulta <a href="{@docRoot}training/material/shadows-clipping.html">Definición -de vistas de recorte y sombras</a>.</p> - - -<h3>Animaciones</h3> - -<p>Las nuevas API de animaciones te permiten crear animaciones personalizadas para la información táctil en los controles de IU, -además de realizar cambios en el estado de las vistas y transiciones entre actividades.</p> - -<p>Estas API te permiten hacer lo siguiente:</p> - -<ul> -<li style="margin-bottom:15px"> -responder a los eventos táctiles de tus vistas mediante animaciones de <strong>información táctil</strong>; -</li> -<li style="margin-bottom:15px"> -ocultar y mostrar vistas con animaciones con <strong>efecto circular</strong>; -</li> -<li style="margin-bottom:15px"> -alternar entre actividades con animaciones personalizadas de <strong>transición de actividades</strong>; -</li> -<li style="margin-bottom:15px"> -crear animaciones más naturales con <strong>movimiento curvo</strong>; -</li> -<li style="margin-bottom:15px"> -animar los cambios en una o más propiedades de las vistas con las animaciones de <strong>cambio de estado de la vista</strong>; -</li> -<li style="margin-bottom:15px"> -mostrar animaciones en los <strong>elementos de diseño de la lista de estados</strong> entre los cambios de estado de las vistas. -</li> -</ul> - -<p>Las animaciones de la información táctil se concentran en diferentes vistas estándar, como los botones. Las nuevas API -te permiten personalizar estas animaciones y agregarlas a tus vistas personalizadas.</p> - -<p>Para obtener más información, consulta <a href="{@docRoot}training/material/animations.html">Definición de animaciones -personalizadas</a>.</p> - - -<h3>Elementos de diseño</h3> - -<p>Estas nuevas capacidades para los elementos de diseño te permiten implementar aplicaciones de Material Design:</p> - -<ul> -<li>Los <strong>dibujables en vector</strong> se pueden escalar sin perder definición y son perfectos -para los iconos de las aplicaciones de un solo color.</li> -<li>El <strong>teñido de los dibujables</strong> te permite definir mapas de bits como máscaras alfa y pintarlos con -un color durante el tiempo de ejecución.</li> -<li>La <strong>extracción de color</strong> te permite extraer automáticamente colores prominentes de una -imagen del mapa de bits.</li> -</ul> - -<p>Para obtener más información, consulta <a href="{@docRoot}training/material/drawables.html">Trabajo con -elementos de diseño</a>.</p> diff --git a/docs/html-intl/intl/es/index.jd b/docs/html-intl/intl/es/index.jd index 89f63628e656..46974cfe5370 100644 --- a/docs/html-intl/intl/es/index.jd +++ b/docs/html-intl/intl/es/index.jd @@ -5,6 +5,16 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 @jd:body +<script> + $(document).ready(function() { + if (useUpdatedTemplates) { + $("#useUpdatedTemplates").css("display","block"); + } else { + $("#useOldTemplates").css("display","block"); + } + }) +</script> + <!-- <div class="dac-hero-carousel" data-carousel-query="collection:index/carousel"> </div> --> <section class="dac-hero-carousel"> @@ -39,11 +49,39 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 </a> </article></section> -<div class="actions-bar dac-expand dac-invert"> +<div id="useUpdatedTemplates" style="display:none" class="dac-section dac-slim dac-gray dac-expand"> <div class="wrap dac-offset-parent"> <a class="dac-fab dac-scroll-button" data-scroll-button href="#build-apps"> <i class="dac-sprite dac-arrow-down-gray"></i> </a> + <ul class="dac-actions"> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}sdk/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Get the SDK + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}samples/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Browse sample code + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}distribute/stories/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Watch stories + </a> + </li> + </ul> + </div><!-- end .wrap --> +</div><!-- end .dac-actions --> + +<div id="useOldTemplates" style="display:none" class="actions-bar dac-expand dac-invert"> + <div class="wrap dac-offset-parent"> + <a class="dac-fab dac-scroll-button" data-scroll-button="" href="#build-apps"> + <i class="dac-sprite dac-arrow-down-gray"></i> + </a> <div class="actions"> <div><a href="{@docRoot}sdk/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> @@ -53,17 +91,15 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 <span class="dac-sprite dac-auto-chevron-large"></span> Browse Samples </a></div> - <div><a href="//www.youtube.com/user/androiddevelopers"> + <div><a href="{@docRoot}distribute/stories/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> - Watch Videos + Watch Stories </a></div> </div><!-- end .actions --> </div><!-- end .wrap --> -</div><!-- end .actions-bar --> - - +</div> -<section class="dac-section dac-section-light" id="build-apps"><div class="wrap"> +<section class="dac-section dac-light" id="build-apps"><div class="wrap"> <h1 class="dac-section-title">Build Beautiful Apps</h1> <div class="dac-section-subtitle"> Resources to get you started with designing and developing for Android. diff --git a/docs/html-intl/intl/in/design/index.jd b/docs/html-intl/intl/in/design/index.jd deleted file mode 100644 index 8bc12ed3b8c5..000000000000 --- a/docs/html-intl/intl/in/design/index.jd +++ /dev/null @@ -1,186 +0,0 @@ -page.title=Desain Bahan untuk Android -page.tags=Material,design -page.type=desain -page.image=images/cards/design-material-for-android_2x.jpg - -@jd:body - -<!-- developer docs box --> -<a class="notice-developers right" href="{@docRoot}training/material/index.html"> - <div> - <h3>Dokumen Pengembang</h3> - <p>Membuat Aplikasi dengan Desain Bahan</p> - </div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw"> -<div> - <h3>Video</h3> - <p>Pengantar Desain Bahan</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw"> -<div> - <h3>Video</h3> - <p>Kertas dan Tinta: Bahan Penting</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc"> -<div> - <h3>Video</h3> - <p>Desain Bahan di Aplikasi Google I/O</p> -</div> -</a> - - - -<p itemprop="description">Desain bahan adalah panduan komprehensif untuk desain visual, gerak, dan -interaksi lintas platform dan perangkat. Android kini menyertakan dukungan untuk -aplikasi desain bahan. Untuk menggunakan desain bahan di aplikasi Android, ikuti panduan yang didefinisikan -dalam <a href="http://www.google.com/design/spec">spesifikasi desain bahan</a> dan gunakan -komponen dan fungsionalitas baru yang tersedia di Android 5.0 (API level 21) ke atas.</p> - -<p>Android menyediakan elemen berikut untuk membangun aplikasi desain bahan:</p> - -<ul> - <li>Tema baru</li> - <li>Widget baru untuk tampilan yang kompleks</li> - <li>API baru untuk animasi dan bayangan custom</li> -</ul> - -<p>Untuk informasi selengkapnya tentang mengimplementasikan desain bahan pada Android, lihat -<a href="{@docRoot}training/material/index.html">Membuat Aplikasi dengan Desain Bahan</a>.</p> - - -<h3>Tema Bahan</h3> - -<p>Tema bahan menyediakan gaya baru untuk aplikasi Anda, widget sistem yang memungkinkan Anda mengatur -palet warnanya, dan animasi default untuk umpan balik sentuh dan transisi aktivitas.</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">Tema bahan gelap</p> - </div> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">Tema bahan terang</p> - </div> -</div> -<br style="clear:left"/> -</div> - -<p>Untuk informasi selengkapnya, lihat <a href="{@docRoot}training/material/theme.html">Menggunakan Tema -Bahan</a>.</p> - - -<h3>Daftar dan Kartu</h3> - -<p>Android menyediakan dua widget baru untuk menampilkan kartu dan daftar dengan gaya desain bahan -dan animasi:</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" /> - <p>Widget <code>RecyclerView</code> baru adalah versi <code>ListView</code> - yang lebih mudah dimasukkan dan mendukung beragam tipe layout serta memberikan peningkatan kinerja.</p> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> - <p>Widget <code>CardView</code> baru memungkinkan Anda menampilkan potongan informasi penting dalam - kartu yang memiliki tampilan dan cara kerja yang konsisten.</p> -</div> -<br style="clear:left"/> -</div> - -<p>Untuk informasi selengkapnya, lihat <a href="{@docRoot}training/material/lists-cards.html">Membuat Daftar -dan Kartu</a>.</p> - - -<h3>Bayangan Tampilan</h3> - -<p>Selain properti X dan Y, tampilan di Android kini memiliki -properti Z. Properti baru ini mewakili ketinggian tampilan, yang menentukan:</p> - -<ul> -<li>Ukuran bayangan: tampilan dengan nilai Z lebih tinggi menghasilkan bayangan lebih besar.</li> -<li>Urutan penggambaran: tampilan dengan nilai Z lebih tinggi muncul di atas tampilan lainnya.</li> -</ul> - -<div style="width:290px;margin-left:35px;float:right"> - <div class="framed-nexus5-port-span-5"> - <video class="play-on-hover" autoplay> - <source src="{@docRoot}design/material/videos/ContactsAnim.mp4"/> - <source src="{@docRoot}design/videos/ContactsAnim.webm"/> - <source src="{@docRoot}design/videos/ContactsAnim.ogv"/> - </video> - </div> - <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> - <em>Untuk memutar ulang film, klik layar perangkat</em> - </div> -</div> - -<p>Untuk informasi selengkapnya, lihat <a href="{@docRoot}training/material/shadows-clipping.html">Mendefinisikan -Bayangan dan Memangkas Tampilan</a>.</p> - - -<h3>Animasi</h3> - -<p>API animasi baru memungkinkan Anda membuat animasi custom untuk umpan balik sentuh dalam kontrol UI, -perubahan status tampilan, dan transisi aktivitas.</p> - -<p>API ini memungkinkan Anda:</p> - -<ul> -<li style="margin-bottom:15px"> -Merespons kejadian sentuh dalam tampilan Anda dengan animasi <strong>umpan balik sentuh</strong>. -</li> -<li style="margin-bottom:15px"> -Menyembunyikan dan memperlihatkan tampilan dengan animasi <strong>membuka melingkar</strong>. -</li> -<li style="margin-bottom:15px"> -Peralihan antar aktivitas dengan animasi <strong>transisi aktivitas</strong> custom. -</li> -<li style="margin-bottom:15px"> -Membuat animasi yang lebih alami dengan <strong>gerak melengkung</strong>. -</li> -<li style="margin-bottom:15px"> -Menganimasikan perubahan dalam satu atau beberapa properti tampilan dengan animasi <strong>perubahan status tampilan</strong>. -</li> -<li style="margin-bottom:15px"> -Menampilkan animasi di <strong>drawable daftar status</strong> di antara perubahan status tampilan. -</li> -</ul> - -<p>Animasi umpan balik sentuh dimasukkan ke dalam beberapa tampilan standar, misalnya tombol. API baru -ini memungkinkan Anda menyesuaikan animasi ini dan menambahkannya ke tampilan custom Anda.</p> - -<p>Untuk informasi selengkapnya, lihat <a href="{@docRoot}training/material/animations.html">Mendefinisikan Animasi -Custom</a>.</p> - - -<h3>Drawable</h3> - -<p>Kemampuan baru untuk drawable ini membantu Anda mengimplementasikan aplikasi desain bahan:</p> - -<ul> -<li><strong>Drawable vektor</strong> bisa diubah skalanya tanpa kehilangan definisi dan cocok -untuk ikon satu-warna dalam-aplikasi.</li> -<li><strong>Pewarnaan drawable</strong> memungkinkan Anda mendefinisikan bitmap sebagai alpha-mask dan mewarnainya -saat runtime.</li> -<li><strong>Ekstraksi warna</strong> memungkinkan Anda mengekstrak warna mencolok secara otomatis dari -gambar bitmap.</li> -</ul> - -<p>Untuk informasi selengkapnya, lihat <a href="{@docRoot}training/material/drawables.html">Bekerja dengan -Drawable</a>.</p> diff --git a/docs/html-intl/intl/in/design/material/index.jd b/docs/html-intl/intl/in/design/material/index.jd index 28cfd5213247..0cb4dbcff627 100644 --- a/docs/html-intl/intl/in/design/material/index.jd +++ b/docs/html-intl/intl/in/design/material/index.jd @@ -1,4 +1,4 @@ -page.title=Desain Bahan untuk Android +page.title=Material Design for Android page.tags=Material,design page.type=design page.image=images/cards/design-material-for-android_2x.jpg @@ -25,11 +25,7 @@ page.image=images/cards/design-material-for-android_2x.jpg <a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw"> <div> <h3>Video</h3> -<<<<<<< HEAD <p>Kertas dan Tinta: Bahan Penting</p> -======= - <p>Kertas dan Tinta: Bahan-Bahan Penting</p> ->>>>>>> Docs: L10N update for design documentation </div> </a> @@ -37,17 +33,12 @@ page.image=images/cards/design-material-for-android_2x.jpg <a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc"> <div> <h3>Video</h3> -<<<<<<< HEAD <p>Desain Bahan di Aplikasi Google I/O</p> -======= - <p>Desain Bahan dalam Aplikasi Google I/O</p> ->>>>>>> Docs: L10N update for design documentation </div> </a> -<<<<<<< HEAD <p itemprop="description">Desain bahan adalah panduan komprehensif untuk desain visual, gerak, dan interaksi lintas platform dan perangkat. Android kini menyertakan dukungan untuk aplikasi desain bahan. Untuk menggunakan desain bahan di aplikasi Android, ikuti panduan yang didefinisikan @@ -60,20 +51,6 @@ komponen dan fungsionalitas baru yang tersedia di Android 5.0 (API level 21) ke <li>Tema baru</li> <li>Widget baru untuk tampilan yang kompleks</li> <li>API baru untuk animasi dan bayangan custom</li> -======= -<p itemprop="description">Desain bahan adalah panduan komprehensif untuk desain visual, gerakan, dan -interaksi lintas platform dan perangkat. Android sekarang memasukkan dukungan untuk -aplikasi desain bahan. Untuk menggunakan desain bahan dalam aplikasi Android Anda, ikuti panduan yang didefinisikan -dalam <a href="http://www.google.com/design/spec">spesifikasi desain bahan</a> dan gunakan -komponen dan fungsionalitas baru yang tersedia dalam Android 5.0 (API level 21) dan yang di atasnya.</p> - -<p>Android menyediakan elemen-elemen berikut bagi Anda untuk membuat aplikasi desain bahan:</p> - -<ul> - <li>Tema baru</li> - <li>Widget baru untuk tampilan kompleks</li> - <li>API baru untuk bayangan dan animasi custom</li> ->>>>>>> Docs: L10N update for design documentation </ul> <p>Untuk informasi selengkapnya tentang mengimplementasikan desain bahan pada Android, lihat @@ -83,11 +60,7 @@ komponen dan fungsionalitas baru yang tersedia dalam Android 5.0 (API level 21) <h3>Tema Bahan</h3> <p>Tema bahan menyediakan gaya baru untuk aplikasi Anda, widget sistem yang memungkinkan Anda mengatur -<<<<<<< HEAD palet warnanya, dan animasi default untuk umpan balik sentuh dan transisi aktivitas.</p> -======= -palet warna, dan animasi default untuk umpan balik sentuh serta transisi aktivitas.</p> ->>>>>>> Docs: L10N update for design documentation <!-- two columns --> <div style="width:700px;margin-top:25px;margin-bottom:20px"> @@ -119,7 +92,6 @@ dan animasi:</p> <div style="width:700px;margin-top:25px;margin-bottom:20px"> <div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" /> -<<<<<<< HEAD <p>Widget <code>RecyclerView</code> baru adalah versi <code>ListView</code> yang lebih mudah dimasukkan dan mendukung beragam tipe layout serta memberikan peningkatan kinerja.</p> </div> @@ -127,15 +99,6 @@ dan animasi:</p> <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> <p>Widget <code>CardView</code> baru memungkinkan Anda menampilkan potongan informasi penting dalam kartu yang memiliki tampilan dan cara kerja yang konsisten.</p> -======= - <p>Widget <code>RecyclerView</code> baru adalah versi yang lebih mudah dimasukkan untuk <code>ListView</code> - yang mendukung tipe layout berbeda dan memberikan peningkatan kinerja.</p> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> - <p>Widget <code>CardView</code> baru memungkinkan Anda menampilkan bagian informasi penting di dalam - kartu yang memiliki tampilan dan gaya konsisten.</p> ->>>>>>> Docs: L10N update for design documentation </div> <br style="clear:left"/> </div> @@ -146,21 +109,12 @@ dan Kartu</a>.</p> <h3>Bayangan Tampilan</h3> -<<<<<<< HEAD <p>Selain properti X dan Y, tampilan di Android kini memiliki properti Z. Properti baru ini mewakili ketinggian tampilan, yang menentukan:</p> <ul> <li>Ukuran bayangan: tampilan dengan nilai Z lebih tinggi menghasilkan bayangan lebih besar.</li> <li>Urutan penggambaran: tampilan dengan nilai Z lebih tinggi muncul di atas tampilan lainnya.</li> -======= -<p>Selain properti X dan Y, tampilan dalam Android sekarang memiliki -properti Z. Properti baru ini mewakili ketinggian pandangan, yang menentukan:</p> - -<ul> -<li>Ukuran bayangan: tampilan dengan nilai Z lebih tinggi membentuk bayangan yang lebih besar.</li> -<li>Urutan penggambaran: tampilan dengan nilai Z lebih tinggi akan muncul di atas tampilan lain.</li> ->>>>>>> Docs: L10N update for design documentation </ul> <div style="width:290px;margin-left:35px;float:right"> @@ -172,36 +126,23 @@ properti Z. Properti baru ini mewakili ketinggian pandangan, yang menentukan:</p </video> </div> <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> -<<<<<<< HEAD <em>Untuk memutar ulang film, klik layar perangkat</em> -======= - <em>Untuk memutar ulang film, klik pada layar perangkat</em> ->>>>>>> Docs: L10N update for design documentation </div> </div> <p>Untuk informasi selengkapnya, lihat <a href="{@docRoot}training/material/shadows-clipping.html">Mendefinisikan -<<<<<<< HEAD Bayangan dan Memangkas Tampilan</a>.</p> -======= -Bayangan dan Memotong Tampilan</a>.</p> ->>>>>>> Docs: L10N update for design documentation <h3>Animasi</h3> <p>API animasi baru memungkinkan Anda membuat animasi custom untuk umpan balik sentuh dalam kontrol UI, -<<<<<<< HEAD perubahan status tampilan, dan transisi aktivitas.</p> -======= -perubahan dalam status tampilan, dan transisi aktivitas.</p> ->>>>>>> Docs: L10N update for design documentation <p>API ini memungkinkan Anda:</p> <ul> <li style="margin-bottom:15px"> -<<<<<<< HEAD Merespons kejadian sentuh dalam tampilan Anda dengan animasi <strong>umpan balik sentuh</strong>. </li> <li style="margin-bottom:15px"> @@ -212,38 +153,17 @@ Peralihan antar aktivitas dengan animasi <strong>transisi aktivitas</strong> cus </li> <li style="margin-bottom:15px"> Membuat animasi yang lebih alami dengan <strong>gerak melengkung</strong>. -======= -Merespons terjadinya sentuhan dalam tampilan Anda dengan animasi <strong>umpan balik sentuh</strong>. -</li> -<li style="margin-bottom:15px"> -Menyembunyikan dan menampilkan tampilan dengan animasi <strong>penampakan sirkuler</strong>. -</li> -<li style="margin-bottom:15px"> -Beralih antar aktivitas dengan animasi <strong>transisi aktivitas</strong> custom. -</li> -<li style="margin-bottom:15px"> -Membuat animasi yang lebih alami dengan <strong>gerakan melingkar</strong>. ->>>>>>> Docs: L10N update for design documentation </li> <li style="margin-bottom:15px"> Menganimasikan perubahan dalam satu atau beberapa properti tampilan dengan animasi <strong>perubahan status tampilan</strong>. </li> <li style="margin-bottom:15px"> -<<<<<<< HEAD Menampilkan animasi di <strong>drawable daftar status</strong> di antara perubahan status tampilan. </li> </ul> <p>Animasi umpan balik sentuh dimasukkan ke dalam beberapa tampilan standar, misalnya tombol. API baru ini memungkinkan Anda menyesuaikan animasi ini dan menambahkannya ke tampilan custom Anda.</p> -======= -Menampilkan animasi dalam <strong>drawable daftar status</strong> di antara perubahan status tampilan. -</li> -</ul> - -<p>Animasi umpan balik sentuh dimasukkan ke dalam beberapa tampilan standar, misalnya tombol. API -baru ini memungkinkan Anda menyesuaikan animasi ini dan menambahkannya ke tampilan custom.</p> ->>>>>>> Docs: L10N update for design documentation <p>Untuk informasi selengkapnya, lihat <a href="{@docRoot}training/material/animations.html">Mendefinisikan Animasi Custom</a>.</p> @@ -254,7 +174,6 @@ Custom</a>.</p> <p>Kemampuan baru untuk drawable ini membantu Anda mengimplementasikan aplikasi desain bahan:</p> <ul> -<<<<<<< HEAD <li><strong>Drawable vektor</strong> bisa diubah skalanya tanpa kehilangan definisi dan cocok untuk ikon satu-warna dalam-aplikasi.</li> <li><strong>Pewarnaan drawable</strong> memungkinkan Anda mendefinisikan bitmap sebagai alpha-mask dan mewarnainya @@ -264,15 +183,4 @@ gambar bitmap.</li> </ul> <p>Untuk informasi selengkapnya, lihat <a href="{@docRoot}training/material/drawables.html">Bekerja dengan -======= -<li><strong>Drawable vektor</strong> dapat diskalakan tanpa kehilangan ketajaman dan cocok -untuk ikon satu-warna dalam-aplikasi.</li> -<li><strong>Pewarnaan drawable</strong> memungkinkan Anda mendefinisikan bitmap sebagai -alpha-mask dan mewarnainya dengan satu warna saat runtime.</li> -<li><strong>Ekstraksi warna</strong> memungkinkan Anda secara otomatis mengekstrak warna -penting dari gambar bitmap.</li> -</ul> - -<p>Untuk informasi selengkapnya, lihat <a href="{@docRoot}training/material/drawables.html">Menggunakan ->>>>>>> Docs: L10N update for design documentation Drawable</a>.</p> diff --git a/docs/html-intl/intl/in/sdk/index.jd b/docs/html-intl/intl/in/sdk/index.jd index 712e8ea6553f..248a4b8b58f0 100644 --- a/docs/html-intl/intl/in/sdk/index.jd +++ b/docs/html-intl/intl/in/sdk/index.jd @@ -1,62 +1,15 @@ page.title=Unduh Android Studio dan SDK Tools page.tags=sdk, android studio +page.image=images/cards/android-studio_2x.png page.template=sdk +page.image=images/cards/android-studio_2x.png header.hide=1 page.metaDescription=Unduh Android IDE resmi dan alat pengembang untuk membuat aplikasi bagi ponsel, tablet, perangkat wearable, TV Android dan lainnya. -studio.version=1.4.0.10 - -studio.linux_bundle_download=android-studio-ide-141.2288178-linux.zip -studio.linux_bundle_bytes=380821638 -studio.linux_bundle_checksum=137e3734f2e8e285bd7c1d2fae2e8548d0f164bd - -studio.mac_bundle_download=android-studio-ide-141.2288178-mac.dmg -studio.mac_bundle_bytes=364624965 -studio.mac_bundle_checksum=27068d59d5a78717d31bdedd054082b5c50d3897 - -studio.win_bundle_download=android-studio-ide-141.2288178-windows.zip -studio.win_bundle_bytes=373492997 -studio.win_bundle_checksum=c0851dc9a506ba9f4c1379a3e9b4019c08478220 - - -studio.win_bundle_exe_download=android-studio-bundle-141.2288178-windows.exe -studio.win_bundle_exe_bytes=1177811944 -studio.win_bundle_exe_checksum=a2f0141d35f8f0c24dad2ff390e7f6231c5f7625 - -studio.win_notools_exe_download=android-studio-ide-141.2288178-windows.exe -studio.win_notools_exe_bytes=348295968 -studio.win_notools_exe_checksum=82d0d9c78ec23834956f941a07821be347fcb7bf - - - - -sdk.linux_download=android-sdk_r24.3.4-linux.tgz -sdk.linux_bytes=309138331 -sdk.linux_checksum=fb293d7bca42e05580be56b1adc22055d46603dd - -sdk.mac_download=android-sdk_r24.3.4-macosx.zip -sdk.mac_bytes=98340900 -sdk.mac_checksum=128f10fba668ea490cc94a08e505a48a608879b9 - -sdk.win_download=android-sdk_r24.3.4-windows.zip -sdk.win_bytes=187496897 -sdk.win_checksum=4a8718fb4a2bf2128d34b92f23ddd79fc65839e7 - - -sdk.win_installer=installer_r24.3.4-windows.exe -sdk.win_installer_bytes=139477985 -sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd - - - - - - @jd:body <style type="text/css"> .offline {display:none;} - a.download-bundle-button {display:block;} h2.feature { padding-top:30px; margin-top:0; @@ -64,20 +17,7 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd } .feature-blurb { margin:0px; font-size:16px; font-weight:300; - padding:40px 0 0 0; - } - - .landing-button.green { - font-size:16px; - background-color:#90c653; - padding:8px 10px 10px; - margin:0; - width:206px; - text-align:center; - } - - .landing-button.green:hover { - background-color:#85b84f; + padding-top:40px; } .landing-button .small { @@ -95,8 +35,8 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd white-space: nowrap; text-indent: -10000px; font-size:0px; - background: url(../images/tools/studio-logo.png); - background-image: -webkit-image-set(url(../images/tools/studio-logo.png) 1x, url(../images/tools/studio-logo_2x.png) 2x); + background: url({@docRoot}images/tools/studio-logo.png); + background-image: -webkit-image-set(url({@docRoot}images/tools/studio-logo.png) 1x, url({@docRoot}images/tools/studio-logo_2x.png) 2x); background-size: 226px 78px; } @@ -283,8 +223,9 @@ Ini adalah Perjanjian Lisensi Kit Pengembangan Perangkat Lunak Android <div class="col-13"> </div><!-- provides top margin for content --> -<img src="{@docRoot}images/tools/studio-hero.png" srcset="{@docRoot}images/tools/studio-hero_2x.png 2x, {@docRoot}images/tools/studio-hero.png 1x" width="760" height="400" /> - +<img src="{@docRoot}images/tools/studio-hero.png" +srcset="{@docRoot}images/tools/studio-hero_2x.png 2x, {@docRoot}images/tools/studio-hero.png 1x" +width="760" alt="" /> <div style="color: #fff; width:226px; height:0; overflow:visible; position:absolute; top:40px; left:25px"> @@ -293,15 +234,15 @@ Ini adalah Perjanjian Lisensi Kit Pengembangan Perangkat Lunak Android <p style="font-size: 16px; color:#bbb; position: absolute;left: 297px; top: 5px; display: block; width: 400px;text-align: center;">Android IDE resmi</p> -<ul style="font-size:12px"> +<ul style="font-size:12px;line-height:19px;"> <li>Android Studio IDE</li> <li>Android SDK Tools</li> <li>Platform Android 6.0 (Marshmallow)</li> <li>Citra sistem emulator Android 6.0 dengan Google API</li> </ul> - -<a class="online landing-button green download-bundle-button" style="margin-top:30px;" href="#Other">Unduh</a> +<a class="online landing-button green download-bundle-button" +href="#Other" >Download Android Studio<br/><span class='small'></span></a> <!-- this appears when viewing the offline docs --> <p class="offline"> diff --git a/docs/html-intl/intl/in/sdk/installing/adding-packages.jd b/docs/html-intl/intl/in/sdk/installing/adding-packages.jd index b98e27b0a34a..2fc5c3eb0cd8 100644 --- a/docs/html-intl/intl/in/sdk/installing/adding-packages.jd +++ b/docs/html-intl/intl/in/sdk/installing/adding-packages.jd @@ -1,7 +1,6 @@ page.title=Menambahkan Paket SDK page.tags=sdk manager -helpoutsWidget=true @jd:body @@ -31,7 +30,7 @@ ol.large > li > h2 { line-height:20px; padding:0 0 0 20px; margin:0 0 20px 0; - display:inline-block; + display:inline; font-weight:normal; } ol.large > li:nth-child(1):before { diff --git a/docs/html-intl/intl/in/training/material/index.jd b/docs/html-intl/intl/in/training/material/index.jd index 625f02d9b7f5..53697d2ea666 100644 --- a/docs/html-intl/intl/in/training/material/index.jd +++ b/docs/html-intl/intl/in/training/material/index.jd @@ -1,6 +1,5 @@ page.title=Desain Bahan untuk Pengembang -page.type=desain -page.image=gambar/kartu/material_2x.png +page.image=images/cards/material_2x.png page.metaDescription=Pelajari cara menerapkan desain bahan pada aplikasi Anda. diff --git a/docs/html-intl/intl/ja/design/index.jd b/docs/html-intl/intl/ja/design/index.jd deleted file mode 100644 index e8c0f543d6ec..000000000000 --- a/docs/html-intl/intl/ja/design/index.jd +++ /dev/null @@ -1,186 +0,0 @@ -page.title=Android のマテリアル デザイン -page.tags=Material,design -page.type=デザイン -page.image=images/cards/design-material-for-android_2x.jpg - -@jd:body - -<!-- developer docs box --> -<a class="notice-developers right" href="{@docRoot}training/material/index.html"> - <div> - <h3>デベロッパー ドキュメント</h3> - <p>マテリアル デザインを使用したアプリの作成</p> - </div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw"> -<div> - <h3>ビデオ</h3> - <p>マテリアル デザインについて</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw"> -<div> - <h3>ビデオ</h3> - <p>紙とインク: 重要なマテリアル</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc"> -<div> - <h3>ビデオ</h3> - <p>Google I/O アプリのマテリアル デザイン</p> -</div> -</a> - - - -<p itemprop="description">マテリアル デザインは、複数のプラットフォームや端末の視覚、モーション、インタラクション デザインの包括的な指針です。 -Android はマテリアル デザイン アプリに対応するようになりました。 -Android アプリでマテリアル デザインを使うには、<a href="http://www.google.com/design/spec">マテリアル デザインの仕様</a>で定義されているガイドラインに従い、Android 5.0(API レベル 21)以降の新しいコンポーネントや機能を使用します。 - -</p> - -<p>Android にはマテリアル デザインのアプリのビルドに使用できる次の要素が用意されています。</p> - -<ul> - <li>新しいテーマ</li> - <li>複雑なビューに対応した新しいウィジェット</li> - <li>カスタムのシャドウとアニメーション用の新しい API</li> -</ul> - -<p>Android でのマテリアル デザインの実装については、<a href="{@docRoot}training/material/index.html">マテリアル デザインを使用したアプリの作成</a>をご覧ください。 -</p> - - -<h3>マテリアル テーマ</h3> - -<p>マテリアル テーマには、アプリの新しいスタイルであるシステム ウィジェットがあります。このシステム ウィジェットを使うと、システム ウィジェットのカラーパレットを設定したり、タッチ フィードバックやアクティビティ遷移のためのデフォルトのアニメーションを設定したりできます。 -</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">暗い色のマテリアル テーマ</p> - </div> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">明るい色のマテリアル テーマ</p> - </div> -</div> -<br style="clear:left"/> -</div> - -<p>詳細については、<a href="{@docRoot}training/material/theme.html">マテリアル テーマの使用</a>をご覧ください。 -</p> - - -<h3>リストとカード</h3> - -<p>Android はマテリアル デザインのスタイルとアニメーションを含むカードとリストを表示する、次のような新しい 2 つのウィジェットを提供しています。 -</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" /> - <p>新しい <code>RecyclerView</code> ウィジェットは <code>ListView</code> - に比べてさらに柔軟に機能を追加できるようになっており、さまざまなレイアウト タイプをサポートしてパフォーマンスを向上させます。</p> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> - <p>新しい <code>CardView</code> ウィジェットではカードの外観や操作性が統一され、カード内の重要な情報を表示できるようになりました。 -</p> -</div> -<br style="clear:left"/> -</div> - -<p>詳細については、<a href="{@docRoot}training/material/lists-cards.html">リストとカードの作成</a>をご覧ください。 -</p> - - -<h3>シャドウの表示</h3> - -<p>Android のビューに、X と Y のプロパティに加えて Z プロパティが追加されました。 -この新しいプロパティはビューのエレベーションを表し、次の要素を指定します。</p> - -<ul> -<li>シャドウのサイズ: ビューの Z 値が高いほどシャドウのサイズが大きくなります。</li> -<li>描画順序: ビューの Z 値が高いほど他のビューの前面に表示されます。</li> -</ul> - -<div style="width:290px;margin-left:35px;float:right"> - <div class="framed-nexus5-port-span-5"> - <video class="play-on-hover" autoplay> - <source src="{@docRoot}design/material/videos/ContactsAnim.mp4"/> - <source src="{@docRoot}design/videos/ContactsAnim.webm"/> - <source src="{@docRoot}design/videos/ContactsAnim.ogv"/> - </video> - </div> - <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> - <em>端末の画像をクリックすると動画を再生できます</em> - </div> -</div> - -<p>詳細については、<a href="{@docRoot}training/material/shadows-clipping.html">シャドウとクリッピング ビューの定義</a>をご覧ください。 -</p> - - -<h3>アニメーション</h3> - -<p>新しいアニメーション API を使って、UI コントロールのタッチ フィードバック、ビューの状態変化、アクティビティ間の遷移時のカスタム アニメーションを作成できます。 -</p> - -<p>この API で次のようなことができます。</p> - -<ul> -<li style="margin-bottom:15px"> -<strong>タッチ フィードバック</strong> アニメーションでビューのタップ イベントに応答する。 -</li> -<li style="margin-bottom:15px"> -<strong>円形状の出現</strong>アニメーションを使ってビューを表示したり、非表示にしたりする。 -</li> -<li style="margin-bottom:15px"> -カスタムの<strong>アクティビティ遷移</strong>アニメーションを使ってアクティビティを切り替える。 -</li> -<li style="margin-bottom:15px"> -<strong>曲線モーション</strong>を使ってより自然なアニメーションを作成する。 -</li> -<li style="margin-bottom:15px"> -<strong>ビューの状態変化</strong>アニメーションを使って 1 つ以上のビュー プロパティを変化させるアニメーションを作成する。 -</li> -<li style="margin-bottom:15px"> -ビューの状態を変化させるアニメーションを<strong>状態リスト ドローアブル</strong>で表示します。 -</li> -</ul> - -<p>タッチ フィードバック アニメーションはボタンなどの複数の標準ビューに組み込まれています。新しい API を使うと、これらのアニメーションをカスタマイズして、カスタム ビューに追加できます。 -</p> - -<p>詳細については、<a href="{@docRoot}training/material/animations.html">カスタム アニメーションの定義</a>をご覧ください。 -</p> - - -<h3>ドローアブル</h3> - -<p>次の新しいドローアブル機能を使用してマテリアル デザイン アプリを実装できます。</p> - -<ul> -<li><strong>ベクター型ドローアブル</strong>は定義を失わずにスケールできるので、単色のアプリ アイコンに最適です。 -</li> -<li><strong>ドローアブルによる着色</strong>を使ってビットマップをアルファ マスクとして定義し、実行時にそのビットマップに色付けできます。 -</li> -<li><strong>色の抽出</strong>を使ってビットマップ画像から代表色を自動的に抽出できます。 -</li> -</ul> - -<p>詳細については、<a href="{@docRoot}training/material/drawables.html">ドローアブルの使用</a>をご覧ください。 -</p> diff --git a/docs/html-intl/intl/ja/distribute/index.jd b/docs/html-intl/intl/ja/distribute/index-ja.jd index 27f1cb4a839a..27f1cb4a839a 100644 --- a/docs/html-intl/intl/ja/distribute/index.jd +++ b/docs/html-intl/intl/ja/distribute/index-ja.jd diff --git a/docs/html-intl/intl/ja/index.jd b/docs/html-intl/intl/ja/index.jd index fd81a213cd1a..6dfa0dde357a 100644 --- a/docs/html-intl/intl/ja/index.jd +++ b/docs/html-intl/intl/ja/index.jd @@ -5,6 +5,16 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 @jd:body +<script> + $(document).ready(function() { + if (useUpdatedTemplates) { + $("#useUpdatedTemplates").css("display","block"); + } else { + $("#useOldTemplates").css("display","block"); + } + }) +</script> + <!-- <div class="dac-hero-carousel" data-carousel-query="collection:index/carousel"> </div> --> <section class="dac-hero-carousel"> @@ -39,11 +49,39 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 </a> </article></section> -<div class="actions-bar dac-expand dac-invert"> +<div id="useUpdatedTemplates" style="display:none" class="dac-section dac-slim dac-gray dac-expand"> <div class="wrap dac-offset-parent"> <a class="dac-fab dac-scroll-button" data-scroll-button href="#build-apps"> <i class="dac-sprite dac-arrow-down-gray"></i> </a> + <ul class="dac-actions"> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}sdk/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Get the SDK + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}samples/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Browse sample code + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}distribute/stories/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Watch stories + </a> + </li> + </ul> + </div><!-- end .wrap --> +</div><!-- end .dac-actions --> + +<div id="useOldTemplates" style="display:none" class="actions-bar dac-expand dac-invert"> + <div class="wrap dac-offset-parent"> + <a class="dac-fab dac-scroll-button" data-scroll-button="" href="#build-apps"> + <i class="dac-sprite dac-arrow-down-gray"></i> + </a> <div class="actions"> <div><a href="{@docRoot}sdk/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> @@ -53,17 +91,15 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 <span class="dac-sprite dac-auto-chevron-large"></span> Browse Samples </a></div> - <div><a href="//www.youtube.com/user/androiddevelopers"> + <div><a href="{@docRoot}distribute/stories/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> - Watch Videos + Watch Stories </a></div> </div><!-- end .actions --> </div><!-- end .wrap --> -</div><!-- end .actions-bar --> - - +</div> -<section class="dac-section dac-section-light" id="build-apps"><div class="wrap"> +<section class="dac-section dac-light" id="build-apps"><div class="wrap"> <h1 class="dac-section-title">Build Beautiful Apps</h1> <div class="dac-section-subtitle"> Resources to get you started with designing and developing for Android. diff --git a/docs/html-intl/intl/ja/sdk/index.jd b/docs/html-intl/intl/ja/sdk/index.jd index e2ba62d2731f..771894acc408 100644 --- a/docs/html-intl/intl/ja/sdk/index.jd +++ b/docs/html-intl/intl/ja/sdk/index.jd @@ -1,62 +1,14 @@ page.title=Android Studio と SDK Tools のダウンロード page.tags=sdk, android studio page.template=sdk +page.image=images/cards/android-studio_2x.png header.hide=1 page.metaDescription=公式 Android IDE とデベロッパー ツールをダウンロードして、Android 版のモバイル端末、タブレット、ウェアラブル端末、TV などの端末向けのアプリをビルドする。 -studio.version=1.4.0.10 - -studio.linux_bundle_download=android-studio-ide-141.2288178-linux.zip -studio.linux_bundle_bytes=380821638 -studio.linux_bundle_checksum=137e3734f2e8e285bd7c1d2fae2e8548d0f164bd - -studio.mac_bundle_download=android-studio-ide-141.2288178-mac.dmg -studio.mac_bundle_bytes=364624965 -studio.mac_bundle_checksum=27068d59d5a78717d31bdedd054082b5c50d3897 - -studio.win_bundle_download=android-studio-ide-141.2288178-windows.zip -studio.win_bundle_bytes=373492997 -studio.win_bundle_checksum=c0851dc9a506ba9f4c1379a3e9b4019c08478220 - - -studio.win_bundle_exe_download=android-studio-bundle-141.2288178-windows.exe -studio.win_bundle_exe_bytes=1177811944 -studio.win_bundle_exe_checksum=a2f0141d35f8f0c24dad2ff390e7f6231c5f7625 - -studio.win_notools_exe_download=android-studio-ide-141.2288178-windows.exe -studio.win_notools_exe_bytes=348295968 -studio.win_notools_exe_checksum=82d0d9c78ec23834956f941a07821be347fcb7bf - - - - -sdk.linux_download=android-sdk_r24.3.4-linux.tgz -sdk.linux_bytes=309138331 -sdk.linux_checksum=fb293d7bca42e05580be56b1adc22055d46603dd - -sdk.mac_download=android-sdk_r24.3.4-macosx.zip -sdk.mac_bytes=98340900 -sdk.mac_checksum=128f10fba668ea490cc94a08e505a48a608879b9 - -sdk.win_download=android-sdk_r24.3.4-windows.zip -sdk.win_bytes=187496897 -sdk.win_checksum=4a8718fb4a2bf2128d34b92f23ddd79fc65839e7 - - -sdk.win_installer=installer_r24.3.4-windows.exe -sdk.win_installer_bytes=139477985 -sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd - - - - - - @jd:body <style type="text/css"> .offline {display:none;} - a.download-bundle-button {display:block;} h2.feature { padding-top:30px; margin-top:0; @@ -64,20 +16,7 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd } .feature-blurb { margin:0px; font-size:16px; font-weight:300; - padding:40px 0 0 0; - } - - .landing-button.green { - font-size:16px; - background-color:#90c653; - padding:8px 10px 10px; - margin:0; - width:206px; - text-align:center; - } - - .landing-button.green:hover { - background-color:#85b84f; + padding-top:40px; } .landing-button .small { @@ -95,8 +34,8 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd white-space: nowrap; text-indent: -10000px; font-size:0px; - background: url(../images/tools/studio-logo.png); - background-image: -webkit-image-set(url(../images/tools/studio-logo.png) 1x, url(../images/tools/studio-logo_2x.png) 2x); + background: url({@docRoot}images/tools/studio-logo.png); + background-image: -webkit-image-set(url({@docRoot}images/tools/studio-logo.png) 1x, url({@docRoot}images/tools/studio-logo_2x.png) 2x); background-size: 226px 78px; } @@ -293,15 +232,15 @@ API を使用して Google からデータを取得する場合、デベロッ <p style="font-size: 16px; color:#bbb; position: absolute;left: 297px; top: 5px; display: block; width: 400px;text-align: center;">公式 Android IDE</p> -<ul style="font-size:12px"> +<ul style="font-size:12px;line-height:19px;"> <li>Android Studio IDE</li> <li>Android SDK Tools</li> <li>Android 6.0(Marshmallow)プラットフォーム</li> <li>Google API を使用した Android 6.0 エミュレータのシステム イメージ</li> </ul> - -<a class="online landing-button green download-bundle-button" style="margin-top:30px;" href="#Other">Download</a> +<a class="online landing-button green download-bundle-button" +href="#Other" >Download Android Studio<br/><span class='small'></span></a> <!-- this appears when viewing the offline docs --> <p class="offline"> @@ -397,8 +336,6 @@ Gradle で進化する Android のビルド</h2> <p>APK は Android Studio でもコマンドラインでもビルドできます。</p> </div> -</div> - <h2 class="feature norule">Android Studio のその他の特徴</h2> diff --git a/docs/html-intl/intl/ja/sdk/installing/adding-packages.jd b/docs/html-intl/intl/ja/sdk/installing/adding-packages.jd index 7715eed4a340..af5dcd0a4989 100644 --- a/docs/html-intl/intl/ja/sdk/installing/adding-packages.jd +++ b/docs/html-intl/intl/ja/sdk/installing/adding-packages.jd @@ -31,7 +31,7 @@ ol.large > li > h2 { line-height:20px; padding:0 0 0 20px; margin:0 0 20px 0; - display:inline-block; + display:inline; font-weight:normal; } ol.large > li:nth-child(1):before { diff --git a/docs/html-intl/intl/ko/design/index.jd b/docs/html-intl/intl/ko/design/index.jd deleted file mode 100644 index b24c66866b7d..000000000000 --- a/docs/html-intl/intl/ko/design/index.jd +++ /dev/null @@ -1,186 +0,0 @@ -page.title=Android용 머티리얼 디자인 -page.tags=Material,design -page.type=design -page.image=images/cards/design-material-for-android_2x.jpg - -@jd:body - -<!-- developer docs box --> -<a class="notice-developers right" href="{@docRoot}training/material/index.html"> - <div> - <h3>개발자 문서</h3> - <p>머티리얼 디자인으로 앱 생성</p> - </div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw"> -<div> - <h3>비디오</h3> - <p>머티리얼 디자인 소개</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw"> -<div> - <h3>비디오</h3> - <p>종이와 잉크: 중요한 머티리얼</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc"> -<div> - <h3>비디오</h3> - <p>Google I/O 앱 내 머티리얼 디자인</p> -</div> -</a> - - - -<p itemprop="description">머티리얼 디자인은 플랫폼 및 기기 전반의 표현 방식, 모션 및 -상호 작용 디자인에 대한 종합적인 지침입니다. Android에는 이제 -머티리얼 디자인 앱에 대한 지원이 포함되었습니다. Android 앱에서 머티리얼 디자인을 사용하려면 <a href="http://www.google.com/design/spec">머티리얼 디자인 사양</a>에 -규정되어 있는 지침을 따르세요. 또한 Android 5.0(API 레벨 21) 이상에서 제공하는 -새 구성 요소 및 기능을 사용하세요.</p> - -<p>Android는 머티리얼 디자인 앱을 구축하는 데 사용할 수 있는 다음 요소를 제공합니다.</p> - -<ul> - <li>새로운 테마</li> - <li>복잡한 뷰를 위한 새로운 위젯</li> - <li>사용자 지정 그림자 및 애니메이션을 위한 새로운 API</li> -</ul> - -<p>Android에서 머티리얼 디자인을 구현하는 방법에 대한 자세한 내용은 -<a href="{@docRoot}training/material/index.html">머티리얼 디자인으로 앱 생성</a>을 참조하세요.</p> - - -<h3>머티리얼 테마</h3> - -<p>머티리얼 테마는 앱에 사용할 수 있는 새로운 스타일, 색상표를 -설정할 수 있는 시스템 위젯, 그리고 터치 피드백 및 액티비티 전환을 위한 기본 애니메이션을 제공합니다.</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">어두운 머티리얼 테마</p> - </div> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">밝은 머티리얼 테마</p> - </div> -</div> -<br style="clear:left"/> -</div> - -<p>자세한 내용은 <a href="{@docRoot}training/material/theme.html">머티리얼 -테마 사용</a>을 참조하세요.</p> - - -<h3>목록 및 카드</h3> - -<p>Android는 머티리얼 디자인 스타일 -및 애니메이션으로 카드 및 목록을 표시하는 데 사용할 수 있는 두 개의 새로운 위젯을 제공합니다.</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" /> - <p>새로운 <code>RecyclerView</code> 위젯은 <code>ListView</code>의 -플러그 기능이 개선된 버전으로, 다양한 레이아웃 유형을 지원하고 향상된 성능을 제공합니다.</p> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> - <p>새로운 <code>CardView</code> 위젯은 일관적인 모양 및 느낌이 있는 -카드 내 정보의 중요한 부분을 표시할 수 있게 해줍니다.</p> -</div> -<br style="clear:left"/> -</div> - -<p>자세한 내용은 <a href="{@docRoot}training/material/lists-cards.html">목록 -및 카드 생성</a>을 참조하세요.</p> - - -<h3>뷰 그림자</h3> - -<p>X 및 Y 속성과 더불어 이제 Android의 뷰에는 Z -속성이 추가되었습니다. 이 새로운 속성은 다음을 결정하는 뷰의 엘리베이션을 나타냅니다.</p> - -<ul> -<li>그림자 크기: 뷰의 Z 값이 클수록 표시되는 그림자도 커집니다.</li> -<li>그리기 순서: 뷰의 Z 값이 클수록 다른 뷰의 위에 표시됩니다.</li> -</ul> - -<div style="width:290px;margin-left:35px;float:right"> - <div class="framed-nexus5-port-span-5"> - <video class="play-on-hover" autoplay> - <source src="{@docRoot}design/material/videos/ContactsAnim.mp4"/> - <source src="{@docRoot}design/videos/ContactsAnim.webm"/> - <source src="{@docRoot}design/videos/ContactsAnim.ogv"/> - </video> - </div> - <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> - <em>영화를 재생하려면 기기 화면을 클릭하세요.</em> - </div> -</div> - -<p>자세한 내용은 <a href="{@docRoot}training/material/shadows-clipping.html">그림자 -정의 및 뷰 클리핑</a>을 참조하세요.</p> - - -<h3>애니메이션</h3> - -<p>새 애니메이션 API는 UI 컨트롤 내의 터치 피드백, 뷰 상태 -변화, 그리고 액티비티 전환을 위한 사용자 지정 애니메이션을 생성할 수 있게 해줍니다.</p> - -<p>이 API를 사용하면 다음 작업을 수행할 수 있습니다.</p> - -<ul> -<li style="margin-bottom:15px"> -<strong>터치 피드백</strong> 애니메이션으로 뷰 내 터치 이벤트에 응답하기. -</li> -<li style="margin-bottom:15px"> -<strong>회전하며 나타나기</strong> 애니메이션으로 뷰 감추기 및 표시하기. -</li> -<li style="margin-bottom:15px"> -사용자 지정 <strong>액티비티 전환</strong> 애니메이션으로 액티비티 간 전환하기. -</li> -<li style="margin-bottom:15px"> -<strong>커브 모션</strong>으로 더 자연스러운 애니메이션 생성하기. -</li> -<li style="margin-bottom:15px"> -<strong>뷰 상태 변경</strong> 애니메이션으로 하나 이상의 뷰 속성 변경 사항 애니메이션화하기. -</li> -<li style="margin-bottom:15px"> -뷰 상태 변경 간에 <strong>상태 목록 드로어블</strong>에서 애니메이션 표시하기. -</li> -</ul> - -<p>터치 피드백 애니메이션은 버튼과 같은 여러 기본 뷰에 내장되어 있습니다. 새 API를 사용하면 이러한 애니메이션을 사용자 지정하고 사용자 지정 뷰에 추가할 수 -있습니다.</p> - -<p>자세한 내용은 <a href="{@docRoot}training/material/animations.html">사용자지정 -애니메이션 정의</a>를 참조하세요.</p> - - -<h3>드로어블</h3> - -<p>드로어블에 대한 다음과 같은 새 기능을 통해 머티리얼 디자인 앱을 쉽게 구현할 수 있습니다.</p> - -<ul> -<li><strong>벡터 드로어블</strong>은 단색 인앱 아이콘에 -적합하며, 정의 손실 없이 확장 가능합니다.</li> -<li><strong>드로어블 색조</strong>를 사용하면 비트맵을 알파 마스크로 정의할 수 있으며, 런타임에 -색을 입힐 수 있습니다.</li> -<li><strong>색상 추출</strong>은 -비트맵 이미지에서 주요 색상을 자동으로 추출할 수 있게 해줍니다.</li> -</ul> - -<p>자세한 내용은 <a href="{@docRoot}training/material/drawables.html">드로어블 -사용</a>을 참조하세요.</p> diff --git a/docs/html-intl/intl/ko/design/material/index.jd b/docs/html-intl/intl/ko/design/material/index.jd index 61421d5dce2e..b24c66866b7d 100644 --- a/docs/html-intl/intl/ko/design/material/index.jd +++ b/docs/html-intl/intl/ko/design/material/index.jd @@ -40,11 +40,7 @@ page.image=images/cards/design-material-for-android_2x.jpg <p itemprop="description">머티리얼 디자인은 플랫폼 및 기기 전반의 표현 방식, 모션 및 -<<<<<<< HEAD 상호 작용 디자인에 대한 종합적인 지침입니다. Android에는 이제 -======= -상호 작용 디자인에 대한 종합적인 지침입니다. Android에 이제 ->>>>>>> Docs: L10N update for design documentation 머티리얼 디자인 앱에 대한 지원이 포함되었습니다. Android 앱에서 머티리얼 디자인을 사용하려면 <a href="http://www.google.com/design/spec">머티리얼 디자인 사양</a>에 규정되어 있는 지침을 따르세요. 또한 Android 5.0(API 레벨 21) 이상에서 제공하는 새 구성 요소 및 기능을 사용하세요.</p> diff --git a/docs/html-intl/intl/ko/distribute/index.jd b/docs/html-intl/intl/ko/distribute/index-ko.jd index 1765673ea87a..1765673ea87a 100644 --- a/docs/html-intl/intl/ko/distribute/index.jd +++ b/docs/html-intl/intl/ko/distribute/index-ko.jd diff --git a/docs/html-intl/intl/ko/index.jd b/docs/html-intl/intl/ko/index.jd index d3d074811b82..8b1bfbcb30e6 100644 --- a/docs/html-intl/intl/ko/index.jd +++ b/docs/html-intl/intl/ko/index.jd @@ -5,6 +5,16 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 @jd:body +<script> + $(document).ready(function() { + if (useUpdatedTemplates) { + $("#useUpdatedTemplates").css("display","block"); + } else { + $("#useOldTemplates").css("display","block"); + } + }) +</script> + <!-- <div class="dac-hero-carousel" data-carousel-query="collection:index/carousel"> </div> --> <section class="dac-hero-carousel"> @@ -39,11 +49,39 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 </a> </article></section> -<div class="actions-bar dac-expand dac-invert"> +<div id="useUpdatedTemplates" style="display:none" class="dac-section dac-slim dac-gray dac-expand"> <div class="wrap dac-offset-parent"> <a class="dac-fab dac-scroll-button" data-scroll-button href="#build-apps"> <i class="dac-sprite dac-arrow-down-gray"></i> </a> + <ul class="dac-actions"> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}sdk/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Get the SDK + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}samples/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Browse sample code + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}distribute/stories/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Watch stories + </a> + </li> + </ul> + </div><!-- end .wrap --> +</div><!-- end .dac-actions --> + +<div id="useOldTemplates" style="display:none" class="actions-bar dac-expand dac-invert"> + <div class="wrap dac-offset-parent"> + <a class="dac-fab dac-scroll-button" data-scroll-button="" href="#build-apps"> + <i class="dac-sprite dac-arrow-down-gray"></i> + </a> <div class="actions"> <div><a href="{@docRoot}sdk/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> @@ -53,17 +91,15 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 <span class="dac-sprite dac-auto-chevron-large"></span> Browse Samples </a></div> - <div><a href="//www.youtube.com/user/androiddevelopers"> + <div><a href="{@docRoot}distribute/stories/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> - Watch Videos + Watch Stories </a></div> </div><!-- end .actions --> </div><!-- end .wrap --> -</div><!-- end .actions-bar --> - - +</div> -<section class="dac-section dac-section-light" id="build-apps"><div class="wrap"> +<section class="dac-section dac-light" id="build-apps"><div class="wrap"> <h1 class="dac-section-title">Build Beautiful Apps</h1> <div class="dac-section-subtitle"> Resources to get you started with designing and developing for Android. diff --git a/docs/html-intl/intl/ko/sdk/index.jd b/docs/html-intl/intl/ko/sdk/index.jd index 97973028cd61..f4728c3f20c8 100644 --- a/docs/html-intl/intl/ko/sdk/index.jd +++ b/docs/html-intl/intl/ko/sdk/index.jd @@ -1,62 +1,14 @@ page.title=Android Studio 및 SDK 도구 다운로드 page.tags=sdk, android studio page.template=sdk +page.image=images/cards/android-studio_2x.png header.hide=1 page.metaDescription=Android 휴대폰, 태블릿, 웨어러블, TV 등을 위한 앱을 구축하는 데 사용할 수 있는 공식 Android IDE 및 개발자 도구를 다운로드하세요. -studio.version=1.4.0.10 - -studio.linux_bundle_download=android-studio-ide-141.2288178-linux.zip -studio.linux_bundle_bytes=380821638 -studio.linux_bundle_checksum=137e3734f2e8e285bd7c1d2fae2e8548d0f164bd - -studio.mac_bundle_download=android-studio-ide-141.2288178-mac.dmg -studio.mac_bundle_bytes=364624965 -studio.mac_bundle_checksum=27068d59d5a78717d31bdedd054082b5c50d3897 - -studio.win_bundle_download=android-studio-ide-141.2288178-windows.zip -studio.win_bundle_bytes=373492997 -studio.win_bundle_checksum=c0851dc9a506ba9f4c1379a3e9b4019c08478220 - - -studio.win_bundle_exe_download=android-studio-bundle-141.2288178-windows.exe -studio.win_bundle_exe_bytes=1177811944 -studio.win_bundle_exe_checksum=a2f0141d35f8f0c24dad2ff390e7f6231c5f7625 - -studio.win_notools_exe_download=android-studio-ide-141.2288178-windows.exe -studio.win_notools_exe_bytes=348295968 -studio.win_notools_exe_checksum=82d0d9c78ec23834956f941a07821be347fcb7bf - - - - -sdk.linux_download=android-sdk_r24.3.4-linux.tgz -sdk.linux_bytes=309138331 -sdk.linux_checksum=fb293d7bca42e05580be56b1adc22055d46603dd - -sdk.mac_download=android-sdk_r24.3.4-macosx.zip -sdk.mac_bytes=98340900 -sdk.mac_checksum=128f10fba668ea490cc94a08e505a48a608879b9 - -sdk.win_download=android-sdk_r24.3.4-windows.zip -sdk.win_bytes=187496897 -sdk.win_checksum=4a8718fb4a2bf2128d34b92f23ddd79fc65839e7 - - -sdk.win_installer=installer_r24.3.4-windows.exe -sdk.win_installer_bytes=139477985 -sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd - - - - - - @jd:body <style type="text/css"> .offline {display:none;} - a.download-bundle-button {display:block;} h2.feature { padding-top:30px; margin-top:0; @@ -64,20 +16,7 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd } .feature-blurb { margin:0px; font-size:16px; font-weight:300; - padding:40px 0 0 0; - } - - .landing-button.green { - font-size:16px; - background-color:#90c653; - padding:8px 10px 10px; - margin:0; - width:206px; - text-align:center; - } - - .landing-button.green:hover { - background-color:#85b84f; + padding-top:40px; } .landing-button .small { @@ -95,8 +34,8 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd white-space: nowrap; text-indent: -10000px; font-size:0px; - background: url(../images/tools/studio-logo.png); - background-image: -webkit-image-set(url(../images/tools/studio-logo.png) 1x, url(../images/tools/studio-logo_2x.png) 2x); + background: url({@docRoot}images/tools/studio-logo.png); + background-image: -webkit-image-set(url({@docRoot}images/tools/studio-logo.png) 1x, url({@docRoot}images/tools/studio-logo_2x.png) 2x); background-size: 226px 78px; } @@ -292,15 +231,15 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd <p style="font-size: 16px; color:#bbb; position: absolute;left: 297px; top: 5px; display: block; width: 400px;text-align: center;">공식 Android IDE</p> -<ul style="font-size:12px"> +<ul style="font-size:12px;line-height:19px;"> <li>Android Studio IDE</li> <li>Android SDK Tools</li> <li>Android 6.0(Marshmallow) 플랫폼</li> <li>Google API를 사용하는 Android 6.0 에뮬레이터 시스템 이미지</li> </ul> - -<a class="online landing-button green download-bundle-button" style="margin-top:30px;" href="#Other">Download</a> +<a class="online landing-button green download-bundle-button" +href="#Other" >Download Android Studio<br/><span class='small'></span></a> <!-- this appears when viewing the offline docs --> <p class="offline"> diff --git a/docs/html-intl/intl/ko/sdk/installing/adding-packages.jd b/docs/html-intl/intl/ko/sdk/installing/adding-packages.jd index b70d39edbd74..b935d87afee9 100644 --- a/docs/html-intl/intl/ko/sdk/installing/adding-packages.jd +++ b/docs/html-intl/intl/ko/sdk/installing/adding-packages.jd @@ -1,7 +1,6 @@ page.title=SDK 패키지 추가하기 page.tags=sdk manager -helpoutsWidget=true @jd:body @@ -31,7 +30,7 @@ ol.large > li > h2 { line-height:20px; padding:0 0 0 20px; margin:0 0 20px 0; - display:inline-block; + display:inline; font-weight:normal; } ol.large > li:nth-child(1):before { diff --git a/docs/html-intl/intl/pt-br/design/index.jd b/docs/html-intl/intl/pt-br/design/index.jd deleted file mode 100644 index 5368d2d74c0c..000000000000 --- a/docs/html-intl/intl/pt-br/design/index.jd +++ /dev/null @@ -1,186 +0,0 @@ -page.title=Material Design para Android -page.tags=Material,design -page.type=design -page.image=images/cards/design-material-for-android_2x.jpg - -@jd:body - -<!-- developer docs box --> -<a class="notice-developers right" href="{@docRoot}training/material/index.html"> - <div> - <h3>Documentos do desenvolvedor</h3> - <p>Criação de aplicativos com o Material Design</p> - </div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw"> -<div> - <h3>Vídeo</h3> - <p>Introdução ao Material Design</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw"> -<div> - <h3>Vídeo</h3> - <p>Papel e tinta: Os materiais que importam</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc"> -<div> - <h3>Vídeo</h3> - <p>Material Design no aplicativo Google I/O</p> -</div> -</a> - - - -<p itemprop="description">O Material Design é um guia abrangente para design visual, de movimento e de -interação para diversas plataformas e dispositivos. O Android agora é compatível com -aplicativos do Material Design. Para usar o Material Design nos aplicativos Android, siga as orientações definidas -nas <a href="http://www.google.com/design/spec">especificações do Material Design</a> e use os novos -componentes e funcionalidades disponíveis no Android 5.0 (API de nível 21) e em posteriores.</p> - -<p>O Android fornece os seguintes elementos para criar aplicativos do Material Design:</p> - -<ul> - <li>Um novo tema</li> - <li>Novos widgets para vistas complexas</li> - <li>Novas APIs para sombras e animações personalizadas</li> -</ul> - -<p>Para obter mais informações sobre a implementação do Material Design no Android, consulte -<a href="{@docRoot}training/material/index.html">Criação de aplicativos com o Material Design</a>.</p> - - -<h3>Tema do Material</h3> - -<p>O tema do Material fornece um novo estilo para o seu aplicativo, widgets de sistema que permitem -definir a paleta de cores e as animações padrão para feedback de toque e transições de atividades.</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">Tema escuro do Material</p> - </div> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">Tema claro do Material</p> - </div> -</div> -<br style="clear:left"/> -</div> - -<p>Para obter mais informações, consulte <a href="{@docRoot}training/material/theme.html">Como usar o tema -do Material</a>.</p> - - -<h3>Listas e cartões</h3> - -<p>O Android fornece dois novos widgets para exibir cartões e listas com estilos e animações do -Material Design:</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" /> - <p>O novo widget <code>RecyclerView</code> é uma versão mais completa de <code>ListView</code> - com suporte para diferentes tipos de layout e melhorias no desempenho.</p> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> - <p>O novo widget <code>CardView</code> permite exibir informações importantes dentro de - cartões que têm aparência consistente.</p> -</div> -<br style="clear:left"/> -</div> - -<p>Para obter mais informações, consulte <a href="{@docRoot}training/material/lists-cards.html">Como criar -listas e cartões</a>.</p> - - -<h3>Sombras de vistas</h3> - -<p>Além das propriedades X e Y, vistas no Android agora têm uma propriedade -Z. Essa nova propriedade representa a elevação de uma vista, que determina:</p> - -<ul> -<li>O tamanho da sombra: vistas com valores maiores de Z lançam sombras maiores.</li> -<li>A ordem de desenho: vistas com valores maiores de Z aparecem sobre outras vistas.</li> -</ul> - -<div style="width:290px;margin-left:35px;float:right"> - <div class="framed-nexus5-port-span-5"> - <video class="play-on-hover" autoplay> - <source src="{@docRoot}design/material/videos/ContactsAnim.mp4"/> - <source src="{@docRoot}design/videos/ContactsAnim.webm"/> - <source src="{@docRoot}design/videos/ContactsAnim.ogv"/> - </video> - </div> - <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> - <em>Para reproduzir o filme, clique na tela do dispositivo</em> - </div> -</div> - -<p>Para obter mais informações, consulte <a href="{@docRoot}training/material/shadows-clipping.html">Como -definir sombras e recortar visualizações</a>.</p> - - -<h3>Animações</h3> - -<p>As novas APIs de animação permitem criar animações personalizadas para feedback de toque em controles de IU, -mudanças no estado da vista e transições de atividades.</p> - -<p>Essas APIs permitem:</p> - -<ul> -<li style="margin-bottom:15px"> -Responder a eventos de toque nas vistas com animações de <strong>feedback de toque</strong>. -</li> -<li style="margin-bottom:15px"> -Ocultar e exibir vistas com animações de <strong>revelação circular</strong>. -</li> -<li style="margin-bottom:15px"> -Alternar entre atividades com animações de <strong>transição de atividades</strong>. -</li> -<li style="margin-bottom:15px"> -Criar animações mais naturais com <strong>movimento curvado</strong>. -</li> -<li style="margin-bottom:15px"> -Animar mudanças em uma ou mais propriedades da vista com animações de <strong>mudança de estado da vista</strong>. -</li> -<li style="margin-bottom:15px"> -Exibir animações em <strong>desenháveis da lista de estado</strong> entre mudanças de estado da vista. -</li> -</ul> - -<p>Animações de feedback de toque são integradas em várias vistas padrão, como botões. As novas APIs -permitem personalizar essas animações e adicioná-las às vistas personalizadas.</p> - -<p>Para obter mais informações, consulte <a href="{@docRoot}training/material/animations.html">Como definir -animações personalizadas</a>.</p> - - -<h3>Desenháveis</h3> - -<p>Essas novas capacidades dos desenháveis ajudam na implementação de aplicativos do Material Design:</p> - -<ul> -<li><strong>Desenháveis de vetor</strong> são dimensionáveis sem perder definição e são perfeitos -para ícones de uma cor dentro do aplicativo.</li> -<li><strong>Tingimento desenhável</strong> permite definir mapas de bits como uma máscara alfa e tingi-los com -uma cor em tempo de execução.</li> -<li><strong>Extração de cor</strong> permite extrair automaticamente cores proeminentes de uma -imagem de mapa de bits.</li> -</ul> - -<p>Para obter mais informações, consulte <a href="{@docRoot}training/material/drawables.html">Como trabalhar -com desenháveis</a>.</p> diff --git a/docs/html-intl/intl/pt-br/design/material/index.jd b/docs/html-intl/intl/pt-br/design/material/index.jd index 579bf93cbe8a..5368d2d74c0c 100644 --- a/docs/html-intl/intl/pt-br/design/material/index.jd +++ b/docs/html-intl/intl/pt-br/design/material/index.jd @@ -39,11 +39,7 @@ page.image=images/cards/design-material-for-android_2x.jpg -<<<<<<< HEAD <p itemprop="description">O Material Design é um guia abrangente para design visual, de movimento e de -======= -<p itemprop="description">O Material Design é um guia abrangente para projeto visual, de movimento e de ->>>>>>> Docs: L10N update for design documentation interação para diversas plataformas e dispositivos. O Android agora é compatível com aplicativos do Material Design. Para usar o Material Design nos aplicativos Android, siga as orientações definidas nas <a href="http://www.google.com/design/spec">especificações do Material Design</a> e use os novos @@ -102,11 +98,7 @@ Material Design:</p> <div style="float:left;width:250px;margin-right:0px;"> <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> <p>O novo widget <code>CardView</code> permite exibir informações importantes dentro de -<<<<<<< HEAD cartões que têm aparência consistente.</p> -======= - cartões que têm aparência consistente.</p> ->>>>>>> Docs: L10N update for design documentation </div> <br style="clear:left"/> </div> diff --git a/docs/html-intl/intl/pt-br/index.jd b/docs/html-intl/intl/pt-br/index.jd index 2c2fdee5d48e..8605ab8feaf4 100644 --- a/docs/html-intl/intl/pt-br/index.jd +++ b/docs/html-intl/intl/pt-br/index.jd @@ -5,6 +5,16 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 @jd:body +<script> + $(document).ready(function() { + if (useUpdatedTemplates) { + $("#useUpdatedTemplates").css("display","block"); + } else { + $("#useOldTemplates").css("display","block"); + } + }) +</script> + <!-- <div class="dac-hero-carousel" data-carousel-query="collection:index/carousel"> </div> --> <section class="dac-hero-carousel"> @@ -39,11 +49,39 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 </a> </article></section> -<div class="actions-bar dac-expand dac-invert"> +<div id="useUpdatedTemplates" style="display:none" class="dac-section dac-slim dac-gray dac-expand"> <div class="wrap dac-offset-parent"> <a class="dac-fab dac-scroll-button" data-scroll-button href="#build-apps"> <i class="dac-sprite dac-arrow-down-gray"></i> </a> + <ul class="dac-actions"> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}sdk/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Get the SDK + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}samples/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Browse sample code + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}distribute/stories/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Watch stories + </a> + </li> + </ul> + </div><!-- end .wrap --> +</div><!-- end .dac-actions --> + +<div id="useOldTemplates" style="display:none" class="actions-bar dac-expand dac-invert"> + <div class="wrap dac-offset-parent"> + <a class="dac-fab dac-scroll-button" data-scroll-button="" href="#build-apps"> + <i class="dac-sprite dac-arrow-down-gray"></i> + </a> <div class="actions"> <div><a href="{@docRoot}sdk/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> @@ -53,17 +91,15 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 <span class="dac-sprite dac-auto-chevron-large"></span> Browse Samples </a></div> - <div><a href="//www.youtube.com/user/androiddevelopers"> + <div><a href="{@docRoot}distribute/stories/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> - Watch Videos + Watch Stories </a></div> </div><!-- end .actions --> </div><!-- end .wrap --> -</div><!-- end .actions-bar --> - - +</div> -<section class="dac-section dac-section-light" id="build-apps"><div class="wrap"> +<section class="dac-section dac-light" id="build-apps"><div class="wrap"> <h1 class="dac-section-title">Build Beautiful Apps</h1> <div class="dac-section-subtitle"> Resources to get you started with designing and developing for Android. diff --git a/docs/html-intl/intl/pt-br/sdk/index.jd b/docs/html-intl/intl/pt-br/sdk/index.jd index 152bf260fe04..ff3210b1ca83 100644 --- a/docs/html-intl/intl/pt-br/sdk/index.jd +++ b/docs/html-intl/intl/pt-br/sdk/index.jd @@ -1,62 +1,14 @@ page.title=Como baixar o Android Studio e o SDK Tools page.tags=sdk, android studio page.template=sdk +page.image=images/cards/android-studio_2x.png header.hide=1 page.metaDescription=Baixar o Android IDE e ferramentas do desenvolvedor para compilar aplicativos para celulares, tablets, dispositivos de uso junto ao corpo, TVs e muito mais do Android. -studio.version=1.4.0.10 - -studio.linux_bundle_download=android-studio-ide-141.2288178-linux.zip -studio.linux_bundle_bytes=380821638 -studio.linux_bundle_checksum=137e3734f2e8e285bd7c1d2fae2e8548d0f164bd - -studio.mac_bundle_download=android-studio-ide-141.2288178-mac.dmg -studio.mac_bundle_bytes=364624965 -studio.mac_bundle_checksum=27068d59d5a78717d31bdedd054082b5c50d3897 - -studio.win_bundle_download=android-studio-ide-141.2288178-windows.zip -studio.win_bundle_bytes=373492997 -studio.win_bundle_checksum=c0851dc9a506ba9f4c1379a3e9b4019c08478220 - - -studio.win_bundle_exe_download=android-studio-bundle-141.2288178-windows.exe -studio.win_bundle_exe_bytes=1177811944 -studio.win_bundle_exe_checksum=a2f0141d35f8f0c24dad2ff390e7f6231c5f7625 - -studio.win_notools_exe_download=android-studio-ide-141.2288178-windows.exe -studio.win_notools_exe_bytes=348295968 -studio.win_notools_exe_checksum=82d0d9c78ec23834956f941a07821be347fcb7bf - - - - -sdk.linux_download=android-sdk_r24.3.4-linux.tgz -sdk.linux_bytes=309138331 -sdk.linux_checksum=fb293d7bca42e05580be56b1adc22055d46603dd - -sdk.mac_download=android-sdk_r24.3.4-macosx.zip -sdk.mac_bytes=98340900 -sdk.mac_checksum=128f10fba668ea490cc94a08e505a48a608879b9 - -sdk.win_download=android-sdk_r24.3.4-windows.zip -sdk.win_bytes=187496897 -sdk.win_checksum=4a8718fb4a2bf2128d34b92f23ddd79fc65839e7 - - -sdk.win_installer=installer_r24.3.4-windows.exe -sdk.win_installer_bytes=139477985 -sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd - - - - - - @jd:body <style type="text/css"> .offline {display:none;} - a.download-bundle-button {display:block;} h2.feature { padding-top:30px; margin-top:0; @@ -64,20 +16,7 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd } .feature-blurb { margin:0px; font-size:16px; font-weight:300; - padding:40px 0 0 0; - } - - .landing-button.green { - font-size:16px; - background-color:#90c653; - padding:8px 10px 10px; - margin:0; - width:206px; - text-align:center; - } - - .landing-button.green:hover { - background-color:#85b84f; + padding-top:40px; } .landing-button .small { @@ -95,8 +34,8 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd white-space: nowrap; text-indent: -10000px; font-size:0px; - background: url(../images/tools/studio-logo.png); - background-image: -webkit-image-set(url(../images/tools/studio-logo.png) 1x, url(../images/tools/studio-logo_2x.png) 2x); + background: url({@docRoot}images/tools/studio-logo.png); + background-image: -webkit-image-set(url({@docRoot}images/tools/studio-logo.png) 1x, url({@docRoot}images/tools/studio-logo_2x.png) 2x); background-size: 226px 78px; } @@ -292,7 +231,7 @@ Esse é o Contrato de licença do conjunto de desenvolvimento de software do And <p style="font-size: 16px; color:#bbb; position: absolute;left: 297px; top: 5px; display: block; width: 400px;text-align: center;">O IDE oficial do Android</p> -<ul style="font-size:12px"> +<ul style="font-size:12px;line-height:19px;"> <li>IDE do Android Studio</li> <li>Ferramentas do Android SDK</li> <li>Plataforma do Android 6.0 (Marshmallow)</li> @@ -300,7 +239,8 @@ width: 400px;text-align: center;">O IDE oficial do Android</p> </ul> -<a class="online landing-button green download-bundle-button" style="margin-top:30px;" href="#Other">Download</a> +<a class="online landing-button green download-bundle-button" +href="#Other" >Download Android Studio<br/><span class='small'></span></a> <!-- this appears when viewing the offline docs --> <p class="offline"> diff --git a/docs/html-intl/intl/pt-br/sdk/installing/adding-packages.jd b/docs/html-intl/intl/pt-br/sdk/installing/adding-packages.jd index f7022a4eea51..bda33b666b99 100644 --- a/docs/html-intl/intl/pt-br/sdk/installing/adding-packages.jd +++ b/docs/html-intl/intl/pt-br/sdk/installing/adding-packages.jd @@ -1,7 +1,6 @@ page.title=Como adicionar pacotes SDK page.tags=sdk manager -helpoutsWidget=true @jd:body @@ -31,7 +30,7 @@ ol.large > li > h2 { line-height:20px; padding:0 0 0 20px; margin:0 0 20px 0; - display:inline-block; + display:inline; font-weight:normal; } ol.large > li:nth-child(1):before { diff --git a/docs/html-intl/intl/ru/design/index.jd b/docs/html-intl/intl/ru/design/index.jd deleted file mode 100644 index da0352a10ef6..000000000000 --- a/docs/html-intl/intl/ru/design/index.jd +++ /dev/null @@ -1,186 +0,0 @@ -page.title=Material Design для Android -page.tags=Material,design -page.type=разработка -page.image=images/cards/design-material-for-android_2x.jpg - -@jd:body - -<!-- developer docs box --> -<a class="notice-developers right" href="{@docRoot}training/material/index.html"> - <div> - <h3>Документация для разработчиков</h3> - <p>Создание приложений с помощью Material Design</p> - </div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw"> -<div> - <h3>Видеоролик</h3> - <p>Введение в Material Design</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw"> -<div> - <h3>Видеоролик</h3> - <p>Бумага и чернила: материалы, имеющие первостепенное значение</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc"> -<div> - <h3>Видеоролик</h3> - <p>Material Design в приложениях для конференции Google I/O</p> -</div> -</a> - - - -<p itemprop="description">Material Design представляет собой комплексную концепцию создания визуальных, движущихся и - интерактивных элементов для различных платформ и устройств. Теперь Android включает в себя поддержку -приложений с элементами Material Design. Чтобы использовать элементы Material Design в своих приложениях под Android, руководствуйтесь инструкциями -в <a href="http://www.google.com/design/spec">спецификации Material Design</a>, а также воспользуйтесь -новыми компонентами и функциями, доступными в Android 5.0 (уровень API 21) и выше.</p> - -<p>Android предоставляет следующие элементы для построения приложений в соответствии с концепцией Material Design:</p> - -<ul> - <li>новую тему;</li> - <li>новые виджеты для сложных представлений;</li> - <li>новые API-интерфейсы для нестандартных теней и анимаций.</li> -</ul> - -<p>Дополнительные сведения о реализации Material Design в Android см. в разделе -<a href="{@docRoot}training/material/index.html">Создание приложений с помощью Material Design</a>.</p> - - -<h3>Тема Material Design</h3> - -<p>Тема Material Design предоставляет новый стиль для ваших приложений, системные виджеты, для которых можно настраивать -цветовую палитру, и анимации, выполняемые по умолчанию в качестве реакции на касание и при переходах между действиями.</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">Тема Material Design в темных тонах</p> - </div> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">Тема Material Design в светлых тонах</p> - </div> -</div> -<br style="clear:left"/> -</div> - -<p>Дополнительные сведения см. в разделе <a href="{@docRoot}training/material/theme.html">Использование темы -Material Design</a>.</p> - - -<h3>Списки и подсказки</h3> - -<p>Android предоставляет два новых виджета для отображения подсказок и списков с использованием стилей -и анимаций Material Design:</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" /> - <p>Виджет <code>RecyclerView</code> представляет собой более гибкую версию <code>ListView</code>, -которая поддерживает различные типы макетов и способствует повышению производительности.</p> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> - <p>Виджет <code>CardView</code> позволяет отображать важные элементы информации внутри - подсказок, имеющие согласованный внешний вид и поведение.</p> -</div> -<br style="clear:left"/> -</div> - -<p>Дополнительные сведения см. в разделе <a href="{@docRoot}training/material/lists-cards.html">Создание списков -и подсказок</a>.</p> - - -<h3>Тени представлений</h3> - -<p>Теперь, помимо свойств X и Y, представления в Android имеют свойство -Z. Это новое свойство показывает, насколько представление "приподнято", иными словами, определяет</p> - -<ul> -<li>размер тени: чем больше Z, тем больше тени, отбрасываемые представлением;</li> -<li>порядок рисования: представления с более высокими значениями Z отображаются поверх других.</li> -</ul> - -<div style="width:290px;margin-left:35px;float:right"> - <div class="framed-nexus5-port-span-5"> - <video class="play-on-hover" autoplay> - <source src="{@docRoot}design/material/videos/ContactsAnim.mp4"/> - <source src="{@docRoot}design/videos/ContactsAnim.webm"/> - <source src="{@docRoot}design/videos/ContactsAnim.ogv"/> - </video> - </div> - <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> - <em>Для воспроизведения фильма нажмите на экран устройства</em> - </div> -</div> - -<p>Дополнительные сведения см. в разделе <a href="{@docRoot}training/material/shadows-clipping.html">Определение -теней и обрезка представлений</a>.</p> - - -<h3>Анимация</h3> - -<p>Новые API-интерфейсы анимации позволяют создавать нестандартную анимацию для реакции на касание в элементах пользовательского интерфейса, -изменения состояния представления и переходов между действиями.</p> - -<p>Эти API-интерфейсы позволяют:</p> - -<ul> -<li style="margin-bottom:15px"> -реагировать на касание в представлениях, используя анимацию для <strong>реакции на касание</strong>; -</li> -<li style="margin-bottom:15px"> -скрывать и отображать представление с помощью анимации для <strong>кругового появления</strong>; -</li> -<li style="margin-bottom:15px"> -переключаться между действиями с помощью настраиваемой анимации для <strong>переходов между действиями</strong>; -</li> -<li style="margin-bottom:15px"> -создавать более естественное движение с помощью анимации для <strong>перемещения по кривой</strong>; -</li> -<li style="margin-bottom:15px"> -анимировать изменение одного или нескольких свойств представления с помощью анимации для <strong>изменения состояния представления</strong>; -</li> -<li style="margin-bottom:15px"> -отображать анимацию в <strong>графических элементах списков состояний</strong> в промежутке между изменением состояний представления. -</li> -</ul> - -<p>Анимация для реакции на касание встроена в некоторые стандартные представления, например кнопки. Новые API-интерфейсы -позволяют разработчику настраивать эти анимации и добавлять их в свои нестандартные представления.</p> - -<p>Дополнительные сведения см. в разделе <a href="{@docRoot}training/material/animations.html">Определение настраиваемой -анимации</a>.</p> - - -<h3>Графические объекты</h3> - -<p>Следующие возможности по работе с графическими объектами облегчают реализацию приложений с элементами Material Design:</p> - -<ul> -<li><strong>векторные объекты</strong> можно масштабировать без ущерба для четкости, и они отлично подходят -в качестве одноцветных значков приложения;</li> -<li><strong>тонирование графических объектов</strong> позволяет определять растровые изображения как альфа-маску и тонировать их -нужным цветом во время выполнения;</li> -<li><strong>извлечение цвета</strong> позволяет автоматически извлекать главные цвета из -растровых изображений.</li> -</ul> - -<p>Дополнительные сведения см. в разделе <a href="{@docRoot}training/material/drawables.html">Работа с -элементами дизайна</a>.</p> diff --git a/docs/html-intl/intl/ru/design/material/index.jd b/docs/html-intl/intl/ru/design/material/index.jd index a548d3aca650..da0352a10ef6 100644 --- a/docs/html-intl/intl/ru/design/material/index.jd +++ b/docs/html-intl/intl/ru/design/material/index.jd @@ -162,17 +162,10 @@ Z. Это новое свойство показывает, насколько </li> </ul> -<<<<<<< HEAD <p>Анимация для реакции на касание встроена в некоторые стандартные представления, например кнопки. Новые API-интерфейсы позволяют разработчику настраивать эти анимации и добавлять их в свои нестандартные представления.</p> <p>Дополнительные сведения см. в разделе <a href="{@docRoot}training/material/animations.html">Определение настраиваемой -======= -<p>Анимация для реакции на касание встроена в некоторые стандартные представления, например, кнопки. Новые API-интерфейсы -позволяют разработчику настраивать эти анимации и добавлять их в свои нестандартные представления.</p> - -<p>Дополнительные сведения, см. в разделе <a href="{@docRoot}training/material/animations.html">Определение настраиваемой ->>>>>>> Docs: L10N update for design documentation анимации</a>.</p> diff --git a/docs/html-intl/intl/ru/index.jd b/docs/html-intl/intl/ru/index.jd index 8ce4b0232c51..7faaac0166a7 100644 --- a/docs/html-intl/intl/ru/index.jd +++ b/docs/html-intl/intl/ru/index.jd @@ -5,6 +5,16 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 @jd:body +<script> + $(document).ready(function() { + if (useUpdatedTemplates) { + $("#useUpdatedTemplates").css("display","block"); + } else { + $("#useOldTemplates").css("display","block"); + } + }) +</script> + <!-- <div class="dac-hero-carousel" data-carousel-query="collection:index/carousel"> </div> --> <section class="dac-hero-carousel"> @@ -39,11 +49,39 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 </a> </article></section> -<div class="actions-bar dac-expand dac-invert"> +<div id="useUpdatedTemplates" style="display:none" class="dac-section dac-slim dac-gray dac-expand"> <div class="wrap dac-offset-parent"> <a class="dac-fab dac-scroll-button" data-scroll-button href="#build-apps"> <i class="dac-sprite dac-arrow-down-gray"></i> </a> + <ul class="dac-actions"> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}sdk/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Get the SDK + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}samples/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Browse sample code + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}distribute/stories/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Watch stories + </a> + </li> + </ul> + </div><!-- end .wrap --> +</div><!-- end .dac-actions --> + +<div id="useOldTemplates" style="display:none" class="actions-bar dac-expand dac-invert"> + <div class="wrap dac-offset-parent"> + <a class="dac-fab dac-scroll-button" data-scroll-button="" href="#build-apps"> + <i class="dac-sprite dac-arrow-down-gray"></i> + </a> <div class="actions"> <div><a href="{@docRoot}sdk/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> @@ -53,17 +91,15 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 <span class="dac-sprite dac-auto-chevron-large"></span> Browse Samples </a></div> - <div><a href="//www.youtube.com/user/androiddevelopers"> + <div><a href="{@docRoot}distribute/stories/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> - Watch Videos + Watch Stories </a></div> </div><!-- end .actions --> </div><!-- end .wrap --> -</div><!-- end .actions-bar --> - - +</div> -<section class="dac-section dac-section-light" id="build-apps"><div class="wrap"> +<section class="dac-section dac-light" id="build-apps"><div class="wrap"> <h1 class="dac-section-title">Build Beautiful Apps</h1> <div class="dac-section-subtitle"> Resources to get you started with designing and developing for Android. diff --git a/docs/html-intl/intl/ru/sdk/index.jd b/docs/html-intl/intl/ru/sdk/index.jd index 6b986e7beb5f..d94e456df04a 100644 --- a/docs/html-intl/intl/ru/sdk/index.jd +++ b/docs/html-intl/intl/ru/sdk/index.jd @@ -1,62 +1,14 @@ page.title=Загрузка Android Studio и инструментов SDK page.tags=sdk, android studio page.template=sdk +page.image=images/cards/android-studio_2x.png header.hide=1 page.metaDescription=Загрузите официальные средства разработки Android для создания приложений для смартфонов, планшетов, носимых устройств, телевизоров и многих других устройств под управлением ОС Android. -studio.version=1.4.0.10 - -studio.linux_bundle_download=android-studio-ide-141.2288178-linux.zip -studio.linux_bundle_bytes=380821638 -studio.linux_bundle_checksum=137e3734f2e8e285bd7c1d2fae2e8548d0f164bd - -studio.mac_bundle_download=android-studio-ide-141.2288178-mac.dmg -studio.mac_bundle_bytes=364624965 -studio.mac_bundle_checksum=27068d59d5a78717d31bdedd054082b5c50d3897 - -studio.win_bundle_download=android-studio-ide-141.2288178-windows.zip -studio.win_bundle_bytes=373492997 -studio.win_bundle_checksum=c0851dc9a506ba9f4c1379a3e9b4019c08478220 - - -studio.win_bundle_exe_download=android-studio-bundle-141.2288178-windows.exe -studio.win_bundle_exe_bytes=1177811944 -studio.win_bundle_exe_checksum=a2f0141d35f8f0c24dad2ff390e7f6231c5f7625 - -studio.win_notools_exe_download=android-studio-ide-141.2288178-windows.exe -studio.win_notools_exe_bytes=348295968 -studio.win_notools_exe_checksum=82d0d9c78ec23834956f941a07821be347fcb7bf - - - - -sdk.linux_download=android-sdk_r24.3.4-linux.tgz -sdk.linux_bytes=309138331 -sdk.linux_checksum=fb293d7bca42e05580be56b1adc22055d46603dd - -sdk.mac_download=android-sdk_r24.3.4-macosx.zip -sdk.mac_bytes=98340900 -sdk.mac_checksum=128f10fba668ea490cc94a08e505a48a608879b9 - -sdk.win_download=android-sdk_r24.3.4-windows.zip -sdk.win_bytes=187496897 -sdk.win_checksum=4a8718fb4a2bf2128d34b92f23ddd79fc65839e7 - - -sdk.win_installer=installer_r24.3.4-windows.exe -sdk.win_installer_bytes=139477985 -sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd - - - - - - @jd:body <style type="text/css"> .offline {display:none;} - a.download-bundle-button {display:block;} h2.feature { padding-top:30px; margin-top:0; @@ -64,20 +16,7 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd } .feature-blurb { margin:0px; font-size:16px; font-weight:300; - padding:40px 0 0 0; - } - - .landing-button.green { - font-size:16px; - background-color:#90c653; - padding:8px 10px 10px; - margin:0; - width:206px; - text-align:center; - } - - .landing-button.green:hover { - background-color:#85b84f; + padding-top:40px; } .landing-button .small { @@ -95,8 +34,8 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd white-space: nowrap; text-indent: -10000px; font-size:0px; - background: url(../images/tools/studio-logo.png); - background-image: -webkit-image-set(url(../images/tools/studio-logo.png) 1x, url(../images/tools/studio-logo_2x.png) 2x); + background: url({@docRoot}images/tools/studio-logo.png); + background-image: -webkit-image-set(url({@docRoot}images/tools/studio-logo.png) 1x, url({@docRoot}images/tools/studio-logo_2x.png) 2x); background-size: 226px 78px; } @@ -292,15 +231,15 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd <p style="font-size: 16px; color:#bbb; position: absolute;left: 297px; top: 5px; display: block; width: 400px;text-align: center;">Официальная среда разработки Android</p> -<ul style="font-size:12px"> +<ul style="font-size:12px;line-height:19px;"> <li>Среда разработки Android Studio</li> <li>Инструменты Android SDK</li> <li>Платформа Android 6.0 (Marshmallow)</li> <li>Системный образ Android 6.0 с API Google для эмулятора</li> </ul> - -<a class="online landing-button green download-bundle-button" style="margin-top:30px;" href="#Other">Download</a> +<a class="online landing-button green download-bundle-button" +href="#Other" >Download Android Studio<br/><span class='small'></span></a> <!-- this appears when viewing the offline docs --> <p class="offline"> diff --git a/docs/html-intl/intl/ru/sdk/installing/adding-packages.jd b/docs/html-intl/intl/ru/sdk/installing/adding-packages.jd index 81bfe1804e72..19d1edd2f152 100644 --- a/docs/html-intl/intl/ru/sdk/installing/adding-packages.jd +++ b/docs/html-intl/intl/ru/sdk/installing/adding-packages.jd @@ -1,7 +1,6 @@ page.title=Добавление пакетов SDK page.tags=менеджер sdk -helpoutsWidget=true @jd:body @@ -31,7 +30,7 @@ ol.large > li > h2 { line-height:20px; padding:0 0 0 20px; margin:0 0 20px 0; - display:inline-block; + display:inline; font-weight:normal; } ol.large > li:nth-child(1):before { diff --git a/docs/html-intl/intl/vi/design/index.jd b/docs/html-intl/intl/vi/design/index.jd deleted file mode 100644 index d72636f0c79b..000000000000 --- a/docs/html-intl/intl/vi/design/index.jd +++ /dev/null @@ -1,186 +0,0 @@ -page.title=Material Design cho Android -page.tags=Material,design -page.type=thiết kế -page.image=images/cards/design-material-for-android_2x.jpg - -@jd:body - -<!-- developer docs box --> -<a class="notice-developers right" href="{@docRoot}training/material/index.html"> - <div> - <h3>Tài liệu cho Nhà phát triển</h3> - <p>Tạo ứng dụng với Material Design</p> - </div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw"> -<div> - <h3>Video</h3> - <p>Giới thiệu Material Design</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw"> -<div> - <h3>Video</h3> - <p>Giấy và Mực: Những vật liệu quan trọng</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc"> -<div> - <h3>Video</h3> - <p>Material Design trong Google I/O App</p> -</div> -</a> - - - -<p itemprop="description">Material design là một hướng dẫn toàn diện về thiết kế -trực quan, chuyển động và tương tác giữa nhiều nền tảng và thiết bị. Hiện nay Android có hỗ trợ -những ứng dụng theo phong cách material design. Để sử dụng material design trong ứng dụng Androi của mình, hãy làm theo hướng dẫn nêu -trong <a href="http://www.google.com/design/spec">đặc tả material design</a> và sử dụng -những thành phần và tính năng mới sẵn có trong Android 5.0 (API mức 21) trở lên.</p> - -<p>Android cung cấp những phần tử sau để bạn dựng ứng dụng theo phong cách material design:</p> - -<ul> - <li>Một giao diện mới</li> - <li>Widget mới cho các dạng xem phức tạp</li> - <li>API mới cho đổ bóng và hoạt hình tùy chỉnh</li> -</ul> - -<p>Để biết thêm thông tin về triển khai material design trên Android, hãy xem -<a href="{@docRoot}training/material/index.html">Tạo ứng dụng với Material Design</a>.</p> - - -<h3>Giao diện Material</h3> - -<p>Giao diện material mang đến một phong cách mới cho ứng dụng của bạn và các widget hệ thống, cho phép bạn đặt -bảng màu của chúng và hoạt hình mặc định cho phản hồi chạm và chuyển tiếp hoạt động.</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">Giao diện material tối</p> - </div> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">Giao diện material sáng</p> - </div> -</div> -<br style="clear:left"/> -</div> - -<p>Để biết thêm thông tin, hãy xem phần <a href="{@docRoot}training/material/theme.html">Sử dụng Giao diện Material -</a>.</p> - - -<h3>Danh sách và Thẻ</h3> - -<p>Android cung cấp hai loại widget mới để hiển thị thẻ và danh sách bằng phong cách -và hoạt hình material design:</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" /> - <p>Widget <code>RecyclerView</code> mới là một phiên bản có thể ghép nối hơn của <code>ListView</code> - có hỗ trợ nhiều kiểu bố trí khác nhau và cải thiện hiệu năng.</p> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> - <p>Widget <code>CardView</code> mới cho phép bạn hiển thị những mẩu thông tin quan trọng bên trong - thẻ với diện mạo và cảm nhận nhất quán.</p> -</div> -<br style="clear:left"/> -</div> - -<p>Để biết thêm thông tin, hãy xem phần <a href="{@docRoot}training/material/lists-cards.html">Tạo Danh sách -và Thẻ</a>.</p> - - -<h3>Đổ bóng Dạng xem</h3> - -<p>Bên cạnh các thuộc tính X và Y, dạng xem trong Android nay có -thêm thuộc tính Z. Thuộc tính mới này biểu diễn độ cao của một dạng xem và sẽ quyết định:</p> - -<ul> -<li>Kích cỡ của đổ bóng: dạng xem có giá trị Z cao hơn sẽ đặt đổ bóng lớn hơn.</li> -<li>Thứ tự vẽ: dạng xem có giá trị Z cao hơn sẽ xuất hiện phía trên những dạng xem khác.</li> -</ul> - -<div style="width:290px;margin-left:35px;float:right"> - <div class="framed-nexus5-port-span-5"> - <video class="play-on-hover" autoplay> - <source src="{@docRoot}design/material/videos/ContactsAnim.mp4"/> - <source src="{@docRoot}design/videos/ContactsAnim.webm"/> - <source src="{@docRoot}design/videos/ContactsAnim.ogv"/> - </video> - </div> - <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> - <em>Để phát lại phim, nhấp vào màn hình thiết bị</em> - </div> -</div> - -<p>Để biết thêm thông tin, hãy xem phần <a href="{@docRoot}training/material/shadows-clipping.html">Định nghĩa -Đổ bóng và Dạng xem Cắt hình</a>.</p> - - -<h3>Hoạt hình</h3> - -<p>API hoạt hình mới cho phép bạn tạo hoạt hình tùy chỉnh cho phản hồi chạm trong điều khiển UI, -thay đổi trạng thái xem và chuyển tiếp hoạt động.</p> - -<p>Những API này cho phép bạn:</p> - -<ul> -<li style="margin-bottom:15px"> -Phản hồi lại sự kiện chạm trong dạng xem của mình bằng hoạt hình <strong>phản hồi chạm</strong>. -</li> -<li style="margin-bottom:15px"> -Ẩn và hiện dạng xem bằng hoạt hình <strong>hiện hình tròn</strong>. -</li> -<li style="margin-bottom:15px"> -Chuyển giữa các hoạt động bằng hoạt hình <strong>chuyển tiếp hoạt động</strong> tùy chỉnh. -</li> -<li style="margin-bottom:15px"> -Tạo hoạt hình tự nhiên hơn bằng <strong>chuyển động cong</strong>. -</li> -<li style="margin-bottom:15px"> -Tạo hoạt hình cho các thay đổi trong một hoặc nhiều thuộc tính dạng xem bằng hoạt hình <strong>thay đổi trạng thái dạng xem</strong>. -</li> -<li style="margin-bottom:15px"> -Thể hiện hoạt hình trong các <strong>nội dung vẽ được theo danh sách trạng thái</strong> giữa những thay đổi về trạng thái dạng xem. -</li> -</ul> - -<p>Hoạt hình phản hồi chạm được tích hợp vào một vài dạng xem tiêu chuẩn, ví dụ như các nút. Các API mới này -cho phép bạn tùy biến những hoạt hình này và thêm chúng vào dạng xem tùy chỉnh của mình.</p> - -<p>Để biết thêm thông tin, hãy xem phần <a href="{@docRoot}training/material/animations.html">Định nghĩa Hoạt hình -Tùy chỉnh</a>.</p> - - -<h3>Nội dung vẽ được</h3> - -<p>Những khả năng mới này của nội dung vẽ được sẽ giúp bạn triển khai các ứng dụng theo phong cách material design:</p> - -<ul> -<li><strong>Nội dung vẽ được véc-tơ</strong> có thể thay đổi kích cỡ mà không làm mất độ sắc nét và hoàn hảo -cho các biểu tượng trong ứng dụng đơn sắc.</li> -<li><strong>Nhuộm nội dung vẽ được</strong> cho phép bạn định nghĩa ảnh bitmap thành mặt nạ alpha và nhuộm -màu cho chúng theo thời gian chạy.</li> -<li><strong>Trích xuất màu</strong> cho phép bạn tự động trích xuất màu nổi bật từ -hình ảnh bitmap.</li> -</ul> - -<p>Để biết thêm thông tin, hãy xem phần <a href="{@docRoot}training/material/drawables.html">Làm việc với -Nội dung Vẽ được</a>.</p> diff --git a/docs/html-intl/intl/vi/design/material/index.jd b/docs/html-intl/intl/vi/design/material/index.jd index f66d6f62f408..d72636f0c79b 100644 --- a/docs/html-intl/intl/vi/design/material/index.jd +++ b/docs/html-intl/intl/vi/design/material/index.jd @@ -39,13 +39,8 @@ page.image=images/cards/design-material-for-android_2x.jpg -<<<<<<< HEAD <p itemprop="description">Material design là một hướng dẫn toàn diện về thiết kế trực quan, chuyển động và tương tác giữa nhiều nền tảng và thiết bị. Hiện nay Android có hỗ trợ -======= -<p itemprop="description">Material Design là một hướng dẫn toàn diện về thiết kế -trực quan, chuyển động và tương tác giữa nhiều nền tảng và thiết bị. Hiện nay, Android có hỗ trợ ->>>>>>> Docs: L10N update for design documentation những ứng dụng theo phong cách material design. Để sử dụng material design trong ứng dụng Androi của mình, hãy làm theo hướng dẫn nêu trong <a href="http://www.google.com/design/spec">đặc tả material design</a> và sử dụng những thành phần và tính năng mới sẵn có trong Android 5.0 (API mức 21) trở lên.</p> @@ -64,11 +59,7 @@ những thành phần và tính năng mới sẵn có trong Android 5.0 (API m <h3>Giao diện Material</h3> -<<<<<<< HEAD <p>Giao diện material mang đến một phong cách mới cho ứng dụng của bạn và các widget hệ thống, cho phép bạn đặt -======= -<p>Giao diện material mang đến một phong cách mới cho ứng dụng của bạn và widget hệ thống, cho phép bạn đặt ->>>>>>> Docs: L10N update for design documentation bảng màu của chúng và hoạt hình mặc định cho phản hồi chạm và chuyển tiếp hoạt động.</p> <!-- two columns --> @@ -94,25 +85,15 @@ bảng màu của chúng và hoạt hình mặc định cho phản hồi chạm <h3>Danh sách và Thẻ</h3> -<<<<<<< HEAD <p>Android cung cấp hai loại widget mới để hiển thị thẻ và danh sách bằng phong cách và hoạt hình material design:</p> -======= -<p>Android cung cấp hai loại widget mới để hiển thị thẻ và danh sách bằng các kiểu dáng -và hoạt hình theo phong cách material design:</p> ->>>>>>> Docs: L10N update for design documentation <!-- two columns --> <div style="width:700px;margin-top:25px;margin-bottom:20px"> <div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" /> -<<<<<<< HEAD <p>Widget <code>RecyclerView</code> mới là một phiên bản có thể ghép nối hơn của <code>ListView</code> có hỗ trợ nhiều kiểu bố trí khác nhau và cải thiện hiệu năng.</p> -======= - <p>Widget <code>RecyclerView</code> mới là một phiên bản dễ ghép nối hơn của <code>ListView</code> - có hỗ trợ nhiều kiểu bố cục khác nhau và cải thiện hiệu năng.</p> ->>>>>>> Docs: L10N update for design documentation </div> <div style="float:left;width:250px;margin-right:0px;"> <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> @@ -128,21 +109,12 @@ và Thẻ</a>.</p> <h3>Đổ bóng Dạng xem</h3> -<<<<<<< HEAD <p>Bên cạnh các thuộc tính X và Y, dạng xem trong Android nay có thêm thuộc tính Z. Thuộc tính mới này biểu diễn độ cao của một dạng xem và sẽ quyết định:</p> <ul> <li>Kích cỡ của đổ bóng: dạng xem có giá trị Z cao hơn sẽ đặt đổ bóng lớn hơn.</li> <li>Thứ tự vẽ: dạng xem có giá trị Z cao hơn sẽ xuất hiện phía trên những dạng xem khác.</li> -======= -<p>Bên cạnh các thuộc tính X và Y, dạng xem trong Android nay có thêm thuộc tính Z -. Thuộc tính mới này biểu diễn độ cao của một dạng xem và sẽ quyết định:</p> - -<ul> -<li>Kích cỡ của đổ bóng: dạng xem với giá trị Z cao hơn sẽ có đổ bóng lớn hơn.</li> -<li>Thứ tự vẽ: dạng xem với giá trị Z cao hơn sẽ xuất hiện ở trên những dạng xem khác.</li> ->>>>>>> Docs: L10N update for design documentation </ul> <div style="width:290px;margin-left:35px;float:right"> @@ -154,11 +126,7 @@ thêm thuộc tính Z. Thuộc tính mới này biểu diễn độ cao của m </video> </div> <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> -<<<<<<< HEAD <em>Để phát lại phim, nhấp vào màn hình thiết bị</em> -======= - <em>Để phát lại phim, hãy nhấp vào màn hình thiết bị</em> ->>>>>>> Docs: L10N update for design documentation </div> </div> @@ -181,11 +149,7 @@ Phản hồi lại sự kiện chạm trong dạng xem của mình bằng hoạt Ẩn và hiện dạng xem bằng hoạt hình <strong>hiện hình tròn</strong>. </li> <li style="margin-bottom:15px"> -<<<<<<< HEAD Chuyển giữa các hoạt động bằng hoạt hình <strong>chuyển tiếp hoạt động</strong> tùy chỉnh. -======= -Chuyển giữa các hoạt động và hoạt hình <strong>chuyển tiếp hoạt động</strong> tùy chỉnh. ->>>>>>> Docs: L10N update for design documentation </li> <li style="margin-bottom:15px"> Tạo hoạt hình tự nhiên hơn bằng <strong>chuyển động cong</strong>. diff --git a/docs/html-intl/intl/vi/sdk/index.jd b/docs/html-intl/intl/vi/sdk/index.jd index af01ede18756..4d6bfeca42b7 100644 --- a/docs/html-intl/intl/vi/sdk/index.jd +++ b/docs/html-intl/intl/vi/sdk/index.jd @@ -1,62 +1,14 @@ page.title=Tải xuống Android Studio và SDK Tools page.tags=sdk, android studio page.template=sdk +page.image=images/cards/android-studio_2x.png header.hide=1 page.metaDescription=Tải xuống Android IDE chính thức và bộ công cụ cho nhà phát triển để xây dựng ứng dụng cho điện thoại, máy tính bảng, thiết bị đeo được, TV chạy Android và nhiều thiết bị khác. -studio.version=1.4.0.10 - -studio.linux_bundle_download=android-studio-ide-141.2288178-linux.zip -studio.linux_bundle_bytes=380821638 -studio.linux_bundle_checksum=137e3734f2e8e285bd7c1d2fae2e8548d0f164bd - -studio.mac_bundle_download=android-studio-ide-141.2288178-mac.dmg -studio.mac_bundle_bytes=364624965 -studio.mac_bundle_checksum=27068d59d5a78717d31bdedd054082b5c50d3897 - -studio.win_bundle_download=android-studio-ide-141.2288178-windows.zip -studio.win_bundle_bytes=373492997 -studio.win_bundle_checksum=c0851dc9a506ba9f4c1379a3e9b4019c08478220 - - -studio.win_bundle_exe_download=android-studio-bundle-141.2288178-windows.exe -studio.win_bundle_exe_bytes=1177811944 -studio.win_bundle_exe_checksum=a2f0141d35f8f0c24dad2ff390e7f6231c5f7625 - -studio.win_notools_exe_download=android-studio-ide-141.2288178-windows.exe -studio.win_notools_exe_bytes=348295968 -studio.win_notools_exe_checksum=82d0d9c78ec23834956f941a07821be347fcb7bf - - - - -sdk.linux_download=android-sdk_r24.3.4-linux.tgz -sdk.linux_bytes=309138331 -sdk.linux_checksum=fb293d7bca42e05580be56b1adc22055d46603dd - -sdk.mac_download=android-sdk_r24.3.4-macosx.zip -sdk.mac_bytes=98340900 -sdk.mac_checksum=128f10fba668ea490cc94a08e505a48a608879b9 - -sdk.win_download=android-sdk_r24.3.4-windows.zip -sdk.win_bytes=187496897 -sdk.win_checksum=4a8718fb4a2bf2128d34b92f23ddd79fc65839e7 - - -sdk.win_installer=installer_r24.3.4-windows.exe -sdk.win_installer_bytes=139477985 -sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd - - - - - - @jd:body <style type="text/css"> .offline {display:none;} - a.download-bundle-button {display:block;} h2.feature { padding-top:30px; margin-top:0; @@ -64,20 +16,7 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd } .feature-blurb { margin:0px; font-size:16px; font-weight:300; - padding:40px 0 0 0; - } - - .landing-button.green { - font-size:16px; - background-color:#90c653; - padding:8px 10px 10px; - margin:0; - width:206px; - text-align:center; - } - - .landing-button.green:hover { - background-color:#85b84f; + padding-top:40px; } .landing-button .small { @@ -95,8 +34,8 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd white-space: nowrap; text-indent: -10000px; font-size:0px; - background: url(../images/tools/studio-logo.png); - background-image: -webkit-image-set(url(../images/tools/studio-logo.png) 1x, url(../images/tools/studio-logo_2x.png) 2x); + background: url({@docRoot}images/tools/studio-logo.png); + background-image: -webkit-image-set(url({@docRoot}images/tools/studio-logo.png) 1x, url({@docRoot}images/tools/studio-logo_2x.png) 2x); background-size: 226px 78px; } @@ -292,15 +231,15 @@ bạn phải đồng ý với các điều khoản và điều kiện sau.</p> <p style="font-size: 16px; color:#bbb; position: absolute;left: 297px; top: 5px; display: block; width: 400px;text-align: center;">IDE Android chính thức</p> -<ul style="font-size:12px"> +<ul style="font-size:12px;line-height:19px;"> <li>IDE Android Studio</li> <li>Bộ công cụ SDK Android</li> <li>Nền tảng Android 6.0 (Marshmallow)</li> <li>Ảnh hệ thống trình mô phỏng Android 6.0 cùng các API của Google</li> </ul> - -<a class="online landing-button green download-bundle-button" style="margin-top:30px;" href="#Other">Download</a> +<a class="online landing-button green download-bundle-button" +href="#Other" >Download Android Studio<br/><span class='small'></span></a> <!-- this appears when viewing the offline docs --> <p class="offline"> diff --git a/docs/html-intl/intl/vi/sdk/installing/adding-packages.jd b/docs/html-intl/intl/vi/sdk/installing/adding-packages.jd index 728c92d760f0..1c9072c746bf 100644 --- a/docs/html-intl/intl/vi/sdk/installing/adding-packages.jd +++ b/docs/html-intl/intl/vi/sdk/installing/adding-packages.jd @@ -1,7 +1,6 @@ page.title=Thêm Gói SDK page.tags=trình quản lý sdk -helpoutsWidget=true @jd:body @@ -31,7 +30,7 @@ ol.large > li > h2 { line-height:20px; padding:0 0 0 20px; margin:0 0 20px 0; - display:inline-block; + display:inline; font-weight:normal; } ol.large > li:nth-child(1):before { diff --git a/docs/html-intl/intl/zh-cn/design/index.jd b/docs/html-intl/intl/zh-cn/design/index.jd deleted file mode 100644 index f33d4bcddc3a..000000000000 --- a/docs/html-intl/intl/zh-cn/design/index.jd +++ /dev/null @@ -1,186 +0,0 @@ -page.title=Android 材料设计 -page.tags=Material,design -page.type=设计 -page.image=images/cards/design-material-for-android_2x.jpg - -@jd:body - -<!-- developer docs box --> -<a class="notice-developers right" href="{@docRoot}training/material/index.html"> - <div> - <h3>开发者文档</h3> - <p>使用材料设计创建应用</p> - </div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw"> -<div> - <h3>视频</h3> - <p>材料设计简介</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw"> -<div> - <h3>视频</h3> - <p>纸张和墨水:相关材料</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc"> -<div> - <h3>视频</h3> - <p>Google I/O 应用中的材料设计</p> -</div> -</a> - - - -<p itemprop="description">材料设计是专为设计适用于多个平台和设备的视觉、运动与互动效果而制定的综合指南。 -Android 现在已支持材料设计应用。 -如果要在您的 Android 应用中使用材料设计,请遵循<a href="http://www.google.com/design/spec">材料设计规范</a>内定义的指导方针,并使用 Android 5.0(API 级别 21)及以上版本所提供的新组件和功能。 - -</p> - -<p>Android 为您提供了以下元素来构建材料设计应用:</p> - -<ul> - <li>全新的风格主题</li> - <li>用于设计复杂视图的全新小工具</li> - <li>用于自定义阴影和动画的全新 API</li> -</ul> - -<p>有关在 Android 上实现材料设计的详细信息,请参阅<a href="{@docRoot}training/material/index.html">使用材料设计创建应用</a>。 -</p> - - -<h3>材料主题</h3> - -<p>材料主题提供了新的应用样式和系统小工具,让您能够为触摸反馈以及 Activity 转换设置配色工具以及默认动画。 -</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">深色材料主题</p> - </div> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">浅色材料主题</p> - </div> -</div> -<br style="clear:left"/> -</div> - -<p>如需了解详细信息,请参阅<a href="{@docRoot}training/material/theme.html">使用材料主题 -</a>。</p> - - -<h3>列表和卡片</h3> - -<p>Android 提供了两个全新的小工具,用于显示采用材料设计样式和动画的卡片和列表: -</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" /> - <p>全新的 <code>RecyclerView</code> 小工具是 <code>ListView</code> - 的可插入版本,支持不同的布局类型,并且具有更高性能。</p> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> - <p>全新的 <code>CardView</code> 小工具可让您展示卡片内的重要信息,并且有统一的观感。 -</p> -</div> -<br style="clear:left"/> -</div> - -<p>如需了解详细信息,请参阅<a href="{@docRoot}training/material/lists-cards.html">创建列表和卡片</a>。 -</p> - - -<h3>视图阴影</h3> - -<p>除了 X 和 Y 属性之外,Android 中的视图现在还提供了 Z -属性。这一新属性用于展现视图的高度,从而确定:</p> - -<ul> -<li>阴影的大小:Z 值越高的视图投射的阴影越长。</li> -<li>绘制顺序:Z 值较高的视图会显示在其他视图的上方。</li> -</ul> - -<div style="width:290px;margin-left:35px;float:right"> - <div class="framed-nexus5-port-span-5"> - <video class="play-on-hover" autoplay> - <source src="{@docRoot}design/material/videos/ContactsAnim.mp4"/> - <source src="{@docRoot}design/videos/ContactsAnim.webm"/> - <source src="{@docRoot}design/videos/ContactsAnim.ogv"/> - </video> - </div> - <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> - <em>如果要重新播放影片,请点击设备屏幕</em> - </div> -</div> - -<p>如需了解详细信息,请参阅<a href="{@docRoot}training/material/shadows-clipping.html">定义阴影与裁剪视图</a>。 -</p> - - -<h3>动画</h3> - -<p>动画 API 让您可为 UI 控件中的触摸反馈、视图状态更改以及 Activity 转换创建自定义动画。 -</p> - -<p>这些 API 的作用是:</p> - -<ul> -<li style="margin-bottom:15px"> -使用<strong>触摸反馈</strong>动画响应视图中的触摸事件。 -</li> -<li style="margin-bottom:15px"> -使用<strong>循环显示</strong>动画隐藏和显示视图。 -</li> -<li style="margin-bottom:15px"> -使用自定义 <strong>Activity 转换</strong>动画切换 Activity。 -</li> -<li style="margin-bottom:15px"> -使用<strong>曲线运动</strong>创建更自然的动画。 -</li> -<li style="margin-bottom:15px"> -使用<strong>视图状态更改</strong>动画以动画形式呈现一个或多个视图属性的更改。 -</li> -<li style="margin-bottom:15px"> -在视图状态更改期间以<strong>可绘制状态列表</strong>显示动画。 -</li> -</ul> - -<p>触摸反馈动画内建于数个标准视图(例如按钮)中。全新的 API让您可以自定义这些动画并将其添加至自己的自定义视图中。 -</p> - -<p>如需了解详细信息,请参阅<a href="{@docRoot}training/material/animations.html">定义自定义动画</a>。 -</p> - - -<h3>可绘制对象</h3> - -<p>下列可绘制对象的新功能将帮助您实现材料设计应用:</p> - -<ul> -<li><strong>可绘制矢量</strong>可在不影响清晰度的情况下进行缩放,非常适合单色应用内图标。 -</li> -<li><strong>可绘制底色</strong>可让您将位图定义为 alpha 蒙板,并在运行时为其着色。 -</li> -<li><strong>颜色提取</strong>可让您从位图图像自动提取突出色彩。 -</li> -</ul> - -<p>如需了解详细信息,请参阅<a href="{@docRoot}training/material/drawables.html">使用可绘制内容</a>。 -</p> diff --git a/docs/html-intl/intl/zh-cn/design/material/index.jd b/docs/html-intl/intl/zh-cn/design/material/index.jd index f33d4bcddc3a..b667bb8ec772 100644 --- a/docs/html-intl/intl/zh-cn/design/material/index.jd +++ b/docs/html-intl/intl/zh-cn/design/material/index.jd @@ -1,6 +1,5 @@ page.title=Android 材料设计 -page.tags=Material,design -page.type=设计 +page.tags=Material,design,设计 page.image=images/cards/design-material-for-android_2x.jpg @jd:body diff --git a/docs/html-intl/intl/zh-cn/distribute/tools/promote/brand.jd b/docs/html-intl/intl/zh-cn/distribute/tools/promote/brand.jd index 065673ee5cb7..8984fc5cecf2 100644 --- a/docs/html-intl/intl/zh-cn/distribute/tools/promote/brand.jd +++ b/docs/html-intl/intl/zh-cn/distribute/tools/promote/brand.jd @@ -69,77 +69,6 @@ page.metaDescription=关于Android 和 Goolge Play 品牌的指南和下载。 <p>不得使用 Android 徽标专用的字体。</p> - <h2 id="brand-google_play">Google Play</h2> - - - <p>以下是关于 Google Play 品牌和相关资源的指南。</p> - - <h4>在文本中使用 Google Play</h4> - - <p>在文本中,请务必为首次出现或位于显著位置的 Google Play™ 加上 TM 符号。</p> - - <p>在提及移动设备体验时,除非相应文本中是很明显的说明性内容,否则请使用“Google Play”。例如,营销资料的标题可以是“从 Google Play™ 下载我们的游戏”,但是说明性内容可以是“使用 Google Play™ 商店应用下载我们的游戏”。 - - <p>每次使用 Google Play 名称或图标时,你的资料中都应注明以下归属信息:</p> - - <blockquote><em>Google Play 是 Google Inc. 的商标。</em></blockquote> - - - <div style="float:right;width:96px;margin-left:30px"> - <img src="{@docRoot}images/brand/Google_Play_Store_96.png" alt="" /> - <p style="text-align:center"> - <a href="{@docRoot}images/brand/Google_Play_Store_48.png">48x48</a> | - <a href="{@docRoot}images/brand/Google_Play_Store_96.png">96x96</a><br /> - <a href="{@docRoot}images/brand/Google_Play_Store_600.png">600x576</a> - </p> - </div> - - <h4>Google Play 商店图标</h4> - - <p>你可以使用 Google Play 商店图标,但不得修改它。</p> - - <p>如上文所述,在文案中提及 Google Play 商店应用时,请使用全称:“Google Play 商店”。但直接标注 Google Play 商店图标时,可以只使用“Play 商店”,以便与设备上显示的图标标签一致。</p> - - - <h4>Google Play 徽章</h4> - - <div style="float:right;clear:right;width:172px;margin-left:30px"> - <img src="{@docRoot}images/brand/en_app_rgb_wo_60.png" alt="" /> - <p style="text-align:center"> - <a href="{@docRoot}images/brand/en_app_rgb_wo_45.png">129x45</a> | - <a href="{@docRoot}images/brand/en_app_rgb_wo_60.png">172x60</a></p> - </div> - - <div style="float:right;clear:right;width:172px;margin-left:30px"> - <img src="{@docRoot}images/brand/en_generic_rgb_wo_60.png" alt="" /> - <p style="text-align:center"> - <a href="{@docRoot}images/brand/en_generic_rgb_wo_45.png">129x45</a> | - <a href="{@docRoot}images/brand/en_generic_rgb_wo_60.png">172x60</a></p> - </div> - - <p>你可以在网站和宣传资料中使用“即刻获取 Google Play”和“即刻获取 Android 应用 Google Play”徽标作为徽章,以指向你在 Google Play 上的商品。你也可以使用其他 Google Play 徽章格式,以及用于音乐、图书、杂志、电影和电视节目的徽章。要申请这些徽章,请使用 <a href="https://docs.google.com/forms/d/1YE5gZpAAcFKjYcUddCsK1Bv9a9Y-luaLVnkazVlaJ2w/viewform">Android 和 Google Play 品牌权限咨询表单</a>。</p> - - <ul> - <li>请不要修改徽章图片的颜色、比例、间距或其他任何方面。 - </li> - <li>当与其他应用市场的徽标一起使用时,Google Play 徽标尺寸不应小于这些徽标的尺寸。</li> - <li>在线使用时,徽章应链接至以下内容之一: - <ul> - <li>由你发布的商品的列表,例如:<br /> - <span style="margin-left:1em">http://play.google.com/store/search?q=publisherName<em></em></span> - </li> - <li>Google Play 中相应应用的商品详情页,例如:<br /> - <span style="margin-left:1em">http://play.google.com/store/apps/details?id=packageName<em></em></span> - </li> - </ul> - </li> - </ul> - - <p>要快速创建链接至你在 Google Play 上的应用的徽章,请使用 <a href="{@docRoot}distribute/tools/promote/badges.html">Google Play 徽章生成器</a>(支持 40 多种语言)。</p> - - <p>要创建自定义尺寸的徽章,请下载<a href="{@docRoot}distribute/tools/promote/badge-files.html">支持 40 多种语言的 Google Play 徽章</a>的 Adobe® Illustrator® (.ai) 文件。</p> - - <p>要详细了解如何链接至 Google Play 中的商品详情页,请参阅<a href="{@docRoot}distribute/tools/promote/linking.html">链接至你的商品</a>。</p> <h2 id="Marketing_Review">营销审核和品牌咨询</h2> diff --git a/docs/html-intl/intl/zh-cn/index.jd b/docs/html-intl/intl/zh-cn/index.jd index b39289594dc2..c915863c6f7a 100644 --- a/docs/html-intl/intl/zh-cn/index.jd +++ b/docs/html-intl/intl/zh-cn/index.jd @@ -5,6 +5,16 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 @jd:body +<script> + $(document).ready(function() { + if (useUpdatedTemplates) { + $("#useUpdatedTemplates").css("display","block"); + } else { + $("#useOldTemplates").css("display","block"); + } + }) +</script> + <!-- <div class="dac-hero-carousel" data-carousel-query="collection:index/carousel"> </div> --> <section class="dac-hero-carousel"> @@ -39,11 +49,39 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 </a> </article></section> -<div class="actions-bar dac-expand dac-invert"> +<div id="useUpdatedTemplates" style="display:none" class="dac-section dac-slim dac-gray dac-expand"> <div class="wrap dac-offset-parent"> <a class="dac-fab dac-scroll-button" data-scroll-button href="#build-apps"> <i class="dac-sprite dac-arrow-down-gray"></i> </a> + <ul class="dac-actions"> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}sdk/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Get the SDK + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}samples/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Browse sample code + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}distribute/stories/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Watch stories + </a> + </li> + </ul> + </div><!-- end .wrap --> +</div><!-- end .dac-actions --> + +<div id="useOldTemplates" style="display:none" class="actions-bar dac-expand dac-invert"> + <div class="wrap dac-offset-parent"> + <a class="dac-fab dac-scroll-button" data-scroll-button="" href="#build-apps"> + <i class="dac-sprite dac-arrow-down-gray"></i> + </a> <div class="actions"> <div><a href="{@docRoot}sdk/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> @@ -53,17 +91,15 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 <span class="dac-sprite dac-auto-chevron-large"></span> Browse Samples </a></div> - <div><a href="//www.youtube.com/user/androiddevelopers"> + <div><a href="{@docRoot}distribute/stories/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> - Watch Videos + Watch Stories </a></div> </div><!-- end .actions --> </div><!-- end .wrap --> -</div><!-- end .actions-bar --> - - +</div> -<section class="dac-section dac-section-light" id="build-apps"><div class="wrap"> +<section class="dac-section dac-light" id="build-apps"><div class="wrap"> <h1 class="dac-section-title">Build Beautiful Apps</h1> <div class="dac-section-subtitle"> Resources to get you started with designing and developing for Android. diff --git a/docs/html-intl/intl/zh-cn/sdk/index.jd b/docs/html-intl/intl/zh-cn/sdk/index.jd index 2b2e98b6f54e..407fc2d7bda6 100644 --- a/docs/html-intl/intl/zh-cn/sdk/index.jd +++ b/docs/html-intl/intl/zh-cn/sdk/index.jd @@ -1,62 +1,14 @@ page.title=下载 Android Studio 和 SDK 工具 page.tags=sdk, android studio page.template=sdk +page.image=images/cards/android-studio_2x.png header.hide=1 page.metaDescription=下载官方 Android IDE 和开发者工具,构建适用于 Android 手机、平板电脑、可穿戴设备、电视等设备的应用。 -studio.version=1.4.0.10 - -studio.linux_bundle_download=android-studio-ide-141.2288178-linux.zip -studio.linux_bundle_bytes=380821638 -studio.linux_bundle_checksum=137e3734f2e8e285bd7c1d2fae2e8548d0f164bd - -studio.mac_bundle_download=android-studio-ide-141.2288178-mac.dmg -studio.mac_bundle_bytes=364624965 -studio.mac_bundle_checksum=27068d59d5a78717d31bdedd054082b5c50d3897 - -studio.win_bundle_download=android-studio-ide-141.2288178-windows.zip -studio.win_bundle_bytes=373492997 -studio.win_bundle_checksum=c0851dc9a506ba9f4c1379a3e9b4019c08478220 - - -studio.win_bundle_exe_download=android-studio-bundle-141.2288178-windows.exe -studio.win_bundle_exe_bytes=1177811944 -studio.win_bundle_exe_checksum=a2f0141d35f8f0c24dad2ff390e7f6231c5f7625 - -studio.win_notools_exe_download=android-studio-ide-141.2288178-windows.exe -studio.win_notools_exe_bytes=348295968 -studio.win_notools_exe_checksum=82d0d9c78ec23834956f941a07821be347fcb7bf - - - - -sdk.linux_download=android-sdk_r24.3.4-linux.tgz -sdk.linux_bytes=309138331 -sdk.linux_checksum=fb293d7bca42e05580be56b1adc22055d46603dd - -sdk.mac_download=android-sdk_r24.3.4-macosx.zip -sdk.mac_bytes=98340900 -sdk.mac_checksum=128f10fba668ea490cc94a08e505a48a608879b9 - -sdk.win_download=android-sdk_r24.3.4-windows.zip -sdk.win_bytes=187496897 -sdk.win_checksum=4a8718fb4a2bf2128d34b92f23ddd79fc65839e7 - - -sdk.win_installer=installer_r24.3.4-windows.exe -sdk.win_installer_bytes=139477985 -sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd - - - - - - @jd:body <style type="text/css"> .offline {display:none;} - a.download-bundle-button {display:block;} h2.feature { padding-top:30px; margin-top:0; @@ -64,20 +16,7 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd } .feature-blurb { margin:0px; font-size:16px; font-weight:300; - padding:40px 0 0 0; - } - - .landing-button.green { - font-size:16px; - background-color:#90c653; - padding:8px 10px 10px; - margin:0; - width:206px; - text-align:center; - } - - .landing-button.green:hover { - background-color:#85b84f; + padding-top:40px; } .landing-button .small { @@ -95,8 +34,8 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd white-space: nowrap; text-indent: -10000px; font-size:0px; - background: url(../images/tools/studio-logo.png); - background-image: -webkit-image-set(url(../images/tools/studio-logo.png) 1x, url(../images/tools/studio-logo_2x.png) 2x); + background: url({@docRoot}images/tools/studio-logo.png); + background-image: -webkit-image-set(url({@docRoot}images/tools/studio-logo.png) 1x, url({@docRoot}images/tools/studio-logo_2x.png) 2x); background-size: 226px 78px; } @@ -292,15 +231,15 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd <p style="font-size: 16px; color:#bbb; position: absolute;left: 297px; top: 5px; display: block; width: 400px;text-align: center;">官方 Android IDE</p> -<ul style="font-size:12px"> +<ul style="font-size:12px;line-height:19px;"> <li>Android Studio IDE</li> <li>Android SDK 工具</li> <li>Android 6.0 (Marshmallow) 平台</li> <li>Android 6.0 模拟器系统映像(附带 Google API)</li> </ul> - -<a class="online landing-button green download-bundle-button" style="margin-top:30px;" href="#Other">Download</a> +<a class="online landing-button green download-bundle-button" +href="#Other" >Download Android Studio<br/><span class='small'></span></a> <!-- this appears when viewing the offline docs --> <p class="offline"> diff --git a/docs/html-intl/intl/zh-cn/sdk/installing/adding-packages.jd b/docs/html-intl/intl/zh-cn/sdk/installing/adding-packages.jd index 04f55b10da97..4d5d7ec8b0c9 100644 --- a/docs/html-intl/intl/zh-cn/sdk/installing/adding-packages.jd +++ b/docs/html-intl/intl/zh-cn/sdk/installing/adding-packages.jd @@ -1,7 +1,6 @@ page.title=添加 SDK 软件包 page.tags=sdk 管理器 -helpoutsWidget=true @jd:body @@ -31,7 +30,7 @@ ol.large > li > h2 { line-height:20px; padding:0 0 0 20px; margin:0 0 20px 0; - display:inline-block; + display:inline; font-weight:normal; } ol.large > li:nth-child(1):before { diff --git a/docs/html-intl/intl/zh-tw/design/index.jd b/docs/html-intl/intl/zh-tw/design/index.jd deleted file mode 100644 index 43134fc1a8bf..000000000000 --- a/docs/html-intl/intl/zh-tw/design/index.jd +++ /dev/null @@ -1,186 +0,0 @@ -page.title=Android 材料設計 -page.tags=Material,design -page.type=設計 -page.image=images/cads/design-material-for-android_2x.jpg - -@jd:body - -<!-- developer docs box --> -<a class="notice-developers right" href="{@docRoot}training/material/index.html"> - <div> - <h3>開發人員文件</h3> - <p>使用材料設計建立應用程式</p> - </div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=p4gmvHyuZzw"> -<div> - <h3>影片</h3> - <p>材料設計簡介</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=YaG_ljfzeUw"> -<div> - <h3>影片</h3> - <p>紙張和墨水:重要的材料</p> -</div> -</a> - -<!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=XOcCOBe8PTc"> -<div> - <h3>影片</h3> - <p>Google I/O 應用程式中的材料設計</p> -</div> -</a> - - - -<p itemprop="description">材料設計是一份內容廣泛的綜合性指南,引導您跨平台、跨裝置進行視覺、動態和互動的設計。 -Android 現已納入對材料設計應用程式的支援。 -如果要在 Android 應用程式中使用材料設計,請依照<a href="http://www.google.com/design/spec">材料設計規格</a>中定義的指示,並使用 Android 5.0 (API 級別 21) 或後續版本中的新元件和新功能。 - -</p> - -<p>Android 提供下列元素,供您打造材料設計應用程式:</p> - -<ul> - <li>新的設計風格</li> - <li>用於複雜視圖的小工具</li> - <li>自訂陰影和動畫的新 API</li> -</ul> - -<p>如需取得如何在 Android 上實作材料設計的詳細資訊,請參閱<a href="{@docRoot}training/material/index.html">使用材料設計建立應用程式</a>。 -</p> - - -<h3>材料設計風格</h3> - -<p>材料設計風格提供您應用程式使用的新樣式、可以讓您設定色板的系統小工具,並針對輕觸回饋與操作行為轉換提供預設動畫。 -</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/MaterialDark.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">深色材料設計風格</p> - </div> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/MaterialLight.png" width="500" height="238" /> - <div style="width:140px;margin:0 auto"> - <p style="margin-top:8px">淺色材料設計風格</p> - </div> -</div> -<br style="clear:left"/> -</div> - -<p>如需詳細資訊,請參閱<a href="{@docRoot}training/material/theme.html">使用材料設計風格</a>。 -</p> - - -<h3>清單和卡片</h3> - -<p>Android 提供兩個新的小工具,搭配材料設計樣式與動畫,可用來顯示清單和卡片: -</p> - -<!-- two columns --> -<div style="width:700px;margin-top:25px;margin-bottom:20px"> -<div style="float:left;width:250px;margin-left:40px;margin-right:60px;"> - <img src="{@docRoot}design/material/images/list_mail.png" width="500" height="426" /> - <p>新的 <code>RecyclerView</code> 小工具是 <code>ListView</code> 更容易插入的版本,支援不同的版面配置類型,並提供效能改善。 -</p> -</div> -<div style="float:left;width:250px;margin-right:0px;"> - <img src="{@docRoot}design/material/images/card_travel.png" width="500" height="426" /> - <p>新的 <code>CardView</code> 小工具讓您可以顯示卡片內的重要資訊,並且該資訊都能擁有一致的外觀與風格。 -</p> -</div> -<br style="clear:left"/> -</div> - -<p>如需詳細資訊,請參閱<a href="{@docRoot}training/material/lists-cards.html">建立清單和卡片</a>。 -</p> - - -<h3>檢視陰影</h3> - -<p>除了 X 和 Y 屬性外,Android 中的視圖現在也有 Z 屬性。 -這個新屬性代表視圖的高度,這會決定:</p> - -<ul> -<li>陰影大小:Z 值較高的視圖會投射更大的陰影。</li> -<li>繪製順序:Z 值較高的視圖會顯示在其他視圖之上。</li> -</ul> - -<div style="width:290px;margin-left:35px;float:right"> - <div class="framed-nexus5-port-span-5"> - <video class="play-on-hover" autoplay> - <source src="{@docRoot}design/material/videos/ContactsAnim.mp4"/> - <source src="{@docRoot}design/videos/ContactsAnim.webm"/> - <source src="{@docRoot}design/videos/ContactsAnim.ogv"/> - </video> - </div> - <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> - 如要重播影片,請按一下裝置螢幕<em></em> - </div> -</div> - -<p>如需詳細資訊,請參閱<a href="{@docRoot}training/material/shadows-clipping.html">定義陰影和裁剪視圖</a>。 -</p> - - -<h3>動畫</h3> - -<p>新的動畫 API 可針對 UI 控制項的輕觸回饋、視圖狀態中的變更,以及操作行為轉換,讓您建立自訂動畫。 -</p> - -<p>這些 API 讓您可以:</p> - -<ul> -<li style="margin-bottom:15px"> -回應您視圖中有<strong>輕觸回饋</strong>動畫的輕觸事件。 -</li> -<li style="margin-bottom:15px"> -隱藏和顯示有<strong>循環顯示</strong>動畫的視圖。 -</li> -<li style="margin-bottom:15px"> -在包含自訂<strong>操作行為轉換</strong>動畫的行為間切換。 -</li> -<li style="margin-bottom:15px"> -使用<strong>曲線動作</strong>建立更自然的動畫。 -</li> -<li style="margin-bottom:15px"> -在包含<strong>視圖狀態變更</strong>動畫的一個或多個視圖屬性中變更動畫。 -</li> -<li style="margin-bottom:15px"> -在視圖狀態變更之間,顯示<strong>狀態清單可繪項目</strong>中的動畫。 -</li> -</ul> - -<p>輕觸回饋動畫會內建於數個標準視圖中,例如按鈕等。新 API 可讓您自訂這些動畫,並將其新增至您的自訂視圖中。 -</p> - -<p>如需詳細資訊,請參閱<a href="{@docRoot}training/material/animations.html">定義自訂動畫</a>。 -</p> - - -<h3>可繪項目</h3> - -<p>可繪項目的這些新功能可以幫助您實作材料設計應用程式:</p> - -<ul> -<li><strong>矢量可繪項目</strong>可以調整大小,但又不會喪失定義,最適合於應用程式中的單色圖示。 -</li> -<li><strong>繪製著色</strong>可讓您在執行階段將點陣圖定義為 Alpha 遮罩,並以一個顏色進行著色。 -</li> -<li><strong>顏色提取</strong>可讓您自動從點陣圖影像中提取顯著顏色。 -</li> -</ul> - -<p>如需詳細資訊,請參閱<a href="{@docRoot}training/material/drawables.html">使用可繪項目</a>。 -</p> diff --git a/docs/html-intl/intl/zh-tw/design/material/index.jd b/docs/html-intl/intl/zh-tw/design/material/index.jd index ecc266106a88..464dc2a1b216 100644 --- a/docs/html-intl/intl/zh-tw/design/material/index.jd +++ b/docs/html-intl/intl/zh-tw/design/material/index.jd @@ -1,7 +1,6 @@ page.title=Android 材料設計 -page.tags=Material,design -page.type=設計 -page.image=mages/cards/design-material-for-android_2x.jpg +page.tags=Material,design, 設計 +page.image=images/cards/design-material-for-android_2x.jpg @jd:body @@ -135,12 +134,7 @@ Android 現已納入對材料設計應用程式的支援。 <h3>動畫</h3> - -<<<<<<< HEAD <p>新的動畫 API 可針對 UI 控制項的輕觸回饋、視圖狀態中的變更,以及操作行為轉換,讓您建立自訂動畫。 -======= -<p>新的動畫 API 可針對 UI 控制項的輕觸回饋、視圖狀態中的變更,以及 Activity 轉換,讓您建立自訂動畫。 ->>>>>>> Docs: L10N update for design documentation </p> <p>這些 API 讓您可以:</p> @@ -153,11 +147,7 @@ Android 現已納入對材料設計應用程式的支援。 隱藏和顯示有<strong>循環顯示</strong>動畫的視圖。 </li> <li style="margin-bottom:15px"> -<<<<<<< HEAD 在包含自訂<strong>操作行為轉換</strong>動畫的行為間切換。 -======= -在包含自訂 <strong>Activity 轉換</strong>動畫的 Activity 間切換。 ->>>>>>> Docs: L10N update for design documentation </li> <li style="margin-bottom:15px"> 使用<strong>曲線動作</strong>建立更自然的動畫。 diff --git a/docs/html-intl/intl/zh-tw/index.jd b/docs/html-intl/intl/zh-tw/index.jd index cbac617cb59e..493283bd4fb7 100644 --- a/docs/html-intl/intl/zh-tw/index.jd +++ b/docs/html-intl/intl/zh-tw/index.jd @@ -5,6 +5,16 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 @jd:body +<script> + $(document).ready(function() { + if (useUpdatedTemplates) { + $("#useUpdatedTemplates").css("display","block"); + } else { + $("#useOldTemplates").css("display","block"); + } + }) +</script> + <!-- <div class="dac-hero-carousel" data-carousel-query="collection:index/carousel"> </div> --> <section class="dac-hero-carousel"> @@ -39,11 +49,39 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 </a> </article></section> -<div class="actions-bar dac-expand dac-invert"> +<div id="useUpdatedTemplates" style="display:none" class="dac-section dac-slim dac-gray dac-expand"> <div class="wrap dac-offset-parent"> <a class="dac-fab dac-scroll-button" data-scroll-button href="#build-apps"> <i class="dac-sprite dac-arrow-down-gray"></i> </a> + <ul class="dac-actions"> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}sdk/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Get the SDK + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}samples/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Browse sample code + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}distribute/stories/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Watch stories + </a> + </li> + </ul> + </div><!-- end .wrap --> +</div><!-- end .dac-actions --> + +<div id="useOldTemplates" style="display:none" class="actions-bar dac-expand dac-invert"> + <div class="wrap dac-offset-parent"> + <a class="dac-fab dac-scroll-button" data-scroll-button="" href="#build-apps"> + <i class="dac-sprite dac-arrow-down-gray"></i> + </a> <div class="actions"> <div><a href="{@docRoot}sdk/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> @@ -53,17 +91,15 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 <span class="dac-sprite dac-auto-chevron-large"></span> Browse Samples </a></div> - <div><a href="//www.youtube.com/user/androiddevelopers"> + <div><a href="{@docRoot}distribute/stories/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> - Watch Videos + Watch Stories </a></div> </div><!-- end .actions --> </div><!-- end .wrap --> -</div><!-- end .actions-bar --> - - +</div> -<section class="dac-section dac-section-light" id="build-apps"><div class="wrap"> +<section class="dac-section dac-light" id="build-apps"><div class="wrap"> <h1 class="dac-section-title">Build Beautiful Apps</h1> <div class="dac-section-subtitle"> Resources to get you started with designing and developing for Android. diff --git a/docs/html-intl/intl/zh-tw/sdk/index.jd b/docs/html-intl/intl/zh-tw/sdk/index.jd index a4869d91abb8..aff9d1b6684c 100644 --- a/docs/html-intl/intl/zh-tw/sdk/index.jd +++ b/docs/html-intl/intl/zh-tw/sdk/index.jd @@ -1,62 +1,14 @@ page.title=下載 Android Studio 和 SDK 工具 page.tags=sdk, android studio page.template=sdk +page.image=images/cards/android-studio_2x.png header.hide=1 page.metaDescription=下載官方 Android IDE 和開發人員工具以建置適用於 Android 手機、平板電腦、穿戴式裝置、電視等裝置的應用程式。 -studio.version=1.4.0.10 - -studio.linux_bundle_download=android-studio-ide-141.2288178-linux.zip -studio.linux_bundle_bytes=380821638 -studio.linux_bundle_checksum=137e3734f2e8e285bd7c1d2fae2e8548d0f164bd - -studio.mac_bundle_download=android-studio-ide-141.2288178-mac.dmg -studio.mac_bundle_bytes=364624965 -studio.mac_bundle_checksum=27068d59d5a78717d31bdedd054082b5c50d3897 - -studio.win_bundle_download=android-studio-ide-141.2288178-windows.zip -studio.win_bundle_bytes=373492997 -studio.win_bundle_checksum=c0851dc9a506ba9f4c1379a3e9b4019c08478220 - - -studio.win_bundle_exe_download=android-studio-bundle-141.2288178-windows.exe -studio.win_bundle_exe_bytes=1177811944 -studio.win_bundle_exe_checksum=a2f0141d35f8f0c24dad2ff390e7f6231c5f7625 - -studio.win_notools_exe_download=android-studio-ide-141.2288178-windows.exe -studio.win_notools_exe_bytes=348295968 -studio.win_notools_exe_checksum=82d0d9c78ec23834956f941a07821be347fcb7bf - - - - -sdk.linux_download=android-sdk_r24.3.4-linux.tgz -sdk.linux_bytes=309138331 -sdk.linux_checksum=fb293d7bca42e05580be56b1adc22055d46603dd - -sdk.mac_download=android-sdk_r24.3.4-macosx.zip -sdk.mac_bytes=98340900 -sdk.mac_checksum=128f10fba668ea490cc94a08e505a48a608879b9 - -sdk.win_download=android-sdk_r24.3.4-windows.zip -sdk.win_bytes=187496897 -sdk.win_checksum=4a8718fb4a2bf2128d34b92f23ddd79fc65839e7 - - -sdk.win_installer=installer_r24.3.4-windows.exe -sdk.win_installer_bytes=139477985 -sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd - - - - - - @jd:body <style type="text/css"> .offline {display:none;} - a.download-bundle-button {display:block;} h2.feature { padding-top:30px; margin-top:0; @@ -64,20 +16,7 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd } .feature-blurb { margin:0px; font-size:16px; font-weight:300; - padding:40px 0 0 0; - } - - .landing-button.green { - font-size:16px; - background-color:#90c653; - padding:8px 10px 10px; - margin:0; - width:206px; - text-align:center; - } - - .landing-button.green:hover { - background-color:#85b84f; + padding-top:40px; } .landing-button .small { @@ -95,8 +34,8 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd white-space: nowrap; text-indent: -10000px; font-size:0px; - background: url(../images/tools/studio-logo.png); - background-image: -webkit-image-set(url(../images/tools/studio-logo.png) 1x, url(../images/tools/studio-logo_2x.png) 2x); + background: url({@docRoot}images/tools/studio-logo.png); + background-image: -webkit-image-set(url({@docRoot}images/tools/studio-logo.png) 1x, url({@docRoot}images/tools/studio-logo_2x.png) 2x); background-size: 226px 78px; } @@ -292,15 +231,15 @@ sdk.win_installer_checksum=094dd45f98a31f839feae898b48f23704f2878dd <p style="font-size: 16px; color:#bbb; position: absolute;left: 297px; top: 5px; display: block; width: 400px;text-align: center;">官方 Android IDE</p> -<ul style="font-size:12px"> +<ul style="font-size:12px;line-height:19px;"> <li>Android Studio IDE</li> <li>Android SDK 工具</li> <li>Android 6.0 (Marshmallow) 平台</li> <li>含 Google API 的 Android 6.0 模擬器系統映像檔</li> </ul> - -<a class="online landing-button green download-bundle-button" style="margin-top:30px;" href="#Other">Download</a> +<a class="online landing-button green download-bundle-button" +href="#Other" >Download Android Studio<br/><span class='small'></span></a> <!-- this appears when viewing the offline docs --> <p class="offline"> diff --git a/docs/html-intl/intl/zh-tw/sdk/installing/adding-packages.jd b/docs/html-intl/intl/zh-tw/sdk/installing/adding-packages.jd index 7b4ad0b37aa3..563df51e22d3 100644 --- a/docs/html-intl/intl/zh-tw/sdk/installing/adding-packages.jd +++ b/docs/html-intl/intl/zh-tw/sdk/installing/adding-packages.jd @@ -1,7 +1,6 @@ page.title=新增 SDK 封裝 page.tags=sdk manager -helpoutsWidget=true @jd:body @@ -31,7 +30,7 @@ ol.large > li > h2 { line-height:20px; padding:0 0 0 20px; margin:0 0 20px 0; - display:inline-block; + display:inline; font-weight:normal; } ol.large > li:nth-child(1):before { diff --git a/docs/html/about/about_toc.cs b/docs/html/about/about_toc.cs index eb59b12dcb22..a45601278d88 100644 --- a/docs/html/about/about_toc.cs +++ b/docs/html/about/about_toc.cs @@ -1,6 +1,5 @@ <ul id="nav"> - - <li class="nav-section"> + <li class="nav-section"> <div class="nav-section-header"><a href="<?cs var:toroot ?>about/versions/marshmallow/index.html"> <span class="en">Marshmallow</span></a></div> <ul> @@ -10,7 +9,6 @@ Android 6.0 Changes</a></li> <li><a href="<?cs var:toroot ?>about/versions/marshmallow/samples.html"> Android 6.0 Samples</a></li> - </li> </ul> </li> <li class="nav-section"> diff --git a/docs/html/about/android.jd b/docs/html/about/android.jd index ad0ea7c96676..e3b6958db73e 100644 --- a/docs/html/about/android.jd +++ b/docs/html/about/android.jd @@ -26,7 +26,7 @@ the fastest-growing mobile OS.</p> <blockquote>Every day more than a million new Android devices are activated worldwide.</blockquote> <p>Android’s openness has made it a favorite for consumers and developers alike, -driving strong growth in app consumption. Android users download more than +driving strong growth in app consumption. Android users download billions of apps and games from Google Play each month. </p> <p>With its partners, Android is continuously pushing the boundaries of hardware and software @@ -76,7 +76,7 @@ offer a full Java IDE with advanced features for developing, debugging, and packaging Android apps. Using the IDE, you can develop on any available Android device or create virtual devices that emulate any hardware configuration.</p> -<blockquote>1.5 billion downloads a month and growing. Get your apps in front +<blockquote>Billion downloads a month and growing. Get your apps in front of millions of users at Google's scale.</blockquote> <h3>Open marketplace for distributing your apps</h3> @@ -107,5 +107,5 @@ Play gives them higher placement in weekly "top" charts and rankings, and for the best apps promotional slots in curated collections. </p> -<p>Preinstalled on hundreds of billions of Android devices around the world, +<p>Preinstalled on billions of Android devices around the world, Google Play can be a growth engine for your business.</p>
\ No newline at end of file diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd index 9274d5d2932f..471dc07479e1 100644 --- a/docs/html/about/dashboards/index.jd +++ b/docs/html/about/dashboards/index.jd @@ -1,7 +1,9 @@ page.title=Dashboards -page.metaDescription=page.metaDescription=Charts that give you an overview of device characteristics and platform versions that are active in the Android ecosystem. +page.metaDescription=page.metaDescription=An overview of device characteristics and platform versions that are active in the Android ecosystem. page.tags="android, dashboard, platforms, versions" -meta.tags="ecosystem, versions, whatsnew" +meta.tags="ecosystem, versions, whatsnew, dashboards" +page.image=http://chart.googleapis.com/chart?chl=GL%201.1%20only%7CGL%202.0%7CGL%203.0&chf=bg%2Cs%2C00000000&chd=t%3A0.1%2C93.5%2C6.4&chco=c4df9b%2C6fad0c&chs=400x250&cht=p + @jd:body <style> diff --git a/docs/html/about/index.jd b/docs/html/about/index.jd index 215fc3c26504..22f504edc408 100644 --- a/docs/html/about/index.jd +++ b/docs/html/about/index.jd @@ -119,40 +119,4 @@ the best apps promotional slots in curated collections. <p>Preinstalled on hundreds of millions of Android devices around the world, Google Play can be a growth engine for your business.</p> -<p><a class="landing-page-link" href="{@docRoot}about/start.html">GET STARTED</a></p> - -<div style="background: #F0F0F0; - border-top: 1px solid #DDD; - padding: 20px 0 24px 0; - overflow: auto; - clear:both; - margin-bottom:-10px; - margin-top:60px;""> - <div style="padding:0 0 0 29px;"> - <h4>Developer Story: Robot Invader</h4> - <img alt="" class="screenshot thumbnail" style="-webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px height:78px; - width: 78px; - float: left; - margin: 17px 20px 9px 0;" src= - "//g0.gstatic.com/android/market/com.robotinvader.knightmare/hi-256-0-9e08d83bc8d01649e167131d197ada1cd1783fb0"> - <div style="width:700px;"> - <p style="margin-top:26px;margin-bottom:12px;">Robot Invader chose - Android as the launch platform for their first game, - <a data-g-event="Developers Page" data-g-label="Case Study Link" href= - "//play.google.com/store/apps/details?id=com.robotinvader.knightmare"><em>Wind-up - Knight</em></a>. - </p> - <p> - Hear from the developers themselves how Android helped them reach more - than 100 devices with a single app binary, then iterate rapidly to ensure - a great experience for users. - </p> - </div> - <iframe style="float:left; - margin-right:24px; - margin-top:14px;" width="700" height="394" src= - "http://www.youtube.com/embed/hTtlLiUTowY" frameborder="0" allowfullscreen></iframe> - </div> -</div>
\ No newline at end of file +<p><a class="landing-page-link" href="{@docRoot}about/start.html">GET STARTED</a></p>
\ No newline at end of file diff --git a/docs/html/about/versions/kitkat.jd b/docs/html/about/versions/kitkat.jd index dff350899971..2987bd491440 100644 --- a/docs/html/about/versions/kitkat.jd +++ b/docs/html/about/versions/kitkat.jd @@ -58,11 +58,10 @@ window.onhashchange = function () { <img src="{@docRoot}images/kk-devices.png" alt="Android 4.4 on phone and tablet" width="380"> </div> - <div class="landing-docs" style="float:right;clear:both;margin:22px 0 2em 3em;"> - <div class="col-4 normal-links highlights" style="font-size:12px;"> - <h3 id="thisd" >Key Developer Features</h3> +<div id="qv-wrapper"> + <div id="qv"> + <h2 id="features" >Key Developer Features</h3> <ul style="list-style-type:none;"> - <!--<li><a href="#44-ui">UI refresh</a></li>--> <li><a href="#44-hce">Host Card Emulation</a></li> <li><a href="#44-printing">Printing framework</a></li> <li><a href="#44-storage-access">Storage access framework</a></li> diff --git a/docs/html/about/versions/marshmallow/android-6.0-changes.jd b/docs/html/about/versions/marshmallow/android-6.0-changes.jd index bae47175be8a..f998590f5f7e 100644 --- a/docs/html/about/versions/marshmallow/android-6.0-changes.jd +++ b/docs/html/about/versions/marshmallow/android-6.0-changes.jd @@ -346,8 +346,8 @@ addNetwork()} method) are now removed if that work profile is deleted. Owners have the privilege of editing or removing any Wi-Fi configurations, including those not created by them. </li> -<li><strong>Download Work Policy Controller via Google account addition:</strong> When a Google -account that requires management via a Work Policy Controller (WPC) app is added to a device +<li><strong>Download device policy controller via Google account addition:</strong> When a Google +account that requires management via a device policy controller (DPC) app is added to a device outside of a managed context, the add account flow now prompts the user to install the appropriate WPC. This behavior also applies to accounts added via <strong>Settings > Accounts</strong> and in the initial device setup wizard.</li> diff --git a/docs/html/about/versions/marshmallow/android-6.0.jd b/docs/html/about/versions/marshmallow/android-6.0.jd index 732932f76e6d..779ecf48c044 100644 --- a/docs/html/about/versions/marshmallow/android-6.0.jd +++ b/docs/html/about/versions/marshmallow/android-6.0.jd @@ -553,7 +553,7 @@ a Device Owner can now auto-accept a system update, for instance in the case of a kiosk device, or postpone the update and prevent it being taken by the user for up to 30 days. Furthermore, an administrator can set a daily time window in which an update must be taken, for example during the hours when a kiosk device is not in use. When -a system update is available, the system checks if the Work Policy Controller app has set a system +a system update is available, the system checks if the device policy controller app has set a system update policy, and behaves accordingly. </li> <li> diff --git a/docs/html/about/versions/marshmallow/index.jd b/docs/html/about/versions/marshmallow/index.jd index a7bca5656f64..35edd72a38ec 100644 --- a/docs/html/about/versions/marshmallow/index.jd +++ b/docs/html/about/versions/marshmallow/index.jd @@ -2,7 +2,8 @@ page.title=Android 6.0 Marshmallow page.tags="marshmallow" meta.tags="marshamallow","android60" fullpage=true -section.landing=true +nonavpage=true +forcelocalnav=true header.hide=1 footer.hide=1 @jd:body @@ -55,6 +56,7 @@ footer.hide=1 <div class="resource-widget resource-flow-layout col-16" data-query="collection:marshmallow/landing/more" data-cardSizes="6x6" + data-items-per-page="15" data-initial-results="3"></div> </div> </section> @@ -68,17 +70,19 @@ footer.hide=1 <div class="resource-widget resource-flow-layout col-16" data-query="collection:marshmallow/landing/videos" data-cardSizes="6x6" + data-items-per-page="15" data-initial-results="6"></div> </div> </section> -<section class="dac-section dac-gray dac-small dac-invert" id="latest"><div class="wrap"> +<section class="dac-section dac-gray dac-small" id="latest"><div class="wrap"> <h2 class="norule">Latest</h2> <div class="resource-widget resource-flow-layout col-16" data-query="type:blog+tag:marshmallow" data-sortOrder="-timestamp" data-cardSizes="6x6" - data-maxResults="12" + data-maxResults="24" + data-items-per-page="15" data-initial-results="3"> </div> </section> diff --git a/docs/html/auto/images/ui/gearhead_custom_UI.png b/docs/html/auto/images/ui/gearhead_custom_UI.png Binary files differindex a3baba461f9d..fce7eb8ce7d1 100644 --- a/docs/html/auto/images/ui/gearhead_custom_UI.png +++ b/docs/html/auto/images/ui/gearhead_custom_UI.png diff --git a/docs/html/auto/images/ui/gearhead_custom_user_actions.png b/docs/html/auto/images/ui/gearhead_custom_user_actions.png Binary files differindex 8e65ee04c185..5aedbb9fb8c3 100644 --- a/docs/html/auto/images/ui/gearhead_custom_user_actions.png +++ b/docs/html/auto/images/ui/gearhead_custom_user_actions.png diff --git a/docs/html/auto/images/ui/gearhead_day.png b/docs/html/auto/images/ui/gearhead_day.png Binary files differindex a3baba461f9d..5593caa36c82 100644 --- a/docs/html/auto/images/ui/gearhead_day.png +++ b/docs/html/auto/images/ui/gearhead_day.png diff --git a/docs/html/auto/images/ui/gearhead_drawer_generic.png b/docs/html/auto/images/ui/gearhead_drawer_generic.png Binary files differindex 94dd3058f39f..1d6fc8501ac0 100644 --- a/docs/html/auto/images/ui/gearhead_drawer_generic.png +++ b/docs/html/auto/images/ui/gearhead_drawer_generic.png diff --git a/docs/html/auto/images/ui/gearhead_drawers_customized.png b/docs/html/auto/images/ui/gearhead_drawers_customized.png Binary files differindex fe74a4960e11..308e8cf89dd7 100644 --- a/docs/html/auto/images/ui/gearhead_drawers_customized.png +++ b/docs/html/auto/images/ui/gearhead_drawers_customized.png diff --git a/docs/html/auto/images/ui/gearhead_generic_UI.png b/docs/html/auto/images/ui/gearhead_generic_UI.png Binary files differindex d7cd53dd9e34..cd519292cb8c 100644 --- a/docs/html/auto/images/ui/gearhead_generic_UI.png +++ b/docs/html/auto/images/ui/gearhead_generic_UI.png diff --git a/docs/html/auto/images/ui/gearhead_lens_switching.png b/docs/html/auto/images/ui/gearhead_lens_switching.png Binary files differindex 9fb8b65b7115..39e4bc62df24 100644 --- a/docs/html/auto/images/ui/gearhead_lens_switching.png +++ b/docs/html/auto/images/ui/gearhead_lens_switching.png diff --git a/docs/html/auto/images/ui/gearhead_night.png b/docs/html/auto/images/ui/gearhead_night.png Binary files differindex 8f1ecdd48e60..424df16f9ec7 100644 --- a/docs/html/auto/images/ui/gearhead_night.png +++ b/docs/html/auto/images/ui/gearhead_night.png diff --git a/docs/html/auto/images/ui/gearhead_overview.png b/docs/html/auto/images/ui/gearhead_overview.png Binary files differindex 00b35ced458b..21948f770a68 100644 --- a/docs/html/auto/images/ui/gearhead_overview.png +++ b/docs/html/auto/images/ui/gearhead_overview.png diff --git a/docs/html/auto/index.jd b/docs/html/auto/index.jd index 2f0ffd52badd..cc5ed2ed56be 100644 --- a/docs/html/auto/index.jd +++ b/docs/html/auto/index.jd @@ -619,25 +619,6 @@ page.image=/images/cards/android-auto_2x.png </div> </div> </div> - <div class="content-footer wrap" itemscope="" itemtype="http://schema.org/SiteNavigationElement" - style="border-top: none;"> - - <div class="layout-content-col col-16" style="padding-top:4px"> - <style>#___plusone_0 {float:right !important;}</style> - <div class="g-plusone" data-size="medium"></div> - </div> - </div> - - <div id="footer" class="wrap" style="width:940px;position:relative;top:-35px;z-index:-1"> - <div id="copyright"> - Except as noted, this content is - licensed under <a href="http://creativecommons.org/licenses/by/2.5/"> - Creative Commons Attribution 2.5</a>. For details and - restrictions, see the <a href="{@docRoot}license.html">Content - License</a>. - </div> - </div> -</div> <!-- end .landing-hero-container --> <script> $("a.landing-down-arrow").on("click", function(e) { diff --git a/docs/html/design/design_toc.cs b/docs/html/design/design_toc.cs index 2dda87e82aa6..a837a04ffb8b 100644 --- a/docs/html/design/design_toc.cs +++ b/docs/html/design/design_toc.cs @@ -18,15 +18,10 @@ <li class="nav-section"> <div class="nav-section-header empty"><a href="<?cs var:toroot ?>design/material/index.html" - es-lang="Material Design" ja-lang="マテリアル デザイン" ko-lang="머티어리얼 디자인" - pt-br-lang="Material Design" - ru-lang="Material Design" zh-cn-lang="材料设计" zh-tw-lang="材料設計" - in-lang="Desain Bahan" - vi-lang="Material Design" > Material for Android</a></div> </li> @@ -62,10 +57,9 @@ </li> <li class="nav-section"> - <div class="nav-section-header"><a href="<?cs var:toroot ?>design/style/index.html">Pure Android</a></div> + <div class="nav-section-header"><a href="<?cs var:toroot ?>design/patterns/index.html">Pure Android</a></div> <ul> <li><a href="<?cs var:toroot ?>design/style/devices-displays.html">Devices and Displays</a></li> - <li><a href="<?cs var:toroot ?>design/patterns/app-structure.html">App Structure</a></li> <li><a href="<?cs var:toroot ?>design/patterns/navigation.html" es-lang="Navegación con los botones Back y Up" ja-lang="Back と Up を使用したナビゲーション" @@ -88,7 +82,6 @@ <li><a href="<?cs var:toroot ?>design/patterns/widgets.html">Widgets</a></li> <li><a href="<?cs var:toroot ?>design/patterns/swipe-views.html">Swipe Views</a></li> <li><a href="<?cs var:toroot ?>design/patterns/fullscreen.html">Full Screen</a></li> - <li><a href="<?cs var:toroot ?>design/patterns/confirming-acknowledging.html" es-lang="Confirmación y reconocimiento" ja-lang="確認と通知" @@ -98,7 +91,6 @@ zh-cn-lang="确认和确知" zh-tw-lang="確認及確認完成"> Confirming & Acknowledging</a></li> - <li><a href="<?cs var:toroot ?>design/patterns/pure-android.html">Pure Android</a></li> <li><a href="<?cs var:toroot ?>design/patterns/compatibility.html">Compatibility</a></li> <li><a href="<?cs var:toroot ?>design/patterns/accessibility.html">Accessibility</a></li> diff --git a/docs/html/design/devices.jd b/docs/html/design/devices.jd index 3d23d077d723..461683696e05 100644 --- a/docs/html/design/devices.jd +++ b/docs/html/design/devices.jd @@ -1,7 +1,5 @@ page.title=Android devices -page.viewport_width=970 section.landing=true -header.hide=1 footer.hide=1 page.image=images/cards/android-devices_2x.jpg @jd:body diff --git a/docs/html/design/downloads/index.jd b/docs/html/design/downloads/index.jd index 089a4af6db95..e37b305113c1 100644 --- a/docs/html/design/downloads/index.jd +++ b/docs/html/design/downloads/index.jd @@ -1,8 +1,11 @@ page.title=Downloads -page.tags=Icons,stencils,color swatches +page.tags="icons","stencils","colors,"swatches" +meta.tags="downloads, design, tools" +section.landing=true +footer.hide=true +nonavpage=true +forcelocalnav=true @jd:body - - <p>For icons, sticker sheets, and other downloadable resources, visit the <a href="http://www.google.com/design">Design site</a> or use the links below. </p> diff --git a/docs/html/design/get-started/creative-vision.jd b/docs/html/design/get-started/creative-vision.jd index 974d5d0386ad..26bc1b20522f 100644 --- a/docs/html/design/get-started/creative-vision.jd +++ b/docs/html/design/get-started/creative-vision.jd @@ -1,8 +1,11 @@ page.title=Creative Vision +section.landing=true +footer.hide=1 page.image=images/cards/design-creative-vision_2x.jpg + @jd:body -<img src="{@docRoot}design/media/creative_vision_main.png"> +<img src="{@docRoot}design/media/creative_vision_main.png" style="width:100%;margin-top:"> <div class="vspace size-1"> </div> @@ -15,7 +18,7 @@ page.image=images/cards/design-creative-vision_2x.jpg <div class="vspace size-1"> </div> <div class="cols"> - <div class="col-4"> + <div class="col-1of3"> <h4>Enchant me</h4> <p>Beauty is more than skin deep. Android apps are sleek and aesthetically pleasing on multiple levels. @@ -24,7 +27,7 @@ of art in their own right. Just like a well-made tool, your app should strive to simplicity and purpose to create a magical experience that is effortless and powerful.</p> </div> - <div class="col-5"> + <div class="col-1of3"> <h4>Simplify my life</h4> <p>Android apps make life easier and are easy to understand. When people use your app for the first @@ -35,7 +38,7 @@ of all ages and cultures feel firmly in control, and are never overwhelmed by to irrelevant flash.</p> </div> - <div class="col-4"> + <div class="col-1of3"> <h4>Make me amazing</h4> <p>It's not enough to make an app that is easy to use. Android apps empower people to try new things diff --git a/docs/html/design/get-started/principles.jd b/docs/html/design/get-started/principles.jd index 172a4e440412..9e8a371a5d1b 100644 --- a/docs/html/design/get-started/principles.jd +++ b/docs/html/design/get-started/principles.jd @@ -15,7 +15,7 @@ creativity and design thinking. Deviate with purpose. <h2 id="enchant-me">Enchant Me</h2> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="delight-me">Delight me in surprising ways</h4> <p>A beautiful surface, a carefully-placed animation, or a well-timed sound effect is a joy to @@ -23,7 +23,7 @@ experience. Subtle effects contribute to a feeling of effortlessness and a sense force is at hand.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_delight.png"> @@ -33,14 +33,14 @@ force is at hand.</p> <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="real-objects-more-fun">Real objects are more fun than buttons and menus</h4> <p>Allow people to directly touch and manipulate objects in your app. It reduces the cognitive effort needed to perform a task while making it more emotionally satisfying.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_real_objects.png"> @@ -50,7 +50,7 @@ needed to perform a task while making it more emotionally satisfying.</p> <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="make-it-mine">Let me make it mine</h4> <p>People love to add personal touches because it helps them feel at home and in control. Provide @@ -58,7 +58,7 @@ sensible, beautiful defaults, but also consider fun, optional customizations tha primary tasks.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_make_it_mine.png"> @@ -68,14 +68,14 @@ primary tasks.</p> <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="get-to-know-me">Get to know me</h4> <p>Learn peoples' preferences over time. Rather than asking them to make the same choices over and over, place previous choices within easy reach.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_get_to_know_me.png"> @@ -85,13 +85,13 @@ over, place previous choices within easy reach.</p> <h2 id="simplify-my-life">Simplify My Life</h2> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="keep-it-brief">Keep it brief</h4> <p>Use short phrases with simple words. People are likely to skip sentences if they're long.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_keep_it_brief.png"> @@ -101,14 +101,14 @@ over, place previous choices within easy reach.</p> <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="pictures-faster-than-words">Pictures are faster than words</h4> <p>Consider using pictures to explain ideas. They get people's attention and can be much more efficient than words.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_pictures.png"> @@ -118,14 +118,14 @@ than words.</p> <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="decide-for-me">Decide for me but let me have the final say</h4> <p>Take your best guess and act rather than asking first. Too many choices and decisions make people unhappy. Just in case you get it wrong, allow for 'undo'.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_decide_for_me.png"> @@ -135,14 +135,14 @@ unhappy. Just in case you get it wrong, allow for 'undo'.</p> <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="only-show-when-i-need-it">Only show what I need when I need it</h4> <p>People get overwhelmed when they see too much at once. Break tasks and information into small, digestible chunks. Hide options that aren't essential at the moment, and teach people as they go.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_information_when_need_it.png"> @@ -152,14 +152,14 @@ digestible chunks. Hide options that aren't essential at the moment, and teach p <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="always-know-where-i-am">I should always know where I am</h4> <p>Give people confidence that they know their way around. Make places in your app look distinct and use transitions to show relationships among screens. Provide feedback on tasks in progress.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_navigation.png"> @@ -169,7 +169,7 @@ use transitions to show relationships among screens. Provide feedback on tasks i <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="never-lose-my-stuff">Never lose my stuff</h4> <p>Save what people took time to create and let them access it from anywhere. Remember settings, @@ -177,7 +177,7 @@ personal touches, and creations across phones, tablets, and computers. It makes easiest thing in the world.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_never_lose_stuff.png"> @@ -187,14 +187,14 @@ easiest thing in the world.</p> <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="looks-same-should-act-same">If it looks the same, it should act the same</h4> <p>Help people discern functional differences by making them visually distinct rather than subtle. Avoid modes, which are places that look similar but act differently on the same input.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_looks_same.png"> @@ -204,14 +204,14 @@ Avoid modes, which are places that look similar but act differently on the same <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="interrupt-only-if-important">Only interrupt me if it's important</h4> <p>Like a good personal assistant, shield people from unimportant minutiae. People want to stay focused, and unless it's critical and time-sensitive, an interruption can be taxing and frustrating.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_important_interruption.png"> @@ -221,7 +221,7 @@ focused, and unless it's critical and time-sensitive, an interruption can be tax <h2 id="make-me-amazing">Make Me Amazing</h2> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="give-me-tricks">Give me tricks that work everywhere</h4> <p>People feel great when they figure things out for themselves. Make your app easier to learn by @@ -229,7 +229,7 @@ leveraging visual patterns and muscle memory from other Android apps. For exampl may be a good navigational shortcut.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_tricks.png"> @@ -239,7 +239,7 @@ may be a good navigational shortcut.</p> <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="its-not-my-fault">It's not my fault</h4> <p>Be gentle in how you prompt people to make corrections. They want to feel smart when they use your @@ -247,7 +247,7 @@ app. If something goes wrong, give clear recovery instructions but spare them th If you can fix it behind the scenes, even better.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_error.png"> @@ -257,14 +257,14 @@ If you can fix it behind the scenes, even better.</p> <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="sprinkle-encouragement">Sprinkle encouragement</h4> <p>Break complex tasks into smaller steps that can be easily accomplished. Give feedback on actions, even if it's just a subtle glow.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_sprinkle_encouragement.png"> @@ -274,7 +274,7 @@ even if it's just a subtle glow.</p> <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="do-heavy-lifting-for-me">Do the heavy lifting for me</h4> <p>Make novices feel like experts by enabling them to do things they never thought they could. For @@ -282,7 +282,7 @@ example, shortcuts that combine multiple photo effects can make amateur photogra only a few steps.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_heavy_lifting.png"> @@ -292,14 +292,14 @@ only a few steps.</p> <div class="vspace size-2"> </div> <div class="cols"> - <div class="col-7"> + <div class="col-7of12"> <h4 id="make-important-things-fast">Make important things fast</h4> <p>Not all actions are equal. Decide what's most important in your app and make it easy to find and fast to use, like the shutter button in a camera, or the pause button in a music player.</p> </div> - <div class="col-6"> + <div class="col-5of12"> <img src="{@docRoot}design/media/principles_make_important_fast.png"> diff --git a/docs/html/design/index.jd b/docs/html/design/index.jd index 799a64f643b0..5ea1244040c9 100644 --- a/docs/html/design/index.jd +++ b/docs/html/design/index.jd @@ -1,8 +1,8 @@ fullpage=true page.title=Design -page.viewport_width=970 section.landing=true meta.tags="beautifulapps, design, ux, patterns, holo, appquality, landing" +page.metaDescription=Create beautiful experiences in your apps. header.hide=1 footer.hide=1 @jd:body @@ -46,7 +46,7 @@ footer.hide=1 <i class="dac-sprite dac-arrow-down-gray"></i> </a> </div> -<section class="dac-section dac-gray dac-small dac-invert" id="latest"><div class="wrap"> +<section class="dac-section dac-gray dac-small" id="latest"><div class="wrap"> <h2 class="norule">Latest</h2> <div class="resource-widget resource-flow-layout col-16" data-query="collection:design/landing/latest" diff --git a/docs/html/design/material/index.jd b/docs/html/design/material/index.jd index c5893a704c6f..701c951107e0 100644 --- a/docs/html/design/material/index.jd +++ b/docs/html/design/material/index.jd @@ -1,8 +1,8 @@ page.title=Material Design for Android page.tags=Material,design -page.type=design page.image=images/cards/design-material-for-android_2x.jpg - +footer.hide=true +forcelocalnav=true @jd:body <!-- developer docs box --> diff --git a/docs/html/design/patterns/index.jd b/docs/html/design/patterns/index.jd new file mode 100644 index 000000000000..01e5c0d1b1ca --- /dev/null +++ b/docs/html/design/patterns/index.jd @@ -0,0 +1,29 @@ +page.title=Pure Android +footer.hide=1 +@jd:body + +<style> +#landing-graphic-container { + position: relative; +} + +#text-overlay { + position: absolute; + left: 0; + top: 402px; + width: 220px; +} +</style> + +<div id="landing-graphic-container"> + <div id="text-overlay"> + <span itemprop="description">Build visually compelling apps that look great on any + device.</span> + <br><br> + <a href="{@docRoot}design/style/devices-displays.html" class="landing-page-link">Devices and Displays</a> + </div> + + <a href="{@docRoot}design/style/devices-displays.html"> + <img src="{@docRoot}design/media/design_elements_landing.png"> + </a> +</div> diff --git a/docs/html/design/patterns/notifications.jd b/docs/html/design/patterns/notifications.jd index fdd435c0fde9..844c3b6b95f3 100644 --- a/docs/html/design/patterns/notifications.jd +++ b/docs/html/design/patterns/notifications.jd @@ -1,22 +1,22 @@ page.title=Notifications -page.tags="notifications","design","L" +page.tags="notifications","design" @jd:body - <a class="notice-developers" href="{@docRoot}training/notify-user/index.html"> + <a class="notice-developers right" href="{@docRoot}training/notify-user/index.html"> <div> <h3>Developer Docs</h3> <p>Notifying the User</p> </div> </a> -<a class="notice-designers" href="notifications_k.html"> +<a class="notice-designers right" href="notifications_k.html"> <div> <h3>Notifications in Android 4.4 and Lower</h3> </div> </a> <!-- video box --> -<a class="notice-developers-video" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY"> +<a class="notice-developers-video right" href="https://www.youtube.com/watch?v=Uiq2kZ2JHVY"> <div> <h3>Video</h3> <p>DevBytes: Notifications in the Android L Developer Preview</p> diff --git a/docs/html/design/patterns/notifications_k.jd b/docs/html/design/patterns/notifications_k.jd index 01a12a72e949..39ee26989007 100644 --- a/docs/html/design/patterns/notifications_k.jd +++ b/docs/html/design/patterns/notifications_k.jd @@ -1,14 +1,15 @@ -page.title=Notifications in Android 4.4 and Lower +page.title=Notifications, Android 4.4 and Lower +footer.hide=1 @jd:body -<a class="notice-developers" href="{@docRoot}training/notify-user/index.html"> +<a class="notice-developers right" href="{@docRoot}training/notify-user/index.html"> <div> <h3>Developer Docs</h3> <p>Notifying the User</p> </div> </a> -<a class="notice-designers" href="notifications.html"> +<a class="notice-designers right" href="notifications.html"> <div> <h3>Notifications in Android 5.0</h3> </div> diff --git a/docs/html/design/patterns/swipe-views.jd b/docs/html/design/patterns/swipe-views.jd index 9ee33db3cbc2..789538d3e581 100644 --- a/docs/html/design/patterns/swipe-views.jd +++ b/docs/html/design/patterns/swipe-views.jd @@ -2,7 +2,7 @@ page.title=Swipe Views page.tags=viewpager,navigation,tabs @jd:body -<a class="notice-developers" href="{@docRoot}training/implementing-navigation/lateral.html"> +<a class="notice-developers right" href="{@docRoot}training/implementing-navigation/lateral.html"> <div> <h3>Developer Docs</h3> <p>Creating Swipe Views with Tabs</p> @@ -20,7 +20,7 @@ browsing and consuming data a more fluent experience.</p> related data items, such as images, chats, or emails, and then pick one of the items to see the detail contents in a separate screen.</p> -<img src="{@docRoot}design/media/swipe_views.png"> +<img itemprop="image" src="{@docRoot}design/media/swipe_views.png"> <div class="figure-caption"> Master (left) and detail (right) views. </div> diff --git a/docs/html/design/patterns/widgets.jd b/docs/html/design/patterns/widgets.jd index d84d289a858e..8d94a52e1ff3 100644 --- a/docs/html/design/patterns/widgets.jd +++ b/docs/html/design/patterns/widgets.jd @@ -3,13 +3,6 @@ page.tags="appwidget","home" page.metaDescription=Design guide to creating widgets that are easy to use and look great. @jd:body -<a class="notice-developers" href="{@docRoot}guide/topics/appwidgets/index.html"> - <div> - <h3>Developer Docs</h3> - <p>App Widgets</p> - </div> -</a> - <p itemprop="description">Widgets are an essential aspect of home screen customization. You can imagine them as "at-a-glance" views of an app's most important data and functionality that is accessible right from the user's home screen. Users can move widgets across their home screen panels, and, if supported, resize them to tailor the amount of information within a widget to their preference.</p> <h2>Widget types</h2> diff --git a/docs/html/design/style/devices-displays.jd b/docs/html/design/style/devices-displays.jd index caa77da403d4..9edfaddeb9b9 100644 --- a/docs/html/design/style/devices-displays.jd +++ b/docs/html/design/style/devices-displays.jd @@ -3,15 +3,7 @@ page.metaDescription=Take advantage of Android's flexible layout system and crea @jd:body -<a class="notice-designers-material" - href="http://www.google.com/design/spec/layout/principles.html"> - <div> - <h3>Material Design</h3> - <p>Layout Principles<p> - </div> -</a> - -<p>Android powers hundreds of millions of phones, tablets, and other devices in a wide variety of screen sizes and +<p>Android powers more than a billion phones, tablets, and other devices in a wide variety of screen sizes and form factors. By taking advantage of Android's flexible layout system, you can create apps that gracefully scale from large tablets to smaller phones.</p> diff --git a/docs/html/develop/index.jd b/docs/html/develop/index.jd index 4591e769a452..3b2931882878 100644 --- a/docs/html/develop/index.jd +++ b/docs/html/develop/index.jd @@ -13,15 +13,14 @@ excludeFromSuggestions=true <div class="wrap"> <div class="cols dac-hero-content"> <div class="col-1of2 col-push-1of2 dac-hero-figure"> - + <!-- <iframe width="448" height="252" src="//www.youtube.com/embed/Z98hXV9GmzY?autohide=1&showinfo=0" frameborder="0" allowfullscreen="" style="float: right;"></iframe> - <!-- + --> <img class="dac-hero-image" src="{@docRoot}images/develop/hero_image_studio5_2x.png" srcset="/images/develop/hero_image_studio5.png 1x, /images/develop/hero_image_studio5_2x.png 2x" /> - --> </div> <div class="col-1of2 col-pull-1of2"> <h1 class="dac-hero-title">Get Started with Android Studio</h1> @@ -60,15 +59,16 @@ excludeFromSuggestions=true </a> </div> -<section class="dac-section dac-gray dac-small dac-invert" id="latest"><div class="wrap"> +<section class="dac-section dac-gray dac-small" id="latest"><div class="wrap"> <h2 class="norule">Latest</h2> <div class="resource-widget resource-flow-layout col-16" - data-query="type:youtube+tag:develop+tag:featured, type:blog+tag:develop+tag:featured" - data-query="collection:develop/landing/latest" - data-sortOrder="-timestamp" - data-cardSizes="6x6" - data-maxResults="12" - data-initial-results="3"></div> + data-query="type:youtube+tag:develop+tag:featured, type:blog+tag:develop+tag:featured" + data-query="collection:develop/landing/latest" + data-sortOrder="-timestamp" + data-cardSizes="6x6" + data-items-per-page="6" + data-maxResults="15" + data-initial-results="3"></div> </div></section> <section class="dac-section dac-light"><div class="wrap"> @@ -81,6 +81,7 @@ excludeFromSuggestions=true data-cardSizes="6x6" data-maxResults="15" data-initial-results="3" + data-items-per-page="6" data-sortOrder="random"></div> </div></section> @@ -152,5 +153,6 @@ excludeFromSuggestions=true data-sortOrder="random" data-cardSizes="6x6" data-initial-results="6" + data-items-per-page="24" data-maxResults="24"></div> </div></section> diff --git a/docs/html/distribute/analyze/start.jd b/docs/html/distribute/analyze/start.jd index c3a1f872f1d0..0221f72ef65f 100644 --- a/docs/html/distribute/analyze/start.jd +++ b/docs/html/distribute/analyze/start.jd @@ -1,5 +1,5 @@ page.title=Get Started with Analytics -page.metaDescription=Unlock the power of Analytics by choosing the implementation that works best for your app. +page.metaDescription=Get advanced insight into how players discover and play your games. page.tags="analytics, user behavior" page.image=images/cards/card-analytics_2x.png diff --git a/docs/html/distribute/engage/game-services.jd b/docs/html/distribute/engage/game-services.jd index 9ca27b7098fa..4a2203518c13 100644 --- a/docs/html/distribute/engage/game-services.jd +++ b/docs/html/distribute/engage/game-services.jd @@ -186,7 +186,7 @@ page.image=/images/cards/distribute/engage/card-game-services.png </div> <div class="resource-widget resource-flow-layout col-13" - data-query="collection:distribute/engage/gamesservices/related" + data-query="collection:distribute/engage/googleplaygames" data-sortOrder="-timestamp" data-cardSizes="9x3" data-maxResults="6"></div> diff --git a/docs/html/distribute/essentials/index.jd b/docs/html/distribute/essentials/index.jd index 6185e5494422..636c11d4673c 100644 --- a/docs/html/distribute/essentials/index.jd +++ b/docs/html/distribute/essentials/index.jd @@ -1,5 +1,5 @@ page.title=Essentials for a Successful App -meta.tags="landing, quality" +meta.tags="guidelines, quality" page.tags="guidelines", "tablet", "quality" section.landing=true nonavpage=true @@ -12,21 +12,23 @@ nonavpage=true process of monitoring feedback and making improvement after launch. </p> -<h2 id="guidelines">Quality Guidelines</h2> +<section class="dac-section dac-small" id="latest-games"><div class="wrap"> +<h2 id="guidelines" class="norule">Quality Guidelines</h2> <div class="resource-widget resource-flow-layout landing col-16" data-query="collection:distribute/essentials/guidelines" data-cardSizes="6x6" data-maxResults="9"> -</div> +</div></div></section> -<h2 id="tools">Tools & Resources</h2> +<section class="dac-section dac-small" id="latest-games"><div class="wrap"> +<h2 id="tools" class="norule">Tools & Resources</h2> <div class="resource-widget resource-flow-layout landing col-16" data-query="collection:distribute/essentials/tools" data-cardSizes="6x6" data-maxResults="9"> -</div> +</div></div></section> <!-- <h2>Related resources</h2> diff --git a/docs/html/distribute/essentials/quality/core.jd b/docs/html/distribute/essentials/quality/core.jd index f0e494b00ad0..860d8809ea68 100644 --- a/docs/html/distribute/essentials/quality/core.jd +++ b/docs/html/distribute/essentials/quality/core.jd @@ -746,11 +746,6 @@ data-cardsizes="6x3" data-maxresults="6"> "http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=188189"> Content Rating Guidelines</a>. </p> - - <p style="margin-bottom:.25em;"> - Especially, note that apps that request permission to use the device - location cannot be given the maturity level "Everyone". - </p> </td> <td> <a href="#gp">GP-1</a> diff --git a/docs/html/distribute/googleplay/cardboard.jd b/docs/html/distribute/googleplay/cardboard.jd index d5965d1eda75..8d21c2f280bc 100644 --- a/docs/html/distribute/googleplay/cardboard.jd +++ b/docs/html/distribute/googleplay/cardboard.jd @@ -1,6 +1,7 @@ page.title=Build VR with Google Cardboard page.metaDescription=Build apps and games with VR, for a viewer anyone can buy. -page.tags=vr, carboard, games +page.tags=vr, cardboard, games +page.image=images/cards/card-cardboard_2x.png @jd:body <p> diff --git a/docs/html/distribute/googleplay/index.jd b/docs/html/distribute/googleplay/index.jd index 3b5966f915d3..c69ce23f65bd 100644 --- a/docs/html/distribute/googleplay/index.jd +++ b/docs/html/distribute/googleplay/index.jd @@ -11,22 +11,24 @@ nonavpage=true help you gain traction in the marketplace.</span> </p> - <h2>Overview</h2> + <section class="dac-section dac-small" id="latest-games"><div class="wrap"> + <h2 class="norule">Overview</h2> <div class="resource-widget resource-flow-layout landing col-16" data-query="collection:distribute/gp/gplanding" data-sortOrder="-timestamp" data-cardSizes="6x6" data-maxResults="3"> - </div> + </div></div></section> - <h2 id="opportunities">Opportunities & Programs</h2> + <section class="dac-section dac-small" id="latest-games"><div class="wrap"> + <h2 id="opportunities" class="norule">Opportunities & Programs</h2> <div class="resource-widget resource-flow-layout landing col-16" data-query="collection:distribute/gp/gpfelanding" data-cardSizes="6x6" data-maxResults="10"> - </div> + </div></div></section> <!-- <h2>Related resources</h2> diff --git a/docs/html/distribute/index.jd b/docs/html/distribute/index.jd index a6ece63324a1..638477302d0a 100644 --- a/docs/html/distribute/index.jd +++ b/docs/html/distribute/index.jd @@ -1,5 +1,6 @@ fullpage=true page.title=Distribute Your Apps +page.image=images/distribute/google-play-bg.jpg page.viewport_width=970 section.landing=true header.hide=1 @@ -7,6 +8,17 @@ nonavpage=true page.metaDescription=The most visited store in the world for Android apps. Cloud-connected and always synced, it's never been easier for users to find and download your apps. @jd:body + +<script> + $(document).ready(function() { + if (useUpdatedTemplates) { + $("#useUpdatedTemplates").css("display","block"); + } else { + $("#useOldTemplates").css("display","block"); + } + }) +</script> + <div class="dac-hero-carousel" data-carousel-query="collection:distribute/landing/carousel"> </div> @@ -16,16 +28,64 @@ page.metaDescription=The most visited store in the world for Android apps. Cloud </a> </div> -<section class="dac-section dac-gray dac-small dac-invert" id="latest"><div class="wrap"> +<section id="useOldTemplates" style="display:none" class="dac-section dac-gray dac-small" id="latest"><div class="wrap"> <h2 class="norule">Latest</h2> <div class="resource-widget resource-flow-layout col-16" data-query="type:youtube+tag:googleplay+tag:developerstory+tag:featured, type:blog+tag:googleplay+tag:distribute+tag:featured" data-sortOrder="-timestamp" data-cardSizes="6x6" - data-maxResults="12" + data-maxResults="3" + data-items-per-page="6" data-initial-results="3"></div> </div></section> +<section id="useUpdatedTemplates" style="display:none" class="dac-section dac-gray dac-small" id="latest"><div class="wrap"> + <h2 class="norule">Latest</h2> + + <div class="dac-filter dac-filter-section" data-filter="#latest-resources"> + <div data-tabs> + <span class="dac-filter-title">Showing:</span> + <ol class="dac-tab-bar"> + <li class="dac-tab-item" data-tab-item="goal"> + <p class="dac-tab-title">Goals <i class="dac-tab-arrow dac-sprite dac-expand-more-black"></i></p> + <span data-filter-count="goal" class="dac-filter-count dac-disabled">0</span> + </li> + <li class="dac-tab-item" data-tab-item="type"> + <p class="dac-tab-title">Types <i class="dac-filter-item-arrow dac-sprite dac-expand-more-black"></i></p> + <span data-filter-count="type" class="dac-filter-count dac-disabled">0</span> + </li> + </ol> + + <ol class="dac-tab-views" data-tab-views> + <li class="dac-tab-view" data-tab-view="goal"> + <div class="dac-filter-item" data-filter-value="category:googleplay" data-filter-name="Get Started"></div> + <div class="dac-filter-item" data-filter-value="category:users" data-filter-name="Get Users"></div> + <div class="dac-filter-item" data-filter-value="category:engage" data-filter-name="Engage"></div> + <div class="dac-filter-item" data-filter-value="category:monetize" data-filter-name="Earn"></div> + <div class="dac-filter-item" data-filter-value="category:analyze" data-filter-name="Analyze"></div> + <div class="dac-filter-item" data-filter-value="category:stories" data-filter-name="Stories"></div> + + </li> + <li class="dac-tab-view" data-tab-view="type"> + <div class="dac-filter-item" data-filter-value="type:distribute" data-filter-name="Articles"></div> + <div class="dac-filter-item" data-filter-value="type:youtube" data-filter-name="Videos"></div> + <div class="dac-filter-item" data-filter-value="type:blog" data-filter-name="Blog posts"></div> + </li> + </ol> + </div> + + <ul class="dac-filter-chips" data-filter-chips></ul> + </div> + + <div class="resource-flow-layout col-16" id="latest-resources" + data-query="type:distribute, type:youtube+tag:googleplay, type:blog+tag:googleplay+tag:featured" + data-sortOrder="-timestamp" + data-cardSizes="6x6" + data-items-per-page="6" + data-initial-results="6"></div> +</div></section> + + <section class="dac-section dac-invert dac-darken-bg" style="background-image: url(/images/distribute/google-play-bg.jpg)"><div class="wrap"> <div class="cols"><div class="col-10of12 col-push-1of12"> <h1 class="dac-section-title">Reach the world with Google Play</h1> diff --git a/docs/html/distribute/stories/games.jd b/docs/html/distribute/stories/games.jd index 2351eed79739..22ab1dc5f16d 100644 --- a/docs/html/distribute/stories/games.jd +++ b/docs/html/distribute/stories/games.jd @@ -1,5 +1,6 @@ page.title=Developer Stories: Google Play Game Services -meta.tags="google play, story, stories, games, global" +meta.tags="google play, games, global, developer story" +page.timestamp=1381449601 page.image=/images/distribute/glu-ew-gpgames.jpg page.metaDescription=How game studios are using Google Play game services to deliver new gaming experiences for their users. diff --git a/docs/html/distribute/stories/index.jd b/docs/html/distribute/stories/index.jd index ca7647da9bf6..eb94e314dadc 100644 --- a/docs/html/distribute/stories/index.jd +++ b/docs/html/distribute/stories/index.jd @@ -1,13 +1,41 @@ page.title=Developer Stories section.landing=true +nonavpage=true +excludeFromSuggestions=true page.metaDescription=Android developers, their apps, and their successes with Android and Google Play. @jd:body +<script> + $(document).ready(function() { + if (useUpdatedTemplates) { + $("#useUpdatedTemplates").css("display","block"); + } else { + $("#useOldTemplates").css("display","block"); + } + }) +</script> + <p>Android developers, their apps, and their successes with Android and Google Play.</p> -<div class="resource-widget resource-flow-layout col-13" - data-query="type:youtube+tag:developerstory" - data-sortOrder="-timestamp" - data-cardSizes="18x12" - data-maxResults="32"></div> +<section class="dac-section dac-small" id="latest-apps"><div class="wrap"> + <h2 class="norule">Latest from apps</h2> + + <div class="resource-widget resource-flow-layout col-16" + data-query="type:distribute+tag:developerstory+tag:apps, type:youtube+tag:developerstory+tag:apps" + data-sortOrder="-timestamp" + data-cardSizes="6x6" + data-items-per-page="15" + data-initial-results="6"></div> +</div></section> + +<section class="dac-section dac-small" id="latest-games"><div class="wrap"> + <h2 class="norule">Latest from games</h2> + + <div class="resource-widget resource-flow-layout col-16" + data-query="type:distribute+tag:developerstory+tag:games,type:youtube+tag:developerstory+tag:games" + data-sortOrder="-timestamp" + data-cardSizes="6x6" + data-items-per-page="15" + data-initial-results="6"></div> +</div></section> diff --git a/docs/html/distribute/stories/localization.jd b/docs/html/distribute/stories/localization.jd index d6e6ccff581a..a6a17eb5fe1f 100644 --- a/docs/html/distribute/stories/localization.jd +++ b/docs/html/distribute/stories/localization.jd @@ -1,6 +1,7 @@ page.title=Developer Stories: Localization in Google Play -meta.tags="google play, developer story, localization, global" +meta.tags="google play, developer story, localization, global, games" page.tags="stories", "video", "case study" +page.timestamp=1381449600 page.image=/images/distribute/zombie-ragdoll-n5-land.jpg page.metaDescription=Hear from Android developers who have successfully used the Google Play App Translation Service. diff --git a/docs/html/distribute/stories/tablets.jd b/docs/html/distribute/stories/tablets.jd index 771fa5275fd3..085cd8f87688 100644 --- a/docs/html/distribute/stories/tablets.jd +++ b/docs/html/distribute/stories/tablets.jd @@ -1,7 +1,8 @@ page.title=Developer Stories: The Opportunity of Android Tablets -meta.tags="google play, developer story, journal, tablets, pure" -pdage.metaDescription=Developers are investing in a full tablet experience for their apps and seeing those investments pay off big. -page.image=/images/distribute/rememberthemilk.png +meta.tags="google play, developer story, journal, tablets, apps" +page.metaDescription=Developers are investing in a full tablet experience for their apps and seeing those investments pay off big. +page.image=images/distribute/rememberthemilk.png +page.timestamp=1381449600 @jd:body diff --git a/docs/html/distribute/tools/promote/brand.jd b/docs/html/distribute/tools/promote/brand.jd index cf83a5e7d727..409dfdda2756 100644 --- a/docs/html/distribute/tools/promote/brand.jd +++ b/docs/html/distribute/tools/promote/brand.jd @@ -14,6 +14,12 @@ Partner Marketing team. Use the <a href="https://support.google.com/googleplay/contact/brand_developer">Android and Google Play Brand Permissions Inquiry form</a> to submit your marketing for review.</p> +<p> + If you need Google Play badges or guidelines, please see the + <a href="https://play.google.com/intl/en_us/badges/">Google Play Badge</a> page. +</p> + + <h2 id="brand-android">Android</h2> <p>The following are guidelines for the Android brand @@ -101,103 +107,10 @@ used according to terms described in the Creative Commons 3.0 Attribution Licens <p>The custom typeface may not be used.</p> -<p>The following are guidelines for the Google Play brand.</p> - -<h4>Google Play™ Badges</h4> - - <div style="float:right;clear:right;width:172px;margin-left:30px"> - <img src="{@docRoot}images/brand/en_app_rgb_wo_60.png" alt=""> - <p style="text-align:center"> - <a href="{@docRoot}images/brand/en_app_rgb_wo_45.png">129x45</a> | - <a href="{@docRoot}images/brand/en_app_rgb_wo_60.png">172x60</a></p> - </div> - - <div style="float:right;clear:right;width:172px;margin-left:30px"> - <img src="{@docRoot}images/brand/en_generic_rgb_wo_60.png" alt=""> - <p style="text-align:center"> - <a href="{@docRoot}images/brand/en_generic_rgb_wo_45.png">129x45</a> | - <a href="{@docRoot}images/brand/en_generic_rgb_wo_60.png">172x60</a></p> - </div> - - <p>Use the "Get it on Google Play" and "Android App on Google Play" badges on your website and - promotional materials to point to your products on Google Play. These badges are both available - in over 40 languages. Additional Google Play badge formats and - badges for music, books, magazines, movies, and TV shows are also available. - Use the <a - href="https://support.google.com/googleplay/contact/brand_developer">Android - and Google Play Brand Permissions Inquiry form</a> to request - those badges.</p> - - <p>Google Play badge guidelines:</p> - <ul> - <li>Don't modify the color, proportions, spacing, or any other aspect of the badge.</li> - <li>When used alongside logos for other application marketplaces, the Google Play badge - should be of equal or greater size.</li> - <li>When used online, the badge should link to either:</li> - <ul> - <li>A list of products published by you, for example:<br /> - <span style="margin-left:1em;">http://play.google.com/store/search?q=<em>publisherName</em></span> - </li> - <li>A specific app product details page within Google Play, for example:<br /> - <span style="margin-left:1em;">http://play.google.com/store/apps/details?id=<em>packageName</em></span> - </li> - </ul> - <li>You do not need to include a legal attribution if you are only using a Google Play badge. - However, keep in mind that:</li> - <ul> - <li>If you make any mention of Google Play or Android outside of the badge a legal attribution - must be included. </li> - <li>If you are including another app store’s legal attribution then include this legal - attribution:</li> - <ul> - <li>Google Play is a trademark of Google Inc.</li> - </ul> - </li> - <li>Use of the Google Play badge does not need to be reviewed or approved by the Google Play - brand team unless the marketing campaign will have over 1 million impressions.</li> - </ul> - - <p>To quickly create a badge that links to your apps on Google Play, - use the <a - href="{@docRoot}distribute/tools/promote/badges.html">Google Play badge generator</a> - (badges available in over 40 languages).</p> - - <p>For details on all the ways that you can link to your product details page in Google Play, - see <a href="{@docRoot}distribute/tools/promote/linking.html">Linking to your products</a>.</p> - -<h2 id="Marketing_Review">Google Play in Text</h2> - -<p>Any use of Google Play in text must be reviewed and approved by the Google Play brand team. -Submit your marketing via the <a href="https://support.google.com/googleplay/contact/brand_developer"> -Android and Google Play Partner Brand Inquiry Form.</a></p> - -<p>Always include a ™ symbol on the first or most prominent instance of Google Play™ in text.</p> - -<p>When mentioning that a product is available on Google Play always say “on Google Play”</p> - -<ul> -<li><span style="color:red">Incorrect</span>: Our app is now available from Google Play.</li> -<li><span style="color:green">Correct</span>: Our app is now available on Google Play.</li> -</ul> -<br> -<p>Only refer to Google Play as the Google Play™ store app in instructional text meant to inform a -customer about how to find or download your product on Google Play.</p> - -<ul> -<li><span style="color:red">Incorrect</span>: Download our games using the Google Play™ store app.</li> -<li><span style="color:green">Correct</span>: This is how you download our app using the Google -Play™ store app.</li> -</ul> -<br> - -<p>Any use of the Google Play name in your marketing or communications needs to be accompanied by -this legal attribution:</p> - -<p><em>Google Play is a trademark of Google Inc.</em></p> <h2 id="Marketing_Review">Marketing Reviews and Brand Inquiries</h2> <p>Use the <a href="https://support.google.com/googleplay/contact/brand_developer">Android and Google Play Brand Permissions Inquiry form</a> to submit any marketing -reviews or brand inquires. Typical response time is at least one week.</p>
\ No newline at end of file +reviews or brand inquires. Typical response time is at least one week.</p> diff --git a/docs/html/distribute/users/banners.jd b/docs/html/distribute/users/banners.jd index 8a7ccc0a2305..d889ac7f4efb 100644 --- a/docs/html/distribute/users/banners.jd +++ b/docs/html/distribute/users/banners.jd @@ -1,6 +1,6 @@ page.title=Add An App Install Banner On Your Mobile Website page.metaDescription=Add a native app install banner to your mobile website and allow visitors to install your app straight from your site. -page.image=images/cards/distribute/users/banners.png +page.image=images/cards/card-install-banners_16x9_2x.png page.tags="banner, chrome, web" Xnonavpage=true diff --git a/docs/html/google/backup/signup.jd b/docs/html/google/backup/signup.jd index f9ad6002b0d7..598003dbe23b 100644 --- a/docs/html/google/backup/signup.jd +++ b/docs/html/google/backup/signup.jd @@ -208,7 +208,7 @@ with the Android Backup Service Terms of Service</label> <input id="pname" type="text" name="pname" size="47" value="" onkeyup="onFormInput()" onfocus="boxFocusChanged(this,true)" onblur="boxFocusChanged(this,false)"/> </p> -<p><a href="" class="button disabled" id="registerButton" +<p><a href="" class="dac-button dac-raised dac-primary disabled ndk" id="registerButton" onclick="onRegister(); return false;" >Register with Android Backup Service</a></p> </div> diff --git a/docs/html/google/google_toc.cs b/docs/html/google/google_toc.cs index f3e1f3ccf58d..8151b10f6f3d 100644 --- a/docs/html/google/google_toc.cs +++ b/docs/html/google/google_toc.cs @@ -21,6 +21,9 @@ <li><a href="<?cs var:toroot?>google/play/billing/billing_subscriptions.html"> <span class="en">Subscriptions</span></a> </li> + <li><a href="<?cs var:toroot?>google/play/billing/billing_promotions.html"> + <span class="en">Promotions</span></a> + </li> <li><a href="<?cs var:toroot?>google/play/billing/billing_best_practices.html" zh-cn-lang="安全性和设计"> <span class="en">Security and Design</span></a> </li> diff --git a/docs/html/google/index.jd b/docs/html/google/index.jd index a2a6c5090723..b3ceee3daf13 100644 --- a/docs/html/google/index.jd +++ b/docs/html/google/index.jd @@ -39,12 +39,13 @@ footer.hide=1 </a> </div> -<section class="dac-section dac-gray dac-small dac-invert" id="latest"><div class="wrap"> +<section class="dac-section dac-gray dac-small" id="latest"><div class="wrap"> <h2 class="norule">Latest</h2> <div class="resource-widget resource-flow-layout col-16" data-query="type:blog+tag:googleservices+tag:featured" data-cardSizes="6x6" - data-maxResults="12" + data-maxResults="15" + data-items-per-page="6" data-initial-results="3"></div> </div> </section> @@ -68,7 +69,7 @@ footer.hide=1 </div> </section> -<section class="dac-section dac-gray dac-small dac-invert" id="videos"><div class="wrap"> +<section class="dac-section dac-gray dac-small" id="videos"><div class="wrap"> <h2 class="norule">Videos</h2> <div class="resource-widget resource-flow-layout col-16" data-query="collection:google/landing/videos" diff --git a/docs/html/google/play/billing/billing_integrate.jd b/docs/html/google/play/billing/billing_integrate.jd index 4249885177d5..c658f702dce3 100644..100755 --- a/docs/html/google/play/billing/billing_integrate.jd +++ b/docs/html/google/play/billing/billing_integrate.jd @@ -95,34 +95,38 @@ method calls.</p> <p>To add the AIDL to your project:</p> <ol> - <li>Copy the {@code IInAppBillingService.aidl} file to your Android project. + <li>First, download the Google Play Billing Library to your Android project: + <ol type="a"> + <li>Select <strong>Tools > Android > SDK Manager</strong>.</li> + <li>Under <strong>Appearance & Behavior > System Settings > Android SDK</strong>, + select the <em>SDK Tools</em> tab to select and download <em>Google Play Billing + Library</em>.</li></ol> + + <li>Next, copy the {@code IInAppBillingService.aidl} file to your project. <ul> - <li>If you are using Eclipse: + <li>If you are using Android Studio: <ol type="a"> - <li>If you are starting from an existing Android project, open the - project in Eclipse. If you are creating a new Android project from - scratch, click <strong>File</strong> > <strong>New</strong> > - <strong>Android Application Project</strong>, then follow the - instructions in the <strong>New Android Application</strong> wizard - to create a new project in your workspace. - </li> + <li>Navigate to {@code src/main} in the Project tool window.</li> - <li>In the {@code /src} directory, click <strong>File</strong> > - <strong>New</strong> > <strong>Package</strong>, then create a - package named {@code com.android.vending.billing}. - </li> + <li>Select <strong>File > New > Directory</strong> and enter {@code aidl} in the + <em>New Directory</em> window, then select <strong>OK</strong>. + + <li>Select <strong>File > New > Package</strong> and enter + {@code com.android.vending.billing} in the <em>New Package</em> window, then select + <strong>OK</strong>.</li> - <li>Copy the {@code IInAppBillingService.aidl} file from {@code - <sdk>/extras/google/play_billing/} and paste it into the {@code - src/com.android.vending.billing/} folder in your workspace. + <li>Using your operating system file explorer, navigate to + {@code <sdk>/extras/google/play_billing/}, copy the + {@code IInAppBillingService.aidl} file, and paste it into the + {@code com.android.vending.billing} package in your project. </li> </ol> </li> - <li>If you are developing in a non-Eclipse environment: Create the + <li>If you are developing in a non-Android Studio environment: Create the following directory {@code /src/com/android/vending/billing} and copy the {@code IInAppBillingService.aidl} file into this directory. Put the AIDL - file into your project and use the Ant tool to build your project so that + file into your project and use the Gradle tool to build your project so that the <code>IInAppBillingService.java</code> file gets generated. </li> </ul> diff --git a/docs/html/google/play/billing/billing_promotions.jd b/docs/html/google/play/billing/billing_promotions.jd new file mode 100644 index 000000000000..ccf50fc601c3 --- /dev/null +++ b/docs/html/google/play/billing/billing_promotions.jd @@ -0,0 +1,301 @@ +page.title=In-app Promotions +parent.title=In-app Billing +parent.link=index.html +page.metaDescription=Support promo codes in your app, which let you give content or features away to a limited number of users free of charge. +page.image=/images/play_dev.jpg +page.tags="promotions, billing, promo codes" +meta.tags="monetization, inappbilling, promotions" +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>Quickview</h2> + <h2>In this document</h2> + <ol> + <li><a href="#workflow">Creating and Redeeming Promo Codes</a></li> + <li><a href="#supporting">Supporting Promo Codes In Your App</a></li> + <li><a href="#testing">Testing In-app Promotions</a></li> + </ol> + <h2>See also</h2> + <ol> + <li><a href="{@docRoot}google/play/billing/billing_integrate.html">Implementing + In-app Billing</a></li> + <!-- TODO: link to blog post when available --> + </ol> +</div> +</div> + +<p> + Promo codes let you give content or features away to a limited number of + users free of charge. Once you create a promo code, you can distribute it + subject to the + <!--TODO: Link to TOS when/if they're available as a web page --> terms of + service. The user enters the promo code in your app or in the Play Store app, + and gets the item at no cost. You can use promo codes in many ways to + creatively engage with users. For example: +</p> + +<ul> + <li>A game could have a special item, such as a character or decoration, + that's only available to players who attend an event. The developer could + distribute cards with promo codes at the event, and users would enter their + promo code to unlock the item. + </li> + + <li>An app developer might distribute promo codes at local businesses, to + encourage potential users to try the app. + </li> + + <li>An app developer might give out "friends and family" codes to its employees to + share with their friends. + </li> +</ul> + +<p> + Every promo code is associated with a particular <em>product ID</em> (also + known as a <em>SKU</em>). You can create promo codes for your existing in-app + products. You can also keep a SKU off the Play Store, so the only way to get + that item is by entering that SKU's promo code. When a user enters the promo + code in the Play Store or in their app, the user gets the item, just as if + they paid full price for it. If your app already uses <a href= + "{@docRoot}google/play/billing/api.html">In-app Billing version 3</a> to + support in-app purchases, it's easy to add support for promo codes. +</p> + +<h2 id="workflow">Creating and Redeeming Promo Codes</h2> + +<p> + You create promo codes through the <a href= + "https://play.google.com/apps/publish/" class="external-link">Google Play + Developer Console</a>. Each promo code is associated with a single product item + registered in the developer console. +</p> + +<p> + When a user gets a promo code, they redeem it in one of two ways: +</p> + +<ul> + <li>The user can enter the promo code as part of the app's ordinary purchase flow, as + described in <a href="{@docRoot}google/play/billing/billing_integrate.html"> + Implementing In-app Billing</a>. As far as the app is concerned, this is + just like an ordinary purchase, except that the user makes payment with a + promo code instead of with money. + </li> + + <li>The user can redeem the code in the Google Play Store app. Once the user + enters the code, the Play Store prompts the user to open the app (if they have + the latest version installed) or to download or update it. (We do not + currently support redeeming promo codes from the Google Play web store.) + </li> +</ul> + +<p> + If the promo code is for a <a href= + "{@docRoot}google/play/billing/api.html#consumetypes">consumable product</a>, + the user can apply an additional code for the same product <em>after</em> the first + product is consumed. For example, a game might offer promo codes for a bundle + of extra lives. Betty has two different promo codes for that bundle. She + redeems a single promo code, then launches the game. When the game launches, + the her character receives the lives, consuming the item. She can now redeem + the second promo code for another bundle of lives. (She cannot redeem the + second promo code until after she consumes the item she purchased with the + first promo code.) +</p> + +<h2 id="supporting">Supporting Promo Codes In Your App</h2> + +<p> + To support promotion codes, your app should call the <a href= + "{@docRoot}google/play/billing/billing_reference.html#getPurchases" + ><code>getPurchases()</code></a> + method whenever the app starts or resumes. This method returns a bundle of all + current, unconsumed purchases, including purchases the user made by redeeming + a promo code. This simplest approach is to call <a href= + "{@docRoot}google/play/billing/billing_reference.html#getPurchases" + ><code>getPurchases()</code></a> + in your activity's {@link android.app.Activity#onResume onResume()} method, + since that callback fires when the activity is created, as well as when the + activity is unpaused. Calling <a href= + "{@docRoot}google/play/billing/billing_reference.html#getPurchases" + ><code>getPurchases()</code></a> + on startup and resume guarantees that your app will find out about all + purchases and redemptions the user may have made while the app wasn't + running. Furthermore, if a user makes a purchase while the app is running and + your app misses it for any reason, your app will still find out about the + purchase the next time the activity resumes and calls <a href= + "{@docRoot}google/play/billing/billing_reference.html#getPurchases" + ><code>getPurchases()</code></a>. +</p> + +<p> + In addition, your app should allow users to redeem promo codes inside the app + itself. If your app supports the in-app purchase workflow (described in + <a href= + "{@docRoot}google/play/billing/billing_integrate.html#billing-requests">Making + In-app Billing Requests</a>), your app automatically supports in-app + redemption of promo codes. When you launch the in-app purchase UI, + the user has the option to pay for the purchase with + a promo code. Your activity's {@link android.app.Activity#onActivityResult + onActivityResult()} method receives a response intent telling the app whether the + purchase was completed. However, your app should still call <a href= + "{@docRoot}google/play/billing/billing_reference.html#getPurchases" + ><code>getPurchases()</code></a> + on startup and resume, just in case the purchase and consumption workflow + didn't complete. For example, if the user successfully redeems a promo code, + and then your app crashes before the item is consumed, your app still gets + information about the purchase when the app calls <a href= + "{@docRoot}google/play/billing/billing_reference.html#getPurchases" + ><code>getPurchases()</code></a> on its next startup. +</p> + +<p> + Your app should also support the scenario where a user redeems a promo code + in the Play Store app while the app is running. Your app can find out right + away when the user redeems a code by registering a listener for the + <code>PURCHASES_UPDATED</code> intent. The Play Store fires this intent + whenever a user redeems a promo code. +</p> + +<p> + To listen for the <code>PURCHASES_UPDATED</code> intent, dynamically create a + {@link android.content.BroadcastReceiver} object and register it to listen + for <code>"com.android.vending.billing.PURCHASES_UPDATED"</code>. Register + the receiver by putting code like this in your activity's {@link + android.app.Activity#onResume onResume()} method: +</p> + +<pre>IntentFilter promoFilter = + new IntentFilter("com.android.vending.billing.PURCHASES_UPDATED"); +registerReceiver(myPromoReceiver, promoFilter);</pre> + +<p> + When the user makes a purchase, the system invokes your broadcast receiver's + {@link android.content.BroadcastReceiver#onReceive onReceive()} method. That + method should call <a href= + "{@docRoot}google/play/billing/billing_reference.html#getPurchases" + ><code>getPurchases()</code></a> + to see what purchases the user has made. +</p> + +<p> + Your activity's {@link android.app.Activity#onPause onPause()} method should + unregister the broadcast receiver, to reduce system overhead when your app + isn't running: +</p> + +<pre>unRegisterReceiver(myPromoReceiver);</pre> + +<p class="note"> + <strong>Note:</strong> You should not register this broadcast receiver in the + app manifest. Declaring the receiver in the manifest can cause the system to + launch the app to handle the intent if the user makes a purchase while the app + isn't running. This behavior is not necessary, and may be annoying to the + user. Instead, your app should call <a href= + "{@docRoot}google/play/billing/billing_reference.html#getPurchases" + ><code>getPurchases()</code></a> + when the user launches it, to find out about any purchases the user made + while the app wasn't running. +</p> + +<h2 id="testing">Testing In-app Promotions</h2> + +<p> + If your app supports in-app promotions, you should test the following use + cases. +</p> + +<h3 id="test-inapp">User redeems promo code in the app</h3> + +<p> + If the user redeems a promo code within the app's purchase flow, as described + in <a href= + "{@docRoot}google/play/billing/billing_integrate.html#billing-requests">Making + In-app Billing Requests</a>, the system invokes your activity's {@link + android.app.Activity#onActivityResult onActivityResult()} method to handle + the purchase. Verify that {@link android.app.Activity#onActivityResult + onActivityResult()} handles the purchase properly, whether the user uses cash + or a promo code. +</p> + +<h3 id="test-playstore">User redeems promo code in the Play Store</h3> + +<p> + If the user redeems a promo code in the Play Store, there are several + possible workflows. You should verify each one of these. +</p> + +<h4 id="test-app-uninstalled">App is not installed</h4> + +<p> + If the user redeems a promo code for an app that is not installed on the + device, the Play Store prompts the user to install the app. (If the app is + installed but not up-to-date, the Play Store prompts the user to update the + app.) You should test the following sequence on a device that does not + have your app installed. +</p> + +<ol> + <li>User redeems a promo code for the app in the Play Store. The Play Store + prompts the user to install your app. + </li> + + <li>User installs and launches your app. Verify that on startup, the app + calls <a href= + "{@docRoot}google/play/billing/billing_reference.html#getPurchases" + ><code>getPurchases()</code></a> + and correctly detects the purchase the user made with the promo code. + </li> +</ol> + +<h4 id="test-app-not-running">App is installed, but not running</h4> + +<p> + If the user redeems a promo code for an app that is installed on the device, + the Play Store prompts the user to switch to the app. You should test the + following sequence on a device that has your app installed but not running: +</p> + +<ol> + <li>User redeems a promo code for the app in the Play Store. The Play Store + prompts the user to switch to your app. + </li> + + <li>User launches your app. Verify that on startup, the app calls <a href= + "{@docRoot}google/play/billing/billing_reference.html#getPurchases" + ><code>getPurchases()</code></a> + and correctly detects the purchase the user made with the promo code. + </li> +</ol> + +<h4 id="test-app-running">App is installed and running +</h4> + +<p> + If the user redeems a promo code for an app that is currently running on the + device, the Play Store notifies the app via a <code>PURCHASES_UPDATED</code> + intent. You should test the following sequence: +</p> + +<ol> + <li>User launches the app. Verify that the app has properly registered itself to + receive the <code>PURCHASES_UPDATED</code> intent. + </li> + + <li>User launches the Play Store app and redeems a promo code for the app. The Play + Store fires a <code>PURCHASES_UPDATED</code> intent. Verify that your app's + {@link android.content.BroadcastReceiver#onReceive + BroadcastReceiver.onReceive()} callback fires to handle the intent. + </li> + + <li>Your {@link android.content.BroadcastReceiver#onReceive onReceive()} + method should respond to the intent by calling <a href= + "{@docRoot}google/play/billing/billing_reference.html#getPurchases" + ><code>getPurchases()</code></a>. Verify that it calls this method, and that + it correctly detects the purchase the user made with the promo code. + </li> + + <li>User switches back to your app. Verify that the user has the purchased + item. + </li> +</ol> diff --git a/docs/html/google/play/billing/billing_reference.jd b/docs/html/google/play/billing/billing_reference.jd index 6f2978cee1bd..45ec7854b59d 100644 --- a/docs/html/google/play/billing/billing_reference.jd +++ b/docs/html/google/play/billing/billing_reference.jd @@ -328,7 +328,11 @@ subscriptions.</p> </p> <h3 id="getPurchases">The getPurchases() method</h3> -<p>This method returns the current un-consumed products owned by the user. Table 5 lists the response data that is returned in the {@code Bundle}.</p> +<p>This method returns the current un-consumed products owned by the user, + including both purchased items and items acquired by redeeming a promo code. + Table 5 lists the response data that is returned in the + {@link android.os.Bundle}.</p> + <p class="table-caption" id="getpurchases-response-table"> <strong>Table 6.</strong> Response data from a {@code getPurchases} request.</p> <table> diff --git a/docs/html/google/play/billing/index.jd b/docs/html/google/play/billing/index.jd index b20262f5bd88..b2e9fe4369d4 100644 --- a/docs/html/google/play/billing/index.jd +++ b/docs/html/google/play/billing/index.jd @@ -14,6 +14,8 @@ and features, and more. You can use In-app Billing to sell products as</p> <div class="sidebox"> <h2><strong>New in In-App Billing</strong></h2> <ul> + <li><strong>In-app Promotions</strong>—Developers can create promo codes + which users can redeem for content or features.</li> <li><strong>Prorated Subscription Prices</strong>—Content providers can lower the price of seasonal subscriptions for users who sign up late in the season. For example, a sports-related service might lower the subscription diff --git a/docs/html/google/play/licensing/setting-up.jd b/docs/html/google/play/licensing/setting-up.jd index f43e4aba7320..ef9de43eff92 100644..100755 --- a/docs/html/google/play/licensing/setting-up.jd +++ b/docs/html/google/play/licensing/setting-up.jd @@ -6,7 +6,7 @@ parent.link=index.html <div id="qv-wrapper"> <div id="qv"> - + <h2>In this document</h2> <ol> <li><a href="#account">Setting Up a Publisher Account</a></li> @@ -179,21 +179,24 @@ Play services.</p> these steps: </p> <ol> - <li>Launch the Android SDK Manager (available under the Eclipse <strong>Window</strong> -menu or by executing {@code <sdk>/tools/android sdk}).</li> + <li>Launch the Android SDK Manager, available under the Android Studio Tools menu +(<strong>Tools > Android > SDK Manager</strong>) or by executing +{@code <sdk>/tools/android sdk}.</li> <li>Select and download <strong>Google APIs</strong> for the Android version you'd like to target (must be Android 2.2 or higher).</li> - <li>When the download is complete, open the AVD Manager (available under the Eclipse -<strong>Window</strong> -menu or by executing {@code <sdk>/tools/android avd}).</li> - <li>Click -<strong>New</strong> and set the configuration details for the new AVD. </li> - <li>In the dialog that appears, assign a descriptive name to the AVD and then -use the Target menu to choose the <strong>Google APIs</strong> as -the system image to run on the new AVD. Set the other configuration details as -needed and then click <strong>Create AVD</strong> to finish. The SDK tools -create the new AVD configuration, which then appears in the list of available -Android Virtual Devices.</li> + <li>When the download is complete, open the AVD Manager, available under the Android Studio +Tools menu (<strong>Tools > Android > AVD Manager</strong>) or by executing +{@code <sdk>/tools/android avd}.</li> + <li>In the <em>Android Virtual Device Manager</em> window, select +<strong>+ Create Virtual Device</strong> to set the configuration details for the new AVD. </li> + <li>In the <em>Virtual Device Configuration</em> window, select device hardware, then +select <strong>Next</strong>.</li> +<li>Select a <strong>Google API</strong> as the system image to run on the new AVD, then +select <strong>Next</strong>.</li> +<li>Assign a descriptive name to the AVD and then set the other configuration details as +needed.</li> +<li>Select <strong>Finish</strong> to create the new AVD configuration, which will appear in the +list of available Android Virtual Devices.</li> </ol> <p>If you are not familiar with AVDs or how to use them, see <a @@ -205,7 +208,7 @@ href="{@docRoot}tools/devices/index.html">Managing Virtual Devices</a>.</p> above — either on an actual device or on an emulator — make sure to update your application project or build scripts as needed, so that your compiled <code>.apk</code> files that use licensing are deployed into that environment. -In particular, if you are developing in Eclipse, make sure that you set up a +In particular, if you are developing in Android Studio, make sure that you set up a Run/Debug Configuration that targets the appropriate device or AVD. </p> <p>You do not need to make any changes to your application's @@ -323,28 +326,22 @@ across all of your projects and maintain it centrally. </p> <p>The LVL is provided as a configured library project — once you have downloaded it, you can start using it right away. </p> -<p>If you are working in Eclipse with ADT, you need to add the LVL to your -workspace as a new development project, in the same way as you would a new -application project. </p> +<p>If you are working in Android Studio, you need to add the LVL to your +project as a new module.</p> <ol> -<li>Use the New Project Wizard to create a new -project from existing sources. Select the LVL's <code>library</code> directory -(the directory containing the library's AndroidManifest.xml file) as the project -root.</li> -<li>When you are creating the library project, you can select any application -name, package, and set other fields as needed. </li> -<li>For the library's build target, select Android 1.5 (API level 3) or higher.</li> +<li>Use the New Module Wizard to import a library module by selecting +<strong>File > New > Import Module</strong>.</li> +<li>In the <em>New Module</em> window, in <em>Source directory</em>, enter the LVL's +<code>library</code> directory (the directory containing the library's AndroidManifest.xml file) +as the project root ({@code <sdk>/extras/google/play_licensing/library/AndroidManifest.xml}), +then select <strong>Next</strong>.</li> +<li>Select <strong>Finish</strong> to import the library module.</li> </ol> -<p> When created, the project is -predefined as a library project in its <code>project.properties</code> file, so -no further configuration is needed. </p> - -<p>For more information about how to create an application project or work with -library projects in Eclipse, see <a -href="{@docRoot}tools/projects/projects-eclipse.html">Managing Projects from -Eclipse with ADT</a>.</p> +<p>For more information about how to work with library modules in Android Studio, see +<a href="{@docRoot}sdk/installing/create-project.html#SettingUpLibraryModule">Managing Projects from +Android Studio</a>.</p> <h4>Copying the LVL sources to your application</h4> @@ -369,24 +366,10 @@ build tools to include the LVL library project sources in your application at compile time. The process for adding a reference to a library project depends on your development environment, as described below.</p> -<p> If you are developing in Eclipse with ADT, you should already have added the -library project to your workspace, as described in the previous section. If you +<p> If you are developing in Android Studio, you should already have added the +library module to your project, as described in the previous section. If you haven't done that already, do it now before continuing. </p> -<p>Next, open the application's project properties window, as shown below. -Select the "Android" properties group and click <strong>Add</strong>, then -choose the LVL library project (com_android_vending_licensing) and click -<strong>OK</strong>. For more information, see -<a href="{@docRoot}tools/projects/projects-eclipse.html#SettingUpLibraryProject"> -Managing Projects from Eclipse with ADT</a></p>. - - -<img src="{@docRoot}images/licensing_add_library.png" alt=""/> -<p class="img-caption"><strong>Figure 3.</strong> If you are -working in Eclipse with ADT, you can add the LVL library project to your -application from the application's project properties.</p> - - <p>If you are developing using the SDK command-line tools, navigate to the directory containing your application project and open the <code>project.properties</code> file. Add a line to the file that specifies the diff --git a/docs/html/guide/components/activities.jd b/docs/html/guide/components/activities.jd index 5e6917bac0f5..b5f7c9865fa8 100644 --- a/docs/html/guide/components/activities.jd +++ b/docs/html/guide/components/activities.jd @@ -115,7 +115,7 @@ within the activity's window and can respond to user interaction. For example, a button that initiates an action when the user touches it.</p> <p>Android provides a number of ready-made views that you can use to design and organize your -layout. "Widgets" are views that provide a visual (and interactive) elements for the screen, such +layout. "Widgets" are views that provide visual (and interactive) elements for the screen, such as a button, text field, checkbox, or just an image. "Layouts" are views derived from {@link android.view.ViewGroup} that provide a unique layout model for its child views, such as a linear layout, a grid layout, or relative layout. You can also subclass the {@link android.view.View} and @@ -661,7 +661,7 @@ that should be saved. Almost every widget in the Android framework implements th appropriate, such that any visible changes to the UI are automatically saved and restored when your activity is recreated. For example, the {@link android.widget.EditText} widget saves any text entered by the user and the {@link android.widget.CheckBox} widget saves whether it's checked or -not. The only work required by you is to provide a unique ID (with the <a +not. The only work required of you is to provide a unique ID (with the <a href="{@docRoot}guide/topics/resources/layout-resource.html#idvalue">{@code android:id}</a> attribute) for each widget you want to save its state. If a widget does not have an ID, then the system cannot save its state.</p> diff --git a/docs/html/guide/components/aidl.jd b/docs/html/guide/components/aidl.jd index 0be6e6fa56b3..78fa99696b7b 100644..100755 --- a/docs/html/guide/components/aidl.jd +++ b/docs/html/guide/components/aidl.jd @@ -190,11 +190,11 @@ project's {@code gen/} directory. The generated file name matches the {@code .ai with a {@code .java} extension (for example, {@code IRemoteService.aidl} results in {@code IRemoteService.java}).</p> -<p>If you use Eclipse, the incremental build generates the binder class almost immediately. If you -do not use Eclipse, then the Ant tool generates the binder class next time you build your -application—you should build your project with <code>ant debug</code> (or <code>ant -release</code>) as soon as you're finished writing the {@code .aidl} file, so that your code can -link against the generated class.</p> +<p>If you use Android Studio, the incremental build generates the binder class almost immediately. +If you do not use Android Studio, then the Gradle tool generates the binder class next time you +build your application—you should build your project with <code>gradle assembleDebug</code> +(or <code>gradle assembleRelease</code>) as soon as you're finished writing the {@code .aidl} file, +so that your code can link against the generated class.</p> <h3 id="Implement">2. Implement the interface</h3> @@ -217,7 +217,7 @@ inherited from the {@code .aidl} file.</p> <p>Here is an example implementation of an interface called {@code IRemoteService} (defined by the {@code IRemoteService.aidl} example, above) using an anonymous instance:</p> - + <pre> private final IRemoteService.Stub mBinder = new IRemoteService.Stub() { public int getPid(){ @@ -324,7 +324,7 @@ href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p> - + <h2 id="PassingObjects">Passing Objects over IPC</h2> diff --git a/docs/html/guide/components/fundamentals.jd b/docs/html/guide/components/fundamentals.jd index ca111962b862..80125ba4f07a 100644 --- a/docs/html/guide/components/fundamentals.jd +++ b/docs/html/guide/components/fundamentals.jd @@ -369,7 +369,7 @@ declare an intent filter to respond to "send" intents (in order to send a new em </pre> <p>Then, if another app creates an intent with the {@link -android.content.Intent#ACTION_SEND} action and pass it to {@link android.app.Activity#startActivity +android.content.Intent#ACTION_SEND} action and passes it to {@link android.app.Activity#startActivity startActivity()}, the system may start your activity so the user can draft and send an email.</p> diff --git a/docs/html/guide/topics/providers/content-provider-basics.jd b/docs/html/guide/topics/providers/content-provider-basics.jd index 16e68d1f3f50..b7ae3d2cb85c 100644 --- a/docs/html/guide/topics/providers/content-provider-basics.jd +++ b/docs/html/guide/topics/providers/content-provider-basics.jd @@ -328,7 +328,7 @@ content://user_dictionary/words </pre> <p> where the <code>user_dictionary</code> string is the provider's authority, and - <code>words</code> string is the table's path. The string + the <code>words</code> string is the table's path. The string <code>content://</code> (the <strong>scheme</strong>) is always present, and identifies this as a content URI. </p> @@ -346,8 +346,8 @@ Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4); </p> <p class="note"> <strong>Note:</strong> The {@link android.net.Uri} and {@link android.net.Uri.Builder} classes - contain convenience methods for constructing well-formed Uri objects from strings. The - {@link android.content.ContentUris} contains convenience methods for appending id values to + contain convenience methods for constructing well-formed URI objects from strings. The + {@link android.content.ContentUris} class contains convenience methods for appending id values to a URI. The previous snippet uses {@link android.content.ContentUris#withAppendedId withAppendedId()} to append an id to the UserDictionary content URI. </p> @@ -407,7 +407,7 @@ Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4); <!-- Constructing the query --> <h3 id="Query">Constructing the query</h3> <p> - The next step in retrieving data a provider is to construct a query. This first snippet + The next step in retrieving data from a provider is to construct a query. This first snippet defines some variables for accessing the User Dictionary Provider: </p> <pre class="prettyprint"> diff --git a/docs/html/guide/topics/resources/string-resource.jd b/docs/html/guide/topics/resources/string-resource.jd index 743e69233645..6e874d017c17 100644 --- a/docs/html/guide/topics/resources/string-resource.jd +++ b/docs/html/guide/topics/resources/string-resource.jd @@ -1,6 +1,7 @@ page.title=String Resources parent.title=Resource Types parent.link=available-resources.html +page.metaDescription=Explains how to use string resources in your UI. @jd:body <p>A string resource provides text strings for your application diff --git a/docs/html/guide/topics/security/permissions.jd b/docs/html/guide/topics/security/permissions.jd index 1091a0961d79..ecbe33ab4abb 100644 --- a/docs/html/guide/topics/security/permissions.jd +++ b/docs/html/guide/topics/security/permissions.jd @@ -334,7 +334,7 @@ to be as high as possible. You can see which permissions were added with each re If the device is running Android 6.0 (API level 23) and the app's <a href= "{@docRoot}guide/topics/manifest/uses-sdk-element.html#target" ><code>targetSdkVersion</code></a> is 23 or higher, the following system - behavior applies when you app requests a dangerous permission: + behavior applies when your app requests a dangerous permission: </p> <ul> diff --git a/docs/html/guide/topics/ui/index.jd b/docs/html/guide/topics/ui/index.jd index f342b0652f5b..0725eb73defc 100644 --- a/docs/html/guide/topics/ui/index.jd +++ b/docs/html/guide/topics/ui/index.jd @@ -1,6 +1,6 @@ page.title=User Interface page.landing=true -page.landing.intro=Your app's user interface is everything that the user can see and interact with. Android provides a variety of pre-build UI components such as structured layout objects and UI controls that allow you to build the graphical user interface for your app. Android also provides other UI modules for special interfaces such as dialogs, notifications, and menus. +page.landing.intro=Your app's user interface is everything that the user can see and interact with. Android provides a variety of pre-built UI components such as structured layout objects and UI controls that allow you to build the graphical user interface for your app. Android also provides other UI modules for special interfaces such as dialogs, notifications, and menus. page.landing.image=images/ui/ui_index.png page.landing.next=overview.html @@ -10,7 +10,7 @@ page.landing.next=overview.html <div class="col-6"> <h3>Blog Articles</h3> - + <a href="http://android-developers.blogspot.com/2012/01/say-goodbye-to-menu-button.html"> <h4>Say Goodbye to the Menu Button</h4> <p>As Ice Cream Sandwich rolls out to more devices, it’s important that you begin to migrate @@ -35,7 +35,7 @@ it probably won’t be too long before you’ll need to implement horizontally s <div class="col-6"> <h3>Training</h3> - + <a href="http://developer.android.com/training/implementing-navigation/index.html"> <h4>Implementing Effective Navigation</h4> <p>This class shows you how to plan out the high-level screen hierarchy for your application diff --git a/docs/html/images/brand/Google_Play_Store_48.png b/docs/html/images/brand/Google_Play_Store_48.png Binary files differdeleted file mode 100644 index 2f0cfe0ac650..000000000000 --- a/docs/html/images/brand/Google_Play_Store_48.png +++ /dev/null diff --git a/docs/html/images/brand/Google_Play_Store_600.png b/docs/html/images/brand/Google_Play_Store_600.png Binary files differdeleted file mode 100644 index f748652ef0c0..000000000000 --- a/docs/html/images/brand/Google_Play_Store_600.png +++ /dev/null diff --git a/docs/html/images/brand/Google_Play_Store_96.png b/docs/html/images/brand/Google_Play_Store_96.png Binary files differdeleted file mode 100644 index 6e2c83577a33..000000000000 --- a/docs/html/images/brand/Google_Play_Store_96.png +++ /dev/null diff --git a/docs/html/images/brand/af_generic_rgb_wo_45.png b/docs/html/images/brand/af_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index bf774ab29140..000000000000 --- a/docs/html/images/brand/af_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/af_generic_rgb_wo_60.png b/docs/html/images/brand/af_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 0487c7fea801..000000000000 --- a/docs/html/images/brand/af_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/ar_generic_rgb_wo_45.png b/docs/html/images/brand/ar_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index c403608c1d57..000000000000 --- a/docs/html/images/brand/ar_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/ar_generic_rgb_wo_60.png b/docs/html/images/brand/ar_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 95e31ebbbea3..000000000000 --- a/docs/html/images/brand/ar_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/be_generic_rgb_wo_45.png b/docs/html/images/brand/be_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index bec6c7a4c031..000000000000 --- a/docs/html/images/brand/be_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/be_generic_rgb_wo_60.png b/docs/html/images/brand/be_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 53ad2a11e5fc..000000000000 --- a/docs/html/images/brand/be_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/bg_generic_rgb_wo_45.png b/docs/html/images/brand/bg_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 9a2747199a33..000000000000 --- a/docs/html/images/brand/bg_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/bg_generic_rgb_wo_60.png b/docs/html/images/brand/bg_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 5143a6602c6c..000000000000 --- a/docs/html/images/brand/bg_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/ca_generic_rgb_wo_45.png b/docs/html/images/brand/ca_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 698a4cda0921..000000000000 --- a/docs/html/images/brand/ca_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/ca_generic_rgb_wo_60.png b/docs/html/images/brand/ca_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index e943de12262a..000000000000 --- a/docs/html/images/brand/ca_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/cs_generic_rgb_wo_45.png b/docs/html/images/brand/cs_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index b97b805cc1c8..000000000000 --- a/docs/html/images/brand/cs_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/cs_generic_rgb_wo_60.png b/docs/html/images/brand/cs_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 9656c2ee3425..000000000000 --- a/docs/html/images/brand/cs_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/da_generic_rgb_wo_45.png b/docs/html/images/brand/da_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 541ba293cf0d..000000000000 --- a/docs/html/images/brand/da_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/da_generic_rgb_wo_60.png b/docs/html/images/brand/da_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index d9741544d083..000000000000 --- a/docs/html/images/brand/da_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/de_app_rgb_wo_45.png b/docs/html/images/brand/de_app_rgb_wo_45.png Binary files differdeleted file mode 100644 index db48df2245aa..000000000000 --- a/docs/html/images/brand/de_app_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/de_app_rgb_wo_60.png b/docs/html/images/brand/de_app_rgb_wo_60.png Binary files differdeleted file mode 100644 index 9e0f75719736..000000000000 --- a/docs/html/images/brand/de_app_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/de_generic_rgb_wo_45.png b/docs/html/images/brand/de_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 1396f7972f4c..000000000000 --- a/docs/html/images/brand/de_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/de_generic_rgb_wo_60.png b/docs/html/images/brand/de_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index f2df4a468b10..000000000000 --- a/docs/html/images/brand/de_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/el_generic_rgb_wo_45.png b/docs/html/images/brand/el_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index adaea5fdf3f3..000000000000 --- a/docs/html/images/brand/el_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/el_generic_rgb_wo_60.png b/docs/html/images/brand/el_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 37ae3bc28274..000000000000 --- a/docs/html/images/brand/el_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/en_app_rgb_wo_45.png b/docs/html/images/brand/en_app_rgb_wo_45.png Binary files differdeleted file mode 100644 index 9891cbbd39d3..000000000000 --- a/docs/html/images/brand/en_app_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/en_app_rgb_wo_60.png b/docs/html/images/brand/en_app_rgb_wo_60.png Binary files differdeleted file mode 100644 index 649e782e0209..000000000000 --- a/docs/html/images/brand/en_app_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/en_generic_rgb_wo_45.png b/docs/html/images/brand/en_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 73dd393c5f3b..000000000000 --- a/docs/html/images/brand/en_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/en_generic_rgb_wo_60.png b/docs/html/images/brand/en_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 9a50affda395..000000000000 --- a/docs/html/images/brand/en_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/es-419_app_rgb_wo_45.png b/docs/html/images/brand/es-419_app_rgb_wo_45.png Binary files differdeleted file mode 100644 index 3fb9a3f14bcc..000000000000 --- a/docs/html/images/brand/es-419_app_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/es-419_app_rgb_wo_60.png b/docs/html/images/brand/es-419_app_rgb_wo_60.png Binary files differdeleted file mode 100644 index 1dfb820082eb..000000000000 --- a/docs/html/images/brand/es-419_app_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/es-419_generic_rgb_wo_45.png b/docs/html/images/brand/es-419_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index b89274d71150..000000000000 --- a/docs/html/images/brand/es-419_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/es-419_generic_rgb_wo_60.png b/docs/html/images/brand/es-419_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 23d7705934d2..000000000000 --- a/docs/html/images/brand/es-419_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/es_app_rgb_wo_45.png b/docs/html/images/brand/es_app_rgb_wo_45.png Binary files differdeleted file mode 100644 index ad5e61ae7e3f..000000000000 --- a/docs/html/images/brand/es_app_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/es_app_rgb_wo_60.png b/docs/html/images/brand/es_app_rgb_wo_60.png Binary files differdeleted file mode 100644 index 6796ad31089d..000000000000 --- a/docs/html/images/brand/es_app_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/es_generic_rgb_wo_45.png b/docs/html/images/brand/es_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index b89274d71150..000000000000 --- a/docs/html/images/brand/es_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/es_generic_rgb_wo_60.png b/docs/html/images/brand/es_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 23d7705934d2..000000000000 --- a/docs/html/images/brand/es_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/et_generic_rgb_wo_45.png b/docs/html/images/brand/et_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 0e2673811ab0..000000000000 --- a/docs/html/images/brand/et_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/et_generic_rgb_wo_60.png b/docs/html/images/brand/et_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index a99dee1b5f92..000000000000 --- a/docs/html/images/brand/et_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/fa_generic_rgb_wo_45.png b/docs/html/images/brand/fa_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 25827f69c3f4..000000000000 --- a/docs/html/images/brand/fa_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/fa_generic_rgb_wo_60.png b/docs/html/images/brand/fa_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 51189092fa55..000000000000 --- a/docs/html/images/brand/fa_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/fi_generic_rgb_wo_45.png b/docs/html/images/brand/fi_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 93dc4fc10245..000000000000 --- a/docs/html/images/brand/fi_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/fi_generic_rgb_wo_60.png b/docs/html/images/brand/fi_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 95eff074dea2..000000000000 --- a/docs/html/images/brand/fi_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/fil_generic_rgb_wo_45.png b/docs/html/images/brand/fil_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 7e74e62ac49d..000000000000 --- a/docs/html/images/brand/fil_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/fil_generic_rgb_wo_60.png b/docs/html/images/brand/fil_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 8f027438aa2c..000000000000 --- a/docs/html/images/brand/fil_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/fr_app_rgb_wo_45.png b/docs/html/images/brand/fr_app_rgb_wo_45.png Binary files differdeleted file mode 100644 index 14219e311548..000000000000 --- a/docs/html/images/brand/fr_app_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/fr_app_rgb_wo_60.png b/docs/html/images/brand/fr_app_rgb_wo_60.png Binary files differdeleted file mode 100644 index af588431135d..000000000000 --- a/docs/html/images/brand/fr_app_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/fr_generic_rgb_wo_45.png b/docs/html/images/brand/fr_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 3e1768f824fa..000000000000 --- a/docs/html/images/brand/fr_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/fr_generic_rgb_wo_60.png b/docs/html/images/brand/fr_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 5c307f5c2aec..000000000000 --- a/docs/html/images/brand/fr_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/hr_generic_rgb_wo_45.png b/docs/html/images/brand/hr_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index b8acaac1e41f..000000000000 --- a/docs/html/images/brand/hr_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/hr_generic_rgb_wo_60.png b/docs/html/images/brand/hr_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 4fe6c7b46477..000000000000 --- a/docs/html/images/brand/hr_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/hu_generic_rgb_wo_45.png b/docs/html/images/brand/hu_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 3b2184d5c5a8..000000000000 --- a/docs/html/images/brand/hu_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/hu_generic_rgb_wo_60.png b/docs/html/images/brand/hu_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index d6572be96984..000000000000 --- a/docs/html/images/brand/hu_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/id-in_generic_rgb_wo_45.png b/docs/html/images/brand/id-in_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 17ce06921af9..000000000000 --- a/docs/html/images/brand/id-in_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/id-in_generic_rgb_wo_60.png b/docs/html/images/brand/id-in_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index ad067cee03ff..000000000000 --- a/docs/html/images/brand/id-in_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/it_app_rgb_wo_45.png b/docs/html/images/brand/it_app_rgb_wo_45.png Binary files differdeleted file mode 100644 index 16a137e0e59c..000000000000 --- a/docs/html/images/brand/it_app_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/it_app_rgb_wo_60.png b/docs/html/images/brand/it_app_rgb_wo_60.png Binary files differdeleted file mode 100644 index 27123dc883a3..000000000000 --- a/docs/html/images/brand/it_app_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/it_generic_rgb_wo_45.png b/docs/html/images/brand/it_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index ee5f85ee4a20..000000000000 --- a/docs/html/images/brand/it_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/it_generic_rgb_wo_60.png b/docs/html/images/brand/it_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 03ea5bac12d9..000000000000 --- a/docs/html/images/brand/it_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/iw-he_generic_rgb_wo_45.png b/docs/html/images/brand/iw-he_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 1d03c7745afa..000000000000 --- a/docs/html/images/brand/iw-he_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/iw-he_generic_rgb_wo_60.png b/docs/html/images/brand/iw-he_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index decfdae68d86..000000000000 --- a/docs/html/images/brand/iw-he_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/ja_app_rgb_wo_45.png b/docs/html/images/brand/ja_app_rgb_wo_45.png Binary files differdeleted file mode 100644 index 6af7582a142f..000000000000 --- a/docs/html/images/brand/ja_app_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/ja_app_rgb_wo_60.png b/docs/html/images/brand/ja_app_rgb_wo_60.png Binary files differdeleted file mode 100644 index e197e12beacc..000000000000 --- a/docs/html/images/brand/ja_app_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/ja_generic_rgb_wo_45.png b/docs/html/images/brand/ja_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 5f5281a3a147..000000000000 --- a/docs/html/images/brand/ja_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/ja_generic_rgb_wo_60.png b/docs/html/images/brand/ja_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index fcb4c9cb1dba..000000000000 --- a/docs/html/images/brand/ja_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/ko_app_rgb_wo_45.png b/docs/html/images/brand/ko_app_rgb_wo_45.png Binary files differdeleted file mode 100644 index f0b427e186e1..000000000000 --- a/docs/html/images/brand/ko_app_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/ko_app_rgb_wo_60.png b/docs/html/images/brand/ko_app_rgb_wo_60.png Binary files differdeleted file mode 100644 index 6ccb673fc718..000000000000 --- a/docs/html/images/brand/ko_app_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/ko_generic_rgb_wo_45.png b/docs/html/images/brand/ko_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 61ae04aba2cc..000000000000 --- a/docs/html/images/brand/ko_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/ko_generic_rgb_wo_60.png b/docs/html/images/brand/ko_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 9c14e36220d0..000000000000 --- a/docs/html/images/brand/ko_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/lt_generic_rgb_wo_45.png b/docs/html/images/brand/lt_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 96564d5fb5fc..000000000000 --- a/docs/html/images/brand/lt_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/lt_generic_rgb_wo_60.png b/docs/html/images/brand/lt_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 2c6c1bf04cf8..000000000000 --- a/docs/html/images/brand/lt_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/lv_generic_rgb_wo_45.png b/docs/html/images/brand/lv_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 8182ca52f002..000000000000 --- a/docs/html/images/brand/lv_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/lv_generic_rgb_wo_60.png b/docs/html/images/brand/lv_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 5c0b3d24709e..000000000000 --- a/docs/html/images/brand/lv_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/ms_generic_rgb_wo_45.png b/docs/html/images/brand/ms_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index d6ccc6ba3714..000000000000 --- a/docs/html/images/brand/ms_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/ms_generic_rgb_wo_60.png b/docs/html/images/brand/ms_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 6e1c34d5346b..000000000000 --- a/docs/html/images/brand/ms_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/nl_app_rgb_wo_45.png b/docs/html/images/brand/nl_app_rgb_wo_45.png Binary files differdeleted file mode 100644 index f06ed04d16e6..000000000000 --- a/docs/html/images/brand/nl_app_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/nl_app_rgb_wo_60.png b/docs/html/images/brand/nl_app_rgb_wo_60.png Binary files differdeleted file mode 100644 index f2c797da4240..000000000000 --- a/docs/html/images/brand/nl_app_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/nl_generic_rgb_wo_45.png b/docs/html/images/brand/nl_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 6b5826d3bd14..000000000000 --- a/docs/html/images/brand/nl_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/nl_generic_rgb_wo_60.png b/docs/html/images/brand/nl_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index cb11afda95a4..000000000000 --- a/docs/html/images/brand/nl_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/no_generic_rgb_wo_45.png b/docs/html/images/brand/no_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index fb390d89cb45..000000000000 --- a/docs/html/images/brand/no_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/no_generic_rgb_wo_60.png b/docs/html/images/brand/no_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index e83dce701d7a..000000000000 --- a/docs/html/images/brand/no_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/pl_generic_rgb_wo_45.png b/docs/html/images/brand/pl_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 78cadedb7e28..000000000000 --- a/docs/html/images/brand/pl_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/pl_generic_rgb_wo_60.png b/docs/html/images/brand/pl_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 2d956fba0092..000000000000 --- a/docs/html/images/brand/pl_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/pt-br_app_rgb_wo_45.png b/docs/html/images/brand/pt-br_app_rgb_wo_45.png Binary files differdeleted file mode 100644 index 065998b86e3d..000000000000 --- a/docs/html/images/brand/pt-br_app_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/pt-br_app_rgb_wo_60.png b/docs/html/images/brand/pt-br_app_rgb_wo_60.png Binary files differdeleted file mode 100644 index 1ce0a6c505aa..000000000000 --- a/docs/html/images/brand/pt-br_app_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/pt-br_generic_rgb_wo_45.png b/docs/html/images/brand/pt-br_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index a661d4427dfa..000000000000 --- a/docs/html/images/brand/pt-br_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/pt-br_generic_rgb_wo_60.png b/docs/html/images/brand/pt-br_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 402af7103d2a..000000000000 --- a/docs/html/images/brand/pt-br_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/pt-pt_app_rgb_wo_45.png b/docs/html/images/brand/pt-pt_app_rgb_wo_45.png Binary files differdeleted file mode 100644 index 0b50959a146b..000000000000 --- a/docs/html/images/brand/pt-pt_app_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/pt-pt_app_rgb_wo_60.png b/docs/html/images/brand/pt-pt_app_rgb_wo_60.png Binary files differdeleted file mode 100644 index 65dd88725662..000000000000 --- a/docs/html/images/brand/pt-pt_app_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/pt-pt_generic_rgb_wo_45.png b/docs/html/images/brand/pt-pt_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index a616cf1235cf..000000000000 --- a/docs/html/images/brand/pt-pt_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/pt-pt_generic_rgb_wo_60.png b/docs/html/images/brand/pt-pt_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 36a7b83fbac3..000000000000 --- a/docs/html/images/brand/pt-pt_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/ro_generic_rgb_wo_45.png b/docs/html/images/brand/ro_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index c18a54833d30..000000000000 --- a/docs/html/images/brand/ro_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/ro_generic_rgb_wo_60.png b/docs/html/images/brand/ro_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index b8f3433ab2ca..000000000000 --- a/docs/html/images/brand/ro_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/ru_generic_rgb_wo_45.png b/docs/html/images/brand/ru_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index c049ddb4a4e9..000000000000 --- a/docs/html/images/brand/ru_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/ru_generic_rgb_wo_60.png b/docs/html/images/brand/ru_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index e00c27615d75..000000000000 --- a/docs/html/images/brand/ru_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/sk_generic_rgb_wo_45.png b/docs/html/images/brand/sk_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 27ce06ac77b1..000000000000 --- a/docs/html/images/brand/sk_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/sk_generic_rgb_wo_60.png b/docs/html/images/brand/sk_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 8591f2c27015..000000000000 --- a/docs/html/images/brand/sk_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/sl_generic_rgb_wo_45.png b/docs/html/images/brand/sl_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 115a99dd1e59..000000000000 --- a/docs/html/images/brand/sl_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/sl_generic_rgb_wo_60.png b/docs/html/images/brand/sl_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 37c2e52cc2a0..000000000000 --- a/docs/html/images/brand/sl_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/sr_generic_rgb_wo_45.png b/docs/html/images/brand/sr_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 86dba47b6bfa..000000000000 --- a/docs/html/images/brand/sr_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/sr_generic_rgb_wo_60.png b/docs/html/images/brand/sr_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 67806da6e486..000000000000 --- a/docs/html/images/brand/sr_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/sv_generic_rgb_wo_45.png b/docs/html/images/brand/sv_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index fb390d89cb45..000000000000 --- a/docs/html/images/brand/sv_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/sv_generic_rgb_wo_60.png b/docs/html/images/brand/sv_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index e83dce701d7a..000000000000 --- a/docs/html/images/brand/sv_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/sw_generic_rgb_wo_45.png b/docs/html/images/brand/sw_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index c7deecc57fb2..000000000000 --- a/docs/html/images/brand/sw_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/sw_generic_rgb_wo_60.png b/docs/html/images/brand/sw_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 9c0d057c05ee..000000000000 --- a/docs/html/images/brand/sw_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/th_generic_rgb_wo_45.png b/docs/html/images/brand/th_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 803b6c5a05c7..000000000000 --- a/docs/html/images/brand/th_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/th_generic_rgb_wo_60.png b/docs/html/images/brand/th_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 6e36e02ddb2f..000000000000 --- a/docs/html/images/brand/th_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/tr_generic_rgb_wo_45.png b/docs/html/images/brand/tr_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index baa8394cd4e4..000000000000 --- a/docs/html/images/brand/tr_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/tr_generic_rgb_wo_60.png b/docs/html/images/brand/tr_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 63fa31f2ba6a..000000000000 --- a/docs/html/images/brand/tr_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/uk_generic_rgb_wo_45.png b/docs/html/images/brand/uk_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 68c111fe2f04..000000000000 --- a/docs/html/images/brand/uk_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/uk_generic_rgb_wo_60.png b/docs/html/images/brand/uk_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 918d70a9b806..000000000000 --- a/docs/html/images/brand/uk_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/vi_generic_rgb_wo_45.png b/docs/html/images/brand/vi_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index e39d00ad5c73..000000000000 --- a/docs/html/images/brand/vi_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/vi_generic_rgb_wo_60.png b/docs/html/images/brand/vi_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index ba1e9a06100a..000000000000 --- a/docs/html/images/brand/vi_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/zh-cn_generic_rgb_wo_45.png b/docs/html/images/brand/zh-cn_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index c7748de893de..000000000000 --- a/docs/html/images/brand/zh-cn_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/zh-cn_generic_rgb_wo_60.png b/docs/html/images/brand/zh-cn_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 0a0f91abda11..000000000000 --- a/docs/html/images/brand/zh-cn_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/zh-hk_generic_rgb_wo_45.png b/docs/html/images/brand/zh-hk_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index c3d064c1d157..000000000000 --- a/docs/html/images/brand/zh-hk_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/zh-hk_generic_rgb_wo_60.png b/docs/html/images/brand/zh-hk_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 2b072de063f2..000000000000 --- a/docs/html/images/brand/zh-hk_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/zh-tw_generic_rgb_wo_45.png b/docs/html/images/brand/zh-tw_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 7bb2b09e2910..000000000000 --- a/docs/html/images/brand/zh-tw_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/zh-tw_generic_rgb_wo_60.png b/docs/html/images/brand/zh-tw_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 0797c84b34de..000000000000 --- a/docs/html/images/brand/zh-tw_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/brand/zu_generic_rgb_wo_45.png b/docs/html/images/brand/zu_generic_rgb_wo_45.png Binary files differdeleted file mode 100644 index 1e9f7c7c6f0b..000000000000 --- a/docs/html/images/brand/zu_generic_rgb_wo_45.png +++ /dev/null diff --git a/docs/html/images/brand/zu_generic_rgb_wo_60.png b/docs/html/images/brand/zu_generic_rgb_wo_60.png Binary files differdeleted file mode 100644 index 09f521bb0cea..000000000000 --- a/docs/html/images/brand/zu_generic_rgb_wo_60.png +++ /dev/null diff --git a/docs/html/images/cards/card-install-banners_16x9_2x.png b/docs/html/images/cards/card-install-banners_16x9_2x.png Binary files differnew file mode 100644 index 000000000000..09ebc30e68d6 --- /dev/null +++ b/docs/html/images/cards/card-install-banners_16x9_2x.png diff --git a/docs/html/images/cards/card-studio-modules_crop_2x.png b/docs/html/images/cards/card-studio-modules_crop_2x.png Binary files differnew file mode 100644 index 000000000000..98ddf1f396f9 --- /dev/null +++ b/docs/html/images/cards/card-studio-modules_crop_2x.png diff --git a/docs/html/images/cards/card-user-ids_2x.png b/docs/html/images/cards/card-user-ids_2x.png Binary files differnew file mode 100644 index 000000000000..d27098dab187 --- /dev/null +++ b/docs/html/images/cards/card-user-ids_2x.png diff --git a/docs/html/images/cards/card-user-permissions_2x.png b/docs/html/images/cards/card-user-permissions_2x.png Binary files differnew file mode 100644 index 000000000000..899dc3d33127 --- /dev/null +++ b/docs/html/images/cards/card-user-permissions_2x.png diff --git a/docs/html/images/cards/card-user_2x.png b/docs/html/images/cards/card-user_2x.png Binary files differnew file mode 100644 index 000000000000..28883560fd73 --- /dev/null +++ b/docs/html/images/cards/card-user_2x.png diff --git a/docs/html/images/editorschoice_ann.png b/docs/html/images/editorschoice_ann.png Binary files differnew file mode 100644 index 000000000000..c4f2c06834c8 --- /dev/null +++ b/docs/html/images/editorschoice_ann.png diff --git a/docs/html/images/gp-about-0.jpg b/docs/html/images/gp-about-0.jpg Binary files differnew file mode 100644 index 000000000000..2dd6a8cfa558 --- /dev/null +++ b/docs/html/images/gp-about-0.jpg diff --git a/docs/html/images/gp-about-listing.jpg b/docs/html/images/gp-about-listing.jpg Binary files differnew file mode 100644 index 000000000000..256c051b96eb --- /dev/null +++ b/docs/html/images/gp-about-listing.jpg diff --git a/docs/html/images/gp-about-picks1.jpg b/docs/html/images/gp-about-picks1.jpg Binary files differnew file mode 100644 index 000000000000..555bd7ba4ae2 --- /dev/null +++ b/docs/html/images/gp-about-picks1.jpg diff --git a/docs/html/images/gp-about-picks2.jpg b/docs/html/images/gp-about-picks2.jpg Binary files differnew file mode 100644 index 000000000000..ec25e7423048 --- /dev/null +++ b/docs/html/images/gp-about-picks2.jpg diff --git a/docs/html/images/gp-about-picks3.jpg b/docs/html/images/gp-about-picks3.jpg Binary files differnew file mode 100644 index 000000000000..eb57da90f58e --- /dev/null +++ b/docs/html/images/gp-about-picks3.jpg diff --git a/docs/html/images/gp-about-top.jpg b/docs/html/images/gp-about-top.jpg Binary files differnew file mode 100644 index 000000000000..01a2744fb2cf --- /dev/null +++ b/docs/html/images/gp-about-top.jpg diff --git a/docs/html/images/gp-devconsole-home.png b/docs/html/images/gp-devconsole-home.png Binary files differnew file mode 100644 index 000000000000..b29dc259de73 --- /dev/null +++ b/docs/html/images/gp-devconsole-home.png diff --git a/docs/html/images/gp-rating-web.png b/docs/html/images/gp-rating-web.png Binary files differnew file mode 100644 index 000000000000..14582af5071e --- /dev/null +++ b/docs/html/images/gp-rating-web.png diff --git a/docs/html/images/testing/testing-icon.png b/docs/html/images/testing/testing-icon.png Binary files differnew file mode 100644 index 000000000000..41a783bf0e4c --- /dev/null +++ b/docs/html/images/testing/testing-icon.png diff --git a/docs/html/images/tools/and-studio_feat-gradle_2x.png b/docs/html/images/tools/and-studio_feat-gradle_2x.png Binary files differnew file mode 100644 index 000000000000..b4821b61e8f6 --- /dev/null +++ b/docs/html/images/tools/and-studio_feat-gradle_2x.png diff --git a/docs/html/images/tools/and-studio_shortcuts-included_2x.png b/docs/html/images/tools/and-studio_shortcuts-included_2x.png Binary files differnew file mode 100644 index 000000000000..8d4e30b1a918 --- /dev/null +++ b/docs/html/images/tools/and-studio_shortcuts-included_2x.png diff --git a/docs/html/images/tools/codeeditor-low.gif b/docs/html/images/tools/codeeditor-low.gif Binary files differnew file mode 100644 index 000000000000..50d840ccad31 --- /dev/null +++ b/docs/html/images/tools/codeeditor-low.gif diff --git a/docs/html/images/topdev_ann.png b/docs/html/images/topdev_ann.png Binary files differnew file mode 100644 index 000000000000..9564387e8d8b --- /dev/null +++ b/docs/html/images/topdev_ann.png diff --git a/docs/html/images/training/articles/user-data-overview-permissions-flow01.jpg b/docs/html/images/training/articles/user-data-overview-permissions-flow01.jpg Binary files differnew file mode 100644 index 000000000000..e3b192b53df3 --- /dev/null +++ b/docs/html/images/training/articles/user-data-overview-permissions-flow01.jpg diff --git a/docs/html/images/training/articles/user-data-overview-permissions-flow02.png b/docs/html/images/training/articles/user-data-overview-permissions-flow02.png Binary files differnew file mode 100644 index 000000000000..f572a44ddf94 --- /dev/null +++ b/docs/html/images/training/articles/user-data-overview-permissions-flow02.png diff --git a/docs/html/images/training/articles/user-data-overview-permissions-groups.png b/docs/html/images/training/articles/user-data-overview-permissions-groups.png Binary files differnew file mode 100644 index 000000000000..599648941a0d --- /dev/null +++ b/docs/html/images/training/articles/user-data-overview-permissions-groups.png diff --git a/docs/html/images/training/articles/user-data-overview-permissions-usage.jpg b/docs/html/images/training/articles/user-data-overview-permissions-usage.jpg Binary files differnew file mode 100644 index 000000000000..07323693a6db --- /dev/null +++ b/docs/html/images/training/articles/user-data-overview-permissions-usage.jpg diff --git a/docs/html/index.jd b/docs/html/index.jd index 6c1b30a1ef4e..df815895d1f3 100644 --- a/docs/html/index.jd +++ b/docs/html/index.jd @@ -5,6 +5,16 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 @jd:body +<script> + $(document).ready(function() { + if (useUpdatedTemplates) { + $("#useUpdatedTemplates").css("display","block"); + } else { + $("#useOldTemplates").css("display","block"); + } + }) +</script> + <!-- <div class="dac-hero-carousel" data-carousel-query="collection:index/carousel"> </div> --> <section class="dac-hero-carousel"> @@ -39,11 +49,39 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 </a> </article></section> -<div class="actions-bar dac-expand dac-invert"> +<div id="useUpdatedTemplates" style="display:none" class="dac-section dac-slim dac-gray dac-expand"> <div class="wrap dac-offset-parent"> <a class="dac-fab dac-scroll-button" data-scroll-button href="#build-apps"> <i class="dac-sprite dac-arrow-down-gray"></i> </a> + <ul class="dac-actions"> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}sdk/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Get the SDK + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}samples/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Browse sample code + </a> + </li> + <li class="dac-action"> + <a class="dac-action-link" href="{@docRoot}distribute/stories/index.html"> + <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i> + Watch stories + </a> + </li> + </ul> + </div><!-- end .wrap --> +</div><!-- end .dac-actions --> + +<div id="useOldTemplates" style="display:none" class="actions-bar dac-expand dac-invert"> + <div class="wrap dac-offset-parent"> + <a class="dac-fab dac-scroll-button" data-scroll-button="" href="#build-apps"> + <i class="dac-sprite dac-arrow-down-gray"></i> + </a> <div class="actions"> <div><a href="{@docRoot}sdk/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> @@ -53,17 +91,15 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 <span class="dac-sprite dac-auto-chevron-large"></span> Browse Samples </a></div> - <div><a href="https://www.youtube.com/user/androiddevelopers"> + <div><a href="{@docRoot}distribute/stories/index.html"> <span class="dac-sprite dac-auto-chevron-large"></span> - Watch Videos + Watch Stories </a></div> </div><!-- end .actions --> </div><!-- end .wrap --> -</div><!-- end .actions-bar --> - - +</div> -<section class="dac-section dac-section-light" id="build-apps"><div class="wrap"> +<section class="dac-section dac-light" id="build-apps"><div class="wrap"> <h1 class="dac-section-title">Build Beautiful Apps</h1> <div class="dac-section-subtitle"> Resources to get you started with designing and developing for Android. diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js index 0f2ba3e719e7..739b64830e85 100644 --- a/docs/html/jd_collections.js +++ b/docs/html/jd_collections.js @@ -16,7 +16,7 @@ var RESOURCE_COLLECTIONS = { "index/secondary/carousel": { "title": "", "resources": [ - "http://www.youtube.com/watch?v=yJisuP94lHU", + "https://www.youtube.com/watch?v=yJisuP94lHU", "http://www.youtube.com/watch?v=rcU7VEs1hiE", "http://www.youtube.com/watch?v=JFlX9rW7Epc", "http://www.youtube.com/watch?v=4CqXCkcN_d4" @@ -41,9 +41,9 @@ var RESOURCE_COLLECTIONS = { "design/landing/latest": { "title": "", "resources": [ - "http://www.youtube.com/watch?v=p4gmvHyuZzw", - "http://www.youtube.com/watch?v=YaG_ljfzeUw", - "http://www.youtube.com/watch?v=XOcCOBe8PTc" + "https://www.youtube.com/watch?v=p4gmvHyuZzw", + "https://www.youtube.com/watch?v=YaG_ljfzeUw", + "https://www.youtube.com/watch?v=XOcCOBe8PTc" ] }, "design/landing/materialdesign": { @@ -90,9 +90,9 @@ var RESOURCE_COLLECTIONS = { "develop/landing/latest": { "title": "", "resources": [ - "http://android-developers.blogspot.com/2015/04/new-android-code-samples.html", - "http://android-developers.blogspot.com/2015/04/android-support-library-221.html", - "http://android-developers.blogspot.com/2015/03/a-new-reference-app-for-multi-device.html" + "https://android-developers.blogspot.com/2015/04/new-android-code-samples.html", + "https://android-developers.blogspot.com/2015/04/android-support-library-221.html", + "https://android-developers.blogspot.com/2015/03/a-new-reference-app-for-multi-device.html" ] }, "develop/landing/devpatterns": { @@ -106,9 +106,9 @@ var RESOURCE_COLLECTIONS = { "develop/landing/performance": { "title": "", "resources": [ - "http://www.youtube.com/watch?v=fEEulSk1kNY", - "http://www.youtube.com/watch?v=-3ry8PxcJJA", - "http://www.youtube.com/watch?v=_kKTGK-Cb_4" + "https://www.youtube.com/watch?v=fEEulSk1kNY", + "https://www.youtube.com/watch?v=-3ry8PxcJJA", + "https://www.youtube.com/watch?v=_kKTGK-Cb_4" ] }, "develop/landing/buildwithgoogle": { @@ -188,9 +188,9 @@ var RESOURCE_COLLECTIONS = { "title": "", "resources": [ "distribute/googleplay/guide.html", - "http://www.youtube.com/watch?v=JrR6o5tYMWQ", + "https://www.youtube.com/watch?v=JrR6o5tYMWQ", "https://www.youtube.com/watch?v=B6ydLpkhq04&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", - "http://www.youtube.com/watch?v=yJisuP94lHU", + "https://www.youtube.com/watch?v=yJisuP94lHU", ] }, "distribute/landing/googleplay": { @@ -204,12 +204,12 @@ var RESOURCE_COLLECTIONS = { "distribute/landing/more": { "title": "", "resources": [ - "distribute/users/promote-with-ads.html", - "distribute/monetize/ads.html", - "distribute/analyze/index.html", - "distribute/engage/deep-linking.html", - "distribute/engage/easy-signin.html", - "https://cloud.google.com/docs/" + "distribute/users/promote-with-ads.html", + "distribute/monetize/ads.html", + "distribute/analyze/index.html", + "distribute/engage/deep-linking.html", + "distribute/engage/easy-signin.html", + "https://cloud.google.com/docs/" ] }, "distribute/edu/videos/stories": { @@ -231,17 +231,17 @@ var RESOURCE_COLLECTIONS = { "distribute/edu/videos/experience": { "title": "", "resources": [ - "http://youtu.be/vzvpcEffvaE" + "https://youtu.be/vzvpcEffvaE" ] }, /* "launch/static": { "title": "", "resources": [ - "http://www.youtube.com/watch?v=1RIz-cmTQB4", - "http://www.youtube.com/watch?v=MVBMWDzyHAI", - "http://android-developers.blogspot.com/2013/11/app-translation-service-now-available.html", - "http://android-developers.blogspot.com/2013/10/more-visibility-for-tablet-apps-in.html", - "http://android-developers.blogspot.com/2013/11/bring-your-apps-into-classroom-with.html", + "https://www.youtube.com/watch?v=1RIz-cmTQB4", + "https://www.youtube.com/watch?v=MVBMWDzyHAI", + "https://android-developers.blogspot.com/2013/11/app-translation-service-now-available.html", + "https://android-developers.blogspot.com/2013/10/more-visibility-for-tablet-apps-in.html", + "https://android-developers.blogspot.com/2013/11/bring-your-apps-into-classroom-with.html", "distribute/essentials/quality/tablets.html", "distribute/users/build-buzz.html", "distribute/monetize/premium.html", @@ -258,17 +258,17 @@ var RESOURCE_COLLECTIONS = { "resources": [ "https://www.youtube.com/watch?v=xelYnWcYkuE", "https://www.youtube.com/playlist?list=PLCOC_kP3nqGIHEgwm9mybvA04Vn4Cg9nn", - "http://googledevjp.blogspot.jp/2014/12/android-wear.html", - "http://googledevjp.blogspot.jp/2014/12/android-studio-10.html", - "http://googledevjp.blogspot.jp/2014/12/google-play-65.html", + "https://googledevjp.blogspot.jp/2014/12/android-wear.html", + "https://googledevjp.blogspot.jp/2014/12/android-studio-10.html", + "https://googledevjp.blogspot.jp/2014/12/google-play-65.html", "intl/ja/distribute/googleplay/developer-console.html#alpha-beta", "intl/ja/distribute/googleplay/guide.html", "intl/ja/distribute/essentials/quality/core.html", - "http://support.google.com/googleplay/android-developer/answer/4430948?hl=ja", + "https://support.google.com/googleplay/android-developer/answer/4430948?hl=ja", "intl/ja/support.html", "intl/ja/distribute/essentials/quality/wear.html", "intl/ja/training/tv/start/index.html", - "http://googleforwork-japan.blogspot.jp/2014/12/gcp-google-cloud-platform-rpg-gcp.html", + "https://googleforwork-japan.blogspot.jp/2014/12/gcp-google-cloud-platform-rpg-gcp.html", "intl/ja/distribute/monetize/ads.html" ] }, @@ -277,9 +277,9 @@ var RESOURCE_COLLECTIONS = { "resources": [ "https://www.youtube.com/watch?v=7X9Ue0Nfdh4&index=2&list=PL_WJkTbDHdBksDBRoqfeyLchEQqBAOlNl", "https://www.youtube.com/watch?v=83FpwuschCQ", - "http://googledevkr.blogspot.com/2014/11/android50guidefordevelopers.html", - "http://googledevkr.blogspot.com/2014/10/material-design-on-android-checklist.html", - "http://googledevkr.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html", + "https://googledevkr.blogspot.com/2014/11/android50guidefordevelopers.html", + "https://googledevkr.blogspot.com/2014/10/material-design-on-android-checklist.html", + "https://googledevkr.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html", "intl/ko/distribute/googleplay/developer-console.html#alpha-beta", "intl/ko/distribute/googleplay/guide.html", "intl/ko/distribute/essentials/quality/core.html", @@ -313,7 +313,7 @@ var RESOURCE_COLLECTIONS = { }, "distribute/googleplay/gpfw": { "resources": [ - "http://www.android.com/work/", + "https://www.android.com/work/", "https://www.youtube.com/watch?v=jQWB_-o1kz4&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX", "training/enterprise/index.html" ] @@ -371,7 +371,6 @@ var RESOURCE_COLLECTIONS = { "distribute/analyze/build-better-apps.html", "distribute/engage/gcm.html", "distribute/engage/beta.html" - ] }, "distribute/monetize": { @@ -401,7 +400,7 @@ var RESOURCE_COLLECTIONS = { "google/play-services/index.html", "https://developers.google.com/analytics/solutions/mobile-implementation-guide", "https://developers.google.com/analytics/devguides/collection/android/", - "http://www.google.com/tagmanager/", + "https://www.google.com/tagmanager/", "https://github.com/googleanalytics/google-analytics-plugin-for-unity" ] }, @@ -493,14 +492,14 @@ var RESOURCE_COLLECTIONS = { "distribute/tools/promote": { "resources": [ "distribute/tools/promote/device-art.html", - "distribute/tools/promote/badges.html", + "https://play.google.com/intl/en_us/badges/", "distribute/tools/promote/linking.html" ] }, "distribute/tools/promote/zhcn": { "resources": [ "intl/zh-cn/distribute/tools/promote/device-art.html", - "intl/zh-cn/distribute/tools/promote/badges.html", + "https://play.google.com/intl/en_us/badges/", "intl/zh-cn/distribute/tools/promote/linking.html" ] }, @@ -523,7 +522,7 @@ var RESOURCE_COLLECTIONS = { "distribute/tools/news": { "title": "", "resources": [ - "http://android-developers.blogspot.com/", + "https://android-developers.blogspot.com/", "https://plus.google.com/+AndroidDevelopers/" ] }, @@ -606,7 +605,7 @@ var RESOURCE_COLLECTIONS = { "resources": [ "https://developers.google.com/cast/docs/ux_guidelines", "https://developers.google.com/cast/docs/android_sender", - "http://www.github.com/googlecast" + "https://www.github.com/googlecast" ] }, "distribute/googleplay/cardboard": { @@ -614,13 +613,13 @@ var RESOURCE_COLLECTIONS = { "resources": [ "https://www.google.com/get/cardboard/get-cardboard/", "https://developers.google.com/cardboard/android/download", - "http://www.google.com/design/spec-vr" + "https://www.google.com/design/spec-vr" ] }, "distribute/googleplay/gpfe/highlight": { "title": "About Google Play for Education", "resources": [ - "http://youtu.be/vzvpcEffvaE" + "https://youtu.be/vzvpcEffvaE" ] }, "distribute/googleplay/gpfe/dev/about": { @@ -641,28 +640,28 @@ var RESOURCE_COLLECTIONS = { "https://developers.google.com/edu/guidelines", "distribute/essentials/quality/tablets.html", "distribute/googleplay/developer-console.html", - "http://play.google.com/about/developer-distribution-agreement-addendum.html", + "https://play.google.com/about/developer-distribution-agreement-addendum.html", ] }, "distribute/googleplay/aboutgpfe/educators/about": { "title": "About Google Play for Education / Educators", "resources": [ - "http://www.google.com/edu/tablets/", - "http://www.youtube.com/watch?v=haEmsMo0f3w" + "https://www.google.com/edu/tablets/", + "https://www.youtube.com/watch?v=haEmsMo0f3w" ] }, "distribute/googleplay/aboutgpfe/educators": { "title": "About Google Play for Education / Educators", "resources": [ - "http://www.google.com/edu/tablets/", - "http://youtu.be/vzvpcEffvaE" + "https://www.google.com/edu/tablets/", + "https://youtu.be/vzvpcEffvaE" ] }, "distribute/googleplay/gettingstartedgpfe/educators": { "title": "About Google Play for Education / Educators", "resources": [ - "http://www.google.com/edu/tablets/", - "http://youtu.be/vzvpcEffvaE" + "https://www.google.com/edu/tablets/", + "https://youtu.be/vzvpcEffvaE" ] }, "distribute/essentials/eduessentials/developers": { @@ -676,7 +675,7 @@ var RESOURCE_COLLECTIONS = { "distribute/essentials/eduessentials/educators": { "title": "", "resources": [ - "http://www.google.com/edu/tablets/", + "https://www.google.com/edu/tablets/", "distribute/essentials/quality/tablets.html", ] }, @@ -685,7 +684,7 @@ var RESOURCE_COLLECTIONS = { "resources": [ "design/index.html", "training/articles/perf-anr.html", - "http://android-developers.blogspot.com/2013/10/improved-app-insight-by-linking-google.html" + "https://android-developers.blogspot.com/2013/10/improved-app-insight-by-linking-google.html" ] }, "distribute/users/appinvites": { @@ -708,21 +707,21 @@ var RESOURCE_COLLECTIONS = { "distribute/users/buildbuzz": { "title": "", "resources": [ - "distribute/tools/promote/badges.html", + "https://play.google.com/intl/en_us/badges/", "distribute/tools/promote/linking.html", "distribute/tools/promote/device-art.html", - "http://plus.google.com/+GooglePlay" + "https://plus.google.com/+GooglePlay" ] }, "distribute/users/createagreatlisting": { "title": "", "resources": [ "https://support.google.com/googleplay/android-developer/answer/1078870", - "http://android-developers.blogspot.com/2011/10/android-market-featured-image.html", + "https://android-developers.blogspot.com/2011/10/android-market-featured-image.html", "distribute/tools/launch-checklist.html", - "http://android-developers.blogspot.com/2013/07/making-beautiful-android-app-icons.html", - "http://android-developers.blogspot.com/2012/12/localize-your-promotional-graphics-on.html", - "http://android-developers.blogspot.com/2013/10/making-your-app-content-more-accessible.html" + "https://android-developers.blogspot.com/2013/07/making-beautiful-android-app-icons.html", + "https://android-developers.blogspot.com/2012/12/localize-your-promotional-graphics-on.html", + "https://android-developers.blogspot.com/2013/10/making-your-app-content-more-accessible.html" ] }, "distribute/users/buildcommunity": { @@ -731,7 +730,7 @@ var RESOURCE_COLLECTIONS = { "distribute/googleplay/developer-console.html", "https://support.google.com/groups/answer/46601", "https://support.google.com/plus/topic/2888488", - "http://www.youtube.com/yt/dev/" + "https://www.youtube.com/yt/dev/" ] }, "distribute/users/appindexing": { @@ -756,8 +755,8 @@ var RESOURCE_COLLECTIONS = { "resources": [ "https://support.google.com/admob/topic/2784623", "https://developers.google.com/mobile-ads-sdk/download", - "http://support.google.com/googleplay/android-developer/topic/2985714", - "http://analyticsacademy.withgoogle.com/mobile-app", + "https://support.google.com/googleplay/android-developer/topic/2985714", + "https://analyticsacademy.withgoogle.com/mobile-app", "https://support.google.com/analytics/answer/2611404", "https://support.google.com/admob/answer/3111064" ] @@ -773,16 +772,16 @@ var RESOURCE_COLLECTIONS = { "title": "", "resources": [ "distribute/googleplay/developer-console.html", - "http://android-developers.blogspot.com/" + "https://android-developers.blogspot.com/" ] }, "distribute/toolsreference/bestpractices/games": { "title": "", "resources": [ "google/play-services/games.html", - "http://android-developers.blogspot.com/", + "https://android-developers.blogspot.com/", "distribute/googleplay/developer-console.html", - "http://www.youtube.com/watch?v=1RIz-cmTQB4" + "https://www.youtube.com/watch?v=1RIz-cmTQB4" ] }, "distribute/essentials/corequalityguidelines/visualdesign": { @@ -798,7 +797,7 @@ var RESOURCE_COLLECTIONS = { "distribute/essentials/corequalityguidelines/functionality": { "title": "", "resources": [ - "http://android-developers.blogspot.com/2011/11/making-android-games-that-play-nice.html", + "https://android-developers.blogspot.com/2011/11/making-android-games-that-play-nice.html", "guide/components/tasks-and-back-stack.html", "training/basics/activity-lifecycle/recreating.html" ] @@ -843,19 +842,19 @@ var RESOURCE_COLLECTIONS = { "distribute/essentials/core/performance": { "title": "", "resources": [ - "http://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html", + "https://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html", "training/articles/perf-anr.html", - "http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html" + "https://android-developers.blogspot.com/2010/07/multithreading-for-performance.html" ] }, "distribute/essentials/core/play": { "title": "", "resources": [ "distribute/tools/launch-checklist.html", - "http://play.google.com/about/developer-content-policy.html?hl=zh-Hans", + "https://play.google.com/about/developer-content-policy.html?hl=zh-Hans", "https://support.google.com/googleplay/android-developer/answer/188189?hl=zh-Hans", "https://support.google.com/googleplay/android-developer/answer/1078870?hl=zh-Hans", - "http://android-developers.blogspot.com/2011/10/android-market-featured-image.html", + "https://android-developers.blogspot.com/2011/10/android-market-featured-image.html", "https://support.google.com/googleplay/android-developer/answer/113477?hl=zh-Hans" ] }, @@ -863,10 +862,10 @@ var RESOURCE_COLLECTIONS = { "title": "", "resources": [ "intl/zh-cn/distribute/tools/launch-checklist.html", - "http://play.google.com/about/developer-content-policy.html", + "https://play.google.com/about/developer-content-policy.html", "https://support.google.com/googleplay/android-developer/answer/188189?hl=zh-Hans", "https://support.google.com/googleplay/android-developer/answer/1078870?hl=zh-Hans", - "http://android-developers.blogspot.com/2011/10/android-market-featured-image.html", + "https://android-developers.blogspot.com/2011/10/android-market-featured-image.html", "https://support.google.com/googleplay/android-developer/answer/113477?hl=zh-Hans" ] }, @@ -940,7 +939,7 @@ var RESOURCE_COLLECTIONS = { "resources": [ "distribute/tools/launch-checklist.html", "https://play.google.com/apps/publish/", - "distribute/tools/promote/badges.html", + "https://play.google.com/intl/en_us/badges/", "distribute/tools/promote/device-art.html" ] }, @@ -949,14 +948,14 @@ var RESOURCE_COLLECTIONS = { "resources": [ "intl/zh-cn/distribute/tools/launch-checklist.html", "https://play.google.com/apps/publish/?hl=zh-Hans", - "intl/zh-cn/distribute/tools/promote/badges.html", + "https://play.google.com/intl/en_us/badges/", "intl/zh-cn/distribute/tools/promote/device-art.html" ] }, "distribute/essentials/tabletguidelines/googleplay": { "title": "", "resources": [ - "http://android-developers.blogspot.com/2013/10/more-visibility-for-tablet-apps-in.html", + "https://android-developers.blogspot.com/2013/10/more-visibility-for-tablet-apps-in.html", "google/play/filters.html" ] }, @@ -964,7 +963,7 @@ var RESOURCE_COLLECTIONS = { "title": "", "resources": [ "distribute/essentials/quality/core.html", - "http://android-developers.blogspot.com/2013/10/more-visibility-for-tablet-apps-in.html", + "https://android-developers.blogspot.com/2013/10/more-visibility-for-tablet-apps-in.html", "distribute/tools/launch-checklist.html", "distribute/tools/promote/device-art.html" ] @@ -974,14 +973,14 @@ var RESOURCE_COLLECTIONS = { "resources": [ "design/patterns/notifications.html", "distribute/engage/gcm.html", - "http://play.google.com/about/developer-content-policy.html" + "https://play.google.com/about/developer-content-policy.html" ] }, "distribute/engage/analytics": { "title": "", "resources": [ - "http://www.google.com/analytics/mobile/", - "http://android-developers.blogspot.com/2013/10/improved-app-insight-by-linking-google.html", + "https://www.google.com/analytics/mobile/", + "https://android-developers.blogspot.com/2013/10/improved-app-insight-by-linking-google.html", "https://developers.google.com/analytics/devguides/collection/android/" ] }, @@ -1024,9 +1023,9 @@ var RESOURCE_COLLECTIONS = { "distribute/tools/localization-checklist.html", "https://support.google.com/googleplay/android-developer/table/3541286", "distribute/stories/localization.html", - "distribute/tools/promote/badges.html", + "https://play.google.com/intl/en_us/badges/", "distribute/tools/promote/device-art.html", - "http://www.youtube.com/watch?v=SkHHPf3EdzE" + "https://www.youtube.com/watch?v=SkHHPf3EdzE" ] }, "distribute/engage/gcm": { @@ -1042,7 +1041,7 @@ var RESOURCE_COLLECTIONS = { "https://developers.google.com/games/services/", "distribute/analyze/start.html", "distribute/googleplay/cardboard.html", - "http://www.google.com/admob/" + "https://www.google.com/admob/" ] }, "distribute/engage/gplus": { @@ -1080,9 +1079,9 @@ var RESOURCE_COLLECTIONS = { "distribute/engage/video/more": { "title": "", "resources": [ - "http://www.youtube.com/yt/dev/", + "https://www.youtube.com/yt/dev/", "distribute/essentials/best-practices/games.html", - "http://www.youtube.com/watch?v=RRelFvc6Czo" + "https://www.youtube.com/watch?v=RRelFvc6Czo" ] }, "distribute/engage/community": { @@ -1095,15 +1094,15 @@ var RESOURCE_COLLECTIONS = { "distribute/engage/kiwi": { "title": "", "resources": [ - "http://www.youtube.com/watch?v=WWArLD6nqrk" + "https://www.youtube.com/watch?v=WWArLD6nqrk" ] }, "distribute/toolsreference/gpfefaq": { "title": "", "resources": [ - "http://www.google.com/edu/tablets/", + "https://www.google.com/edu/tablets/", "distribute/googleplay/edu/start.html", - "http://play.google.com/about/developer-distribution-agreement-addendum.html", + "https://play.google.com/about/developer-distribution-agreement-addendum.html", "distribute/essentials/quality/core.html", "distribute/essentials/quality/tablets.html" ] @@ -1123,7 +1122,7 @@ var RESOURCE_COLLECTIONS = { "distribute/tools/loc/designforloc": { "title": "", "resources": [ - "http://android-developers.blogspot.com/2013/03/native-rtl-support-in-android-42.html", + "https://android-developers.blogspot.com/2013/03/native-rtl-support-in-android-42.html", "guide/topics/resources/string-resource.html#Plurals", "guide/topics/resources/string-resource.html", "reference/java/util/Locale.html" @@ -1134,7 +1133,7 @@ var RESOURCE_COLLECTIONS = { "resources": [ "guide/topics/resources/string-resource.html", "design/style/writing.html", - "http://en.wikipedia.org/wiki/XLIFF" + "https://en.wikipedia.org/wiki/XLIFF" ] }, "distribute/toolsreference/localizationchecklist/managestrings/zhcn": { @@ -1142,7 +1141,7 @@ var RESOURCE_COLLECTIONS = { "resources": [ "guide/topics/resources/string-resource.html", "intl/zh-cn/design/style/writing.html", - "http://en.wikipedia.org/wiki/XLIFF" + "https://en.wikipedia.org/wiki/XLIFF" ] }, "distribute/toolsreference/localizationchecklist/translatestrings": { @@ -1154,14 +1153,14 @@ var RESOURCE_COLLECTIONS = { "distribute/toolsreference/localizationchecklist/preplaunch": { "title": "", "resources": [ - "distribute/tools/promote/badges.html", + "https://play.google.com/intl/en_us/badges/", "distribute/tools/promote/device-art.html" ] }, "distribute/toolsreference/localizationchecklist/preplaunch/zhcn": { "title": "", "resources": [ - "intl/zh-cn/distribute/tools/promote/badges.html", + "https://play.google.com/intl/en_us/badges/", "intl/zh-cn/distribute/tools/promote/device-art.html" ] }, @@ -1260,7 +1259,7 @@ var RESOURCE_COLLECTIONS = { "title": "", "resources": [ "https://support.google.com/googleplay/android-developer/answer/1078870", - "http://android-developers.blogspot.com/2011/10/android-market-featured-image.html" + "https://android-developers.blogspot.com/2011/10/android-market-featured-image.html" ] }, "distribute/toolsreference/launchchecklist/productdetails": { @@ -1273,14 +1272,14 @@ var RESOURCE_COLLECTIONS = { "distribute/toolsreference/launchchecklist/badges": { "title": "", "resources": [ - "distribute/tools/promote/badges.html", + "https://play.google.com/intl/en_us/badges/", "distribute/tools/promote/linking.html" ] }, "distribute/toolsreference/launchchecklist/finalchecks": { "title": "", "resources": [ - "http://play.google.com/about/developer-content-policy.html", + "https://play.google.com/about/developer-content-policy.html", "https://support.google.com/googleplay/android-developer/answer/113476", "support.html" ] @@ -1294,9 +1293,6 @@ var RESOURCE_COLLECTIONS = { "distribute/essentials/optimizing-your-app.html" ] }, - - - "distribute/toolsreference/launchchecklist/understanding/zhcn": { "title": "", "resources": [ @@ -1373,7 +1369,7 @@ var RESOURCE_COLLECTIONS = { "title": "", "resources": [ "https://support.google.com/googleplay/android-developer/answer/1078870?hl=zh-Hans", - "http://android-developers.blogspot.com/2011/10/android-market-featured-image.html" + "https://android-developers.blogspot.com/2011/10/android-market-featured-image.html" ] }, "distribute/toolsreference/launchchecklist/productdetails/zhcn": { @@ -1386,14 +1382,14 @@ var RESOURCE_COLLECTIONS = { "distribute/toolsreference/launchchecklist/badges/zhcn": { "title": "", "resources": [ - "intl/zh-cn/distribute/tools/promote/badges.html", + "https://play.google.com/intl/en_us/badges/", "intl/zh-cn/distribute/tools/promote/linking.html" ] }, "distribute/toolsreference/launchchecklist/finalchecks/zhcn": { "title": "", "resources": [ - "http://play.google.com/about/developer-content-policy.html", + "https://play.google.com/about/developer-content-policy.html", "https://support.google.com/googleplay/android-developer/answer/113476?hl=zh-Hans", "support.html" ] @@ -1438,9 +1434,9 @@ var RESOURCE_COLLECTIONS = { "distribute/monetize/advertising": { "title": "", "resources": [ - "http://www.google.com/ads/admob/#subid=us-en-et-dac", - "http://www.google.com/doubleclick/publishers/small-business/index.html", - "http://support.google.com/googleplay/android-developer/topic/2985714", + "https://www.google.com/ads/admob/#subid=us-en-et-dac", + "https://www.google.com/doubleclick/publishers/small-business/index.html", + "https://support.google.com/googleplay/android-developer/topic/2985714", "training/monetization/ads-and-ux.html" ] }, @@ -1448,8 +1444,8 @@ var RESOURCE_COLLECTIONS = { "title": "", "resources": [ "https://support.google.com/admob/topic/2784623", - "http://admob.blogspot.com/", - "http://analyticsacademy.withgoogle.com/mobile-app", + "https://admob.blogspot.com/", + "https://analyticsacademy.withgoogle.com/mobile-app", ] }, "distribute/monetize/paymentmethods": { @@ -1522,19 +1518,55 @@ var RESOURCE_COLLECTIONS = { "distribute/googleplay/auto.html" ] }, + "training/testing/overview": { + "title": "", + "resources": [ + "training/testing/start/index.html", + "tools/testing/testing_android.html", + "https://www.youtube.com/watch?v=vdasFFfXKOY" + ] + }, + "training/testing/tools": { + "title": "", + "resources": [ + "tools/testing-support-library/index.html", + "tools/help/monkey.html", + "tools/help/monkeyrunner_concepts.html", + "tools/testing/testing_otheride.html", + "https://source.android.com/devices/tech/debug/dumpsys.html" + ] + }, + "training/testing/techniques": { + "title": "", + "resources": [ + "training/testing/ui-testing/index.html", + "training/testing/unit-testing/index.html", + "training/testing/performance.html" + ] + }, + "training/testing/resources": { + "title": "", + "resources": [ + "https://github.com/googlesamples/android-testing", + "https://www.youtube.com/watch?v=2I6fuD20qlY", + "https://codelabs.developers.google.com/codelabs/android-testing/index.html", + "https://github.com/googlesamples/android-testing-templates", + "https://google.github.io/android-testing-support-library" + ] + }, "distribute/stories/games": { "title": "", "resources": [ - "http://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_Deerhunter2014_gpgs.pdf", - "http://storage.googleapis.com/androiddevelopers/shareables/stories/ConcreteSoftware_PBABowling_gpgs.pdf", - "http://storage.googleapis.com/androiddevelopers/shareables/stories/Dragonplay_DragonplaySlots_gpgs.pdf", - "http://storage.googleapis.com/androiddevelopers/shareables/stories/Gameloft_Asphalt8_gpgs.pdf", - "http://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_EternityWarriors3_gpgs.pdf", - "http://storage.googleapis.com/androiddevelopers/shareables/stories/HotheadGames_RivalsatWar_gpgs.pdf", - "http://storage.googleapis.com/androiddevelopers/shareables/stories/TMSOFT_Compulsive_gpgs.pdf", - "http://storage.googleapis.com/androiddevelopers/shareables/stories/Noodlecake_SuperStickmanGolf2_gpgs.pdf", - "http://storage.googleapis.com/androiddevelopers/shareables/stories/TinyRebel_DoctorWhoLegacy_gpgs.pdf", - "http://storage.googleapis.com/androiddevelopers/shareables/stories/Senri_LeosFortune_gpgs.pdf" + "https://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_Deerhunter2014_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/ConcreteSoftware_PBABowling_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/Dragonplay_DragonplaySlots_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/Gameloft_Asphalt8_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_EternityWarriors3_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/HotheadGames_RivalsatWar_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/TMSOFT_Compulsive_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/Noodlecake_SuperStickmanGolf2_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/TinyRebel_DoctorWhoLegacy_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/Senri_LeosFortune_gpgs.pdf" ] }, "overview/zhcn/1": { @@ -1560,7 +1592,7 @@ var RESOURCE_COLLECTIONS = { "overview/zhcn/3": { "title": "", "resources": [ - "intl/zh-cn/distribute/tools/promote/badges.html", + "https://play.google.com/intl/en_us/badges/", "intl/zh-cn/distribute/tools/promote/device-art.html", "intl/zh-cn/distribute/tools/promote/linking.html", @@ -1580,9 +1612,9 @@ var RESOURCE_COLLECTIONS = { "overview/carousel/zhcn": { "title": "", "resources": [ - "http://www.youtube.com/watch?v=vGV7FHGzpFU", - "http://www.youtube.com/watch?v=aqc3ZOTzpdk", - "http://www.youtube.com/watch?v=jaNrJ8uyLSc" + "https://www.youtube.com/watch?v=vGV7FHGzpFU", + "https://www.youtube.com/watch?v=aqc3ZOTzpdk", + "https://www.youtube.com/watch?v=jaNrJ8uyLSc" ] }, "overview/1": { @@ -1608,7 +1640,7 @@ var RESOURCE_COLLECTIONS = { "overview/3": { "title": "", "resources": [ - "distribute/tools/promote/badges.html", + "https://play.google.com/intl/en_us/badges/", "distribute/tools/promote/device-art.html", "distribute/tools/promote/linking.html", "distribute/tools/promote/brand.html", @@ -1703,9 +1735,8 @@ var RESOURCE_COLLECTIONS = { ] }, "marshmallow/landing/more": { - "title": "", - "resources": [ - "about/versions/marshmallow/android-6.0-changes.html", + "title": "", + "resources": [ "training/permissions/requesting.html", "training/backup/autosyncapi.html", "training/monitoring-device-state/doze-standby.html", diff --git a/docs/html/jd_extras.js b/docs/html/jd_extras.js index 8e2f040fed51..6c4423e91f17 100644 --- a/docs/html/jd_extras.js +++ b/docs/html/jd_extras.js @@ -68,7 +68,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": [], "tags": [], - "image":"http://i1.ytimg.com/vi/B6ydLpkhq04/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/B6ydLpkhq04/maxresdefault.jpg", "type":"video" }, { @@ -93,7 +93,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "#gpfe", "#googleplay" ], - "image":"http://i1.ytimg.com/vi/Idu7VcTTXfk/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/Idu7VcTTXfk/maxresdefault.jpg", "type":"video" }, { @@ -107,7 +107,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "#gpfe", "#googleplay" ], - "image":"http://i1.ytimg.com/vi/IKhU180eJMo/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/IKhU180eJMo/maxresdefault.jpg", "type":"video" }, { @@ -136,7 +136,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title":"Cast sample apps", "titleFriendly":"", "summary":"Get example Google Cast applications for both senders and receivers.", - "url":"http://www.github.com/googlecast", + "url":"https://www.github.com/googlecast", "group":"", "keywords": ["cast", "samples"], "tags": [], @@ -169,7 +169,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title":"Cardboard design guidelines", "titleFriendly":"", "summary":"Focus on overall usability and avoiding common VR pitfalls while creating an immersive experience of your own.", - "url":"http://www.google.com/design/spec-vr", + "url":"https://www.google.com/design/spec-vr", "group":"", "keywords": ["carboard","vr"], "tags": [], @@ -231,7 +231,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "#gpfe", "#googleplay" ], - "image":"http://i1.ytimg.com/vi/iokH4SAIfRw/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/iokH4SAIfRw/maxresdefault.jpg", "type":"video" }, { @@ -245,7 +245,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "#gpfe", "#googleplay" ], - "image":"http://i1.ytimg.com/vi/Eh2adsAyTKc/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/Eh2adsAyTKc/maxresdefault.jpg", "type":"video" }, { @@ -259,7 +259,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "#gpfe", "#googleplay" ], - "image":"http://i1.ytimg.com/vi/_AZ6UcPz-_g/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/_AZ6UcPz-_g/maxresdefault.jpg", "type":"video" }, { @@ -273,43 +273,43 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "#gpfe", "#googleplay" ], - "image":"http://i1.ytimg.com/vi/iulXz8QTD1g/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/iulXz8QTD1g/maxresdefault.jpg", "type":"video" }, { "title":"DesignBytes: Intro To Material Design", "titleFriendly":"", "summary":"These days, UI designers need to be thinking about phones, tablets, laptops, TVs, smartwatches, and beyond. In this DesignByte we talk about how Google designers have been working on making cross-platform and multi-screen design easier. We wanted to build a design system that felt at home on every screen, from the smallest watch to the largest TV.", - "url":"http://www.youtube.com/watch?v=p4gmvHyuZzw", + "url":"https://www.youtube.com/watch?v=p4gmvHyuZzw", "group":"", "keywords": [], "tags": [ ], - "image":"http://i1.ytimg.com/vi/p4gmvHyuZzw/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/p4gmvHyuZzw/maxresdefault.jpg", "type":"video" }, { "title":"DesignBytes: Paper and Ink: The Materials that Matter", "titleFriendly":"", "summary":"Join Rich Fulcher to learn about the materials of material design. See how virtual paper and ink form the foundation of your tactile user interface and master the rules that govern their behaviour.", - "url":"http://www.youtube.com/watch?v=YaG_ljfzeUw", + "url":"https://www.youtube.com/watch?v=YaG_ljfzeUw", "group":"", "keywords": [], "tags": [ ], - "image":"http://i1.ytimg.com/vi/YaG_ljfzeUw/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/YaG_ljfzeUw/maxresdefault.jpg", "type":"video" }, { "title":"DesignBytes: Material Design in the Google I/O App", "titleFriendly":"", "summary":"Roman Nurik shares details on the design process for the Google I/O 2014 app. To check out the app's source code, visit github.com/google/iosched.", - "url":"http://www.youtube.com/watch?v=XOcCOBe8PTc", + "url":"https://www.youtube.com/watch?v=XOcCOBe8PTc", "group":"", "keywords": [], "tags": [ ], - "image":"http://i1.ytimg.com/vi/XOcCOBe8PTc/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/XOcCOBe8PTc/maxresdefault.jpg", "type":"video" }, { @@ -321,7 +321,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "keywords": [], "tags": [ ], - "image":"http://i1.ytimg.com/vi/kmUGLURRPkI/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/kmUGLURRPkI/maxresdefault.jpg", "type":"video" }, { @@ -333,7 +333,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "keywords": [], "tags": [ ], - "image":"http://i1.ytimg.com/vi/HGElAW224dE/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/HGElAW224dE/maxresdefault.jpg", "type":"video" }, { @@ -345,43 +345,43 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "keywords": [], "tags": [ ], - "image":"http://i1.ytimg.com/vi/zQekzaAgIlQ/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/zQekzaAgIlQ/maxresdefault.jpg", "type":"video" }, { "title":"Battery Drain and Networking", "titleFriendly":"", "summary":"Let’s take a moment to make something insanely clear: As far as battery is concerned, NETWORKING is the biggest, baddest, dirtiest offender there is. And optimizing performance here isn’t easy. Since the chip isn’t always awake and draining power, means you can optimize how it wakes up, sends traffic, and saves battery.", - "url":"http://www.youtube.com/watch?v=fEEulSk1kNY", + "url":"https://www.youtube.com/watch?v=fEEulSk1kNY", "group":"", "keywords": [], "tags": [ ], - "image":"http://i1.ytimg.com/vi/fEEulSk1kNY/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/fEEulSk1kNY/maxresdefault.jpg", "type":"video" }, { "title":"Batching Background Work Until Later", "titleFriendly":"", "summary":"Yes, your app is special. But when it comes to battery use, sometimes it’s better to be part of the crowd. Why not spread the battery blame around a bit? Ian Ni-Lewis shows you how ridiculously easy it is to go from battery hog to team player in this video.", - "url":"http://www.youtube.com/watch?v=-3ry8PxcJJA", + "url":"https://www.youtube.com/watch?v=-3ry8PxcJJA", "group":"", "keywords": [], "tags": [ ], - "image":"http://i1.ytimg.com/vi/-3ry8PxcJJA/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/-3ry8PxcJJA/maxresdefault.jpg", "type":"video" }, { "title":"The Performance Lifecycle", "titleFriendly":"", "summary":"Performance problems surface in your application at the least-wanted times (like right before you’re about to ship your first build). But don’t freak out: There’s a simple process that you can follow to help get your performance back under control.", - "url":"http://www.youtube.com/watch?v=_kKTGK-Cb_4", + "url":"https://www.youtube.com/watch?v=_kKTGK-Cb_4", "group":"", "keywords": [], "tags": [ ], - "image":"http://i1.ytimg.com/vi/_kKTGK-Cb_4/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/_kKTGK-Cb_4/maxresdefault.jpg", "type":"video" }, { @@ -393,7 +393,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "keywords": ["studio", "tools"], "tags": [ ], - "image":"http://i1.ytimg.com/vi/K2dodTXARqc/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/K2dodTXARqc/maxresdefault.jpg", "type":"video" }, @@ -406,7 +406,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "keywords": ["google play services"], "tags": [ ], - "image":"http://i1.ytimg.com/vi/M3Udfu6qidk/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/M3Udfu6qidk/maxresdefault.jpg", "type":"video" }, { @@ -418,7 +418,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "keywords": ["google play services"], "tags": [ ], - "image":"http://i1.ytimg.com/vi/FOn64iqlphk/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/FOn64iqlphk/maxresdefault.jpg", "type":"video" }, { @@ -430,7 +430,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "keywords": ["google play services"], "tags": [ ], - "image":"http://i1.ytimg.com/vi/fvtMtfCuEpw/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/fvtMtfCuEpw/maxresdefault.jpg", "type":"video" }, { @@ -442,19 +442,19 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "keywords": ["google play services"], "tags": [ ], - "image":"http://i1.ytimg.com/vi/F0Kh_RnSM0w/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/F0Kh_RnSM0w/maxresdefault.jpg", "type":"video" }, { "title":"Running a Successful Games Business with Google", "titleFriendly":"", "summary":"Sure, we all want to make the next great gaming masterpiece. But we also want to feed our families and/or dogs. Join Bob Meese from the Google Play team as he gives you some key pointers on how to make sure you're best taking advantage of Google Play and running a successful games business.", - "url":"http://www.youtube.com/watch?v=tDmnGNkTtlE", + "url":"https://www.youtube.com/watch?v=tDmnGNkTtlE", "group":"", "keywords": [], "tags": [ ], - "image":"http://i1.ytimg.com/vi/tDmnGNkTtlE/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/tDmnGNkTtlE/maxresdefault.jpg", "type":"video" }, { @@ -466,7 +466,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "keywords": ["tv"], "tags": [ ], - "image":"http://i1.ytimg.com/vi/6K_jxccHv5M/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/6K_jxccHv5M/maxresdefault.jpg", "type":"video" }, { @@ -478,10 +478,94 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "keywords": ["auto"], "tags": [ ], - "image":"http://i1.ytimg.com/vi/ctiaVxgclsg/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/ctiaVxgclsg/maxresdefault.jpg", "type":"video" }, { + "title":"Debugging and testing in Android Studio", + "titleFriendly":"", + "summary":"This video introduces the state of unit testing support in Studio and Google’s new Android Testing Support Library for functional UI testing and running instrumented tests on a device.", + "url":"https://www.youtube.com/watch?v=2I6fuD20qlY", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/2I6fuD20qlY/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Android Testing (Android Dev Summit 2015)", + "titleFriendly":"", + "summary":"Overview of the testing tools and frameworks provided by Google and how they can help you to iterate more quickly and maintain a more healthy codebase.", + "url":"https://www.youtube.com/watch?v=vdasFFfXKOY", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/vdasFFfXKOY/maxresdefault.jpg", + "type":"video" + }, + { + "title":"dumpsys", + "titleFriendly":"", + "summary":"A tool that runs on the device and provides information about the status of system services.", + "url":"https://source.android.com/devices/tech/debug/dumpsys.html", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"", + "type":"google" + }, + { + "title":"Android Testing Samples", + "titleFriendly":"", + "summary":"A collection of samples demonstrating different frameworks and techniques for automated testing.", + "url":"https://github.com/googlesamples/android-testing", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"images/testing/testing-icon.png", + "type":"Samples" + }, + { + "title":"Android Testing Templates", + "titleFriendly":"", + "summary":"A collection of Google's Android testing tools and frameworks, all integrated in a single application project.", + "url":"https://github.com/googlesamples/android-testing-templates", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"images/testing/testing-icon.png", + "type":"Samples" + }, + { + "title":"Android Testing Support Library (GitHub)", + "titleFriendly":"", + "summary":"A resource page on GitHub for the Android Testing Support Library.", + "url":"https://google.github.io/android-testing-support-library", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"images/testing/testing-icon.png", + "type":"Samples" + }, + { + "title":"Android Testing Codelab", + "titleFriendly":"", + "summary":"This codelab shows how to build an Android app from the ground up in Android Studio, using a Model View Presenter architecture, Unit Tests and Instrumentation Tests.", + "url":"https://codelabs.developers.google.com/codelabs/android-testing/index.html", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"images/testing/testing-icon.png", + "type":"google" + }, + { "title":"Developer Registration", "titleFriendly":"", "summary":"Additional information about the registration process.", @@ -558,7 +642,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": [], "tags": [], - "image":"http://storage.googleapis.com/support-kms-prod/SNP_712EA2784949DDF085C46E3BE7B1DC618A09_4389397_en_v0", + "image":"https://storage.googleapis.com/support-kms-prod/SNP_712EA2784949DDF085C46E3BE7B1DC618A09_4389397_en_v0", "type":"google" }, { @@ -569,7 +653,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": [], "tags": [], - "image":"http://storage.googleapis.com/support-kms-prod/SNP_712EA2784949DDF085C46E3BE7B1DC618A09_4389397_en_v0", + "image":"https://storage.googleapis.com/support-kms-prod/SNP_712EA2784949DDF085C46E3BE7B1DC618A09_4389397_en_v0", "type":"google" }, { @@ -598,7 +682,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title":"Google for Education", "titleFriendly":"", "summary":"Find out more about how Google can support your work with apps and tablets.", - "url":"http://www.google.com/edu/tablets/", + "url":"https://www.google.com/edu/tablets/", "group":"", "keywords": [], "tags": [], @@ -653,7 +737,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title":"Monetize your apps intelligently", "titleFriendly":"", "summary":"Generate revenue from your free games with ads tailored to match your game's look and feel.", - "url":"http://www.google.com/admob/", + "url":"https://www.google.com/admob/", "group":"", "keywords": ["AdMob"], "tags": [], @@ -666,7 +750,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [ "versions", "blog", "googleplay" ], - "url": "http://android-developers.blogspot.com/", + "url": "https://android-developers.blogspot.com/", "timestamp": 1004884220000, "image": "images/blog.jpg", "title": "Android Developers Blog", @@ -679,7 +763,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://android-developers.blogspot.com/2011/11/making-android-games-that-play-nice.html", + "url": "https://android-developers.blogspot.com/2011/11/making-android-games-that-play-nice.html", "timestamp": 1194884220000, "image": null, "title": "Making Android Apps that Play Nice", @@ -692,7 +776,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html", + "url": "https://android-developers.blogspot.com/2010/07/multithreading-for-performance.html", "timestamp": 1194884220000, "image": null, "title": "Multithreading for Performance", @@ -705,7 +789,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://play.google.com/about/developer-content-policy.html", + "url": "https://play.google.com/about/developer-content-policy.html", "timestamp": 1194884220000, "image": "images/play_dev.jpg", "title": "Developer Program Policies", @@ -757,7 +841,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://android-developers.blogspot.com/2011/10/android-market-featured-image.html", + "url": "https://android-developers.blogspot.com/2011/10/android-market-featured-image.html", "timestamp": 1194884220000, "image": "images/play_dev.jpg", "title": "Google Play Featured Image Guidelines", @@ -939,9 +1023,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://youtu.be/SkHHPf3EdzE", + "url": "https://youtu.be/SkHHPf3EdzE", "timestamp": 1194884220000, - "image": "http://i1.ytimg.com/vi/SkHHPf3EdzE/maxresdefault.jpg", + "image": "https://i1.ytimg.com/vi/SkHHPf3EdzE/maxresdefault.jpg", "title": "Level Up Your Android Game", "summary": "Learn how to take your game to the next level on Google Play.", "keywords": [], @@ -965,7 +1049,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://play.google.com/about/developer-distribution-agreement.html", + "url": "https://play.google.com/about/developer-distribution-agreement.html", "timestamp": 1194884220000, "image": "images/play_dev.jpg", "title": "Developer Distribution Agreement", @@ -1004,7 +1088,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://play.google.com/about/developer-distribution-agreement-addendum.html", + "url": "https://play.google.com/about/developer-distribution-agreement-addendum.html", "timestamp": 1194884220000, "image": "images/play_dev.jpg", "title": "Google Play for Education Addendum", @@ -1017,7 +1101,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://android-developers.blogspot.com/2013/03/native-rtl-support-in-android-42.html", + "url": "https://android-developers.blogspot.com/2013/03/native-rtl-support-in-android-42.html", "timestamp": null, "image": null, "title": "Native RTL Support in Android 4.2", @@ -1177,7 +1261,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["android","dashboard","platforms","versions"], "tags": ["#ecosystem","#versions","#whatsnew"], - "image":"http://chart.googleapis.com/chart?chl=GL%201.1%20only%7CGL%202.0%7CGL%203.0&chf=bg%2Cs%2C00000000&chd=t%3A0.1%2C93.5%2C6.4&chco=c4df9b%2C6fad0c&chs=400x250&cht=p", + "image":"https://chart.googleapis.com/chart?chl=GL%201.1%20only%7CGL%202.0%7CGL%203.0&chf=bg%2Cs%2C00000000&chd=t%3A0.1%2C93.5%2C6.4&chco=c4df9b%2C6fad0c&chs=400x250&cht=p", "lang":"en", "type":"about" }, @@ -1396,9 +1480,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "#gpfe", "#googleplay" ], - "url": "http://youtu.be/vzvpcEffvaE", + "url": "https://youtu.be/vzvpcEffvaE", "timestamp": 1383243492000, - "image": "http://i1.ytimg.com/vi/vzvpcEffvaE/maxresdefault.jpg", + "image": "https://i1.ytimg.com/vi/vzvpcEffvaE/maxresdefault.jpg", "title": "Introducing Tablets with Google Play for Education", "summary": "Schools in Hillsborough, New Jersey were among the first to try out Nexus 7 tablets with Google Play for Education. See the difference it made for students, teachers, and administrators.", "keywords": [], @@ -1411,9 +1495,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [ "#engagement", ], - "url": "http://www.youtube.com/yt/dev/", + "url": "https://www.youtube.com/yt/dev/", "timestamp": 1383243492000, - "image": "http://www.youtube.com/yt/dev/media/images/yt-dev-home-hero.jpg", + "image": "https://www.youtube.com/yt/dev/media/images/yt-dev-home-hero.jpg", "title": "YouTube for Developers", "summary": "The YouTube APIs and Tools enable you to integrate YouTube's video content and functionality into your website, app, or device.", "keywords": [], @@ -1426,7 +1510,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [ "#engagement", ], - "url": "http://www.google.com/analytics/mobile/", + "url": "https://www.google.com/analytics/mobile/", "timestamp": 1383243492000, "image": "images/cards/analytics-mobile_2x.jpg", "title": "Mobile App Analytics", @@ -1443,9 +1527,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [ "#gcm", ], - "url": "http://www.youtube.com/watch?v=y76rjidm8cU", + "url": "https://www.youtube.com/watch?v=y76rjidm8cU", "timestamp": 1383243492000, - "image": "http://1.bp.blogspot.com/-IF-1-1kA0sg/UYwTidxdi3I/AAAAAAAAAEU/ellLeQ-E1vs/s800/google-io-lockup-2.png", + "image": "https://1.bp.blogspot.com/-IF-1-1kA0sg/UYwTidxdi3I/AAAAAAAAAEU/ellLeQ-E1vs/s800/google-io-lockup-2.png", "title": "Google Cloud Messaging at I/O 2013", "summary": "Google Cloud Messaging allows your services to efficiently send data to applications on Android devices. See what's new, and learn how to use GCM to make your apps more efficient.", "keywords": ["gcm"], @@ -1458,7 +1542,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [ "#gcm", ], - "url": "http://developer.chrome.com/apps/cloudMessagingV2", + "url": "https://developer.chrome.com/apps/cloudMessagingV2", "timestamp": 1383243492000, "image": "images/kk-chromium-icon.png", "title": "Google Cloud Messaging for Chrome", @@ -1474,7 +1558,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [ "#sdkupdates" ], - "url": "http://android-developers.blogspot.com/2013/07/making-beautiful-android-app-icons.html", + "url": "https://android-developers.blogspot.com/2013/07/making-beautiful-android-app-icons.html", "timestamp": 1194884220000, "image": null, "title": "Make Beautiful Android App Icons", @@ -1489,7 +1573,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [ "#sdkupdates" ], - "url": "http://android-developers.blogspot.com/2012/12/localize-your-promotional-graphics-on.html", + "url": "https://android-developers.blogspot.com/2012/12/localize-your-promotional-graphics-on.html", "timestamp": 1194884220000, "image": null, "title": "Localize Your Promotional Graphics", @@ -1504,7 +1588,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [ "#sdkupdates" ], - "url": "http://android-developers.blogspot.com/2013/10/making-your-app-content-more-accessible.html", + "url": "https://android-developers.blogspot.com/2013/10/making-your-app-content-more-accessible.html", "timestamp": 1194884220000, "image": null, "title": "Make your App Content more Accessible with App Linking", @@ -1595,7 +1679,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://en.wikipedia.org/wiki/XLIFF", + "url": "https://en.wikipedia.org/wiki/XLIFF", "timestamp": 1194884220000, "image": null, "title": "XML Localisation Interchange File Format (XLIFF)", @@ -1660,7 +1744,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://android-developers.blogspot.com/2013/11/bring-your-apps-into-classroom-with.html", + "url": "https://android-developers.blogspot.com/2013/11/bring-your-apps-into-classroom-with.html", "timestamp": null, "image": "distribute/images/gp-edu-apps-image.jpg", "title": "Google play for education", @@ -1699,7 +1783,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": ["games", "localization", "quality"], - "url": "http://www.youtube.com/watch?v=SkHHPf3EdzE", + "url": "https://www.youtube.com/watch?v=SkHHPf3EdzE", "timestamp": null, "image": "https://developers.google.com/apps/images/io_2013/google-io-logo.png", "title": "Level Up Your Android Game", @@ -1738,9 +1822,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": ["monetize", "ads"], - "url": "http://www.google.com/doubleclick/publishers/small-business/index.html", + "url": "https://www.google.com/doubleclick/publishers/small-business/index.html", "timestamp": null, - "image": "http://www.google.com/doubleclick/publishers/small-business/images/define_ad.png", + "image": "https://www.google.com/doubleclick/publishers/small-business/images/define_ad.png", "title": "DoubleClick for Publishers", "summary": "A free ad management solution that helps growing publishers sell, schedule, deliver, and measure all of their digital ad inventory.", "keywords": ["ads"], @@ -1751,7 +1835,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": ["monetize", "ads"], - "url": "http://support.google.com/googleplay/android-developer/topic/2985714", + "url": "https://support.google.com/googleplay/android-developer/topic/2985714", "timestamp": null, "image":"images/play_dev.jpg", "title": "Policy Center: Ads", @@ -1777,7 +1861,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://admob.blogspot.com/", + "url": "https://admob.blogspot.com/", "timestamp": null, "image": "images/cards/analytics-mobile_2x.jpg", "title": "Inside Admob", @@ -1842,7 +1926,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": ["plus", "social"], - "url": "http://plus.google.com/+GooglePlay", + "url": "https://plus.google.com/+GooglePlay", "timestamp": null, "image": "https://lh4.googleusercontent.com/-IKezweZlcXI/AAAAAAAAAAI/AAAAAAABOvg/uK8Z0jekVE4/s120-c/photo.jpg", "title": "+Google Play", @@ -1883,7 +1967,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [], "url": "https://developers.google.com/edu/guidelines", "timestamp": null, - "image": "http://developer.android.com/distribute/images/edu-guidelines.jpg", + "image": "https://developer.android.com/distribute/images/edu-guidelines.jpg", "title": "Education Guidelines", "summary": "These guidelines and requirements help you develop great apps for students, which offer compelling content and an intuitive user experience on Android tablets.", "keywords": [], @@ -1896,7 +1980,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [], "url": "https://developers.google.com/edu/guidelines?hl=zh-Hans", "timestamp": null, - "image": "http://developer.android.com/distribute/images/edu-guidelines.jpg", + "image": "https://developer.android.com/distribute/images/edu-guidelines.jpg", "title": "Education Guidelines", "summary": "These guidelines and requirements help you develop great apps for students, which offer compelling content and an intuitive user experience on Android tablets.", "keywords": [], @@ -1909,7 +1993,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [], "url": "https://developers.google.com/edu/faq", "timestamp": null, - "image": "http://developer.android.com/distribute/images/gpfe-faq.jpg", + "image": "https://developer.android.com/distribute/images/gpfe-faq.jpg", "title": "Education FAQ", "summary": "Answers to common questions you might have about Google Play for Education.", "keywords": [], @@ -1946,9 +2030,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_Deerhunter2014_gpgs.pdf", + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_Deerhunter2014_gpgs.pdf", "timestamp": null, - "image": "http://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_Deerhunter2014_gpgs.png", + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_Deerhunter2014_gpgs.png", "title": "Deer Hunter 2014 by Glu — Sign-in", "summary": "Glu finds that Google Play Game Services helps improve the user experience which leads to increased player happiness. They also find that Play Games Services signed in users tend to play longer and have a higher lifetime value.", "keywords": ["stories"], @@ -1959,9 +2043,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://storage.googleapis.com/androiddevelopers/shareables/stories/ConcreteSoftware_PBABowling_gpgs.pdf", + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/ConcreteSoftware_PBABowling_gpgs.pdf", "timestamp": null, - "image": "http://storage.googleapis.com/androiddevelopers/shareables/stories/ConcreteSoftware_PBABowling_gpgs.png", + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/ConcreteSoftware_PBABowling_gpgs.png", "title": "PBA® Bowling Challenge by Concrete Software — Quests", "summary": "Concrete Software finds that Google Play Game Services' quests are a great way to create new content for users that leads to higher engagement.", "keywords": ["stories"], @@ -1972,9 +2056,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://storage.googleapis.com/androiddevelopers/shareables/stories/Dragonplay_DragonplaySlots_gpgs.pdf", + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Dragonplay_DragonplaySlots_gpgs.pdf", "timestamp": null, - "image": "http://storage.googleapis.com/androiddevelopers/shareables/stories/Dragonplay_DragonplaySlots_gpgs.png", + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Dragonplay_DragonplaySlots_gpgs.png", "title": "Dragonplay Slots by Dragonplay — Sign-in", "summary": "Dragonplay finds that players who sign in with Google Play Games services tend to be high quality users who were highly engaged. They also tend to be easier to convert to paying users.", "keywords": ["stories"], @@ -1985,9 +2069,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://storage.googleapis.com/androiddevelopers/shareables/stories/Gameloft_Asphalt8_gpgs.pdf", + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Gameloft_Asphalt8_gpgs.pdf", "timestamp": null, - "image": "http://storage.googleapis.com/androiddevelopers/shareables/stories/Gameloft_Asphalt8_gpgs.png", + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Gameloft_Asphalt8_gpgs.png", "title": "Asphalt 8 by Gameloft — Friends invitations", "summary": "Gameloft finds that Google Play Game Services users are more engaged than the average Android user and more likely to convert to paying players.", "keywords": ["stories"], @@ -1998,9 +2082,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_EternityWarriors3_gpgs.pdf", + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_EternityWarriors3_gpgs.pdf", "timestamp": null, - "image": "http://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_EternityWarriors3_gpgs.png", + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_EternityWarriors3_gpgs.png", "title": "Eternity Warriors 3 by Glu — Gifting", "summary": "Glu finds that Google Play Game Services gifting outperforms other implementations (including those with incentives) because of its seamless flow and consistent performance.", "keywords": ["stories"], @@ -2011,9 +2095,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://storage.googleapis.com/androiddevelopers/shareables/stories/HotheadGames_RivalsatWar_gpgs.pdf", + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/HotheadGames_RivalsatWar_gpgs.pdf", "timestamp": null, - "image": "http://storage.googleapis.com/androiddevelopers/shareables/stories/HotheadGames_RivalsatWar_gpgs.jpg", + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/HotheadGames_RivalsatWar_gpgs.jpg", "title": "Rivals at War: Firefight by Hothead Games — Leaderboards", "summary": "Hothead Games is planning to include Google Play Game Services features in all their games going forwards after seeing that players that signed in with Play Games Services tend to show higher retention and a higher average revenue.", "keywords": ["stories"], @@ -2024,9 +2108,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://storage.googleapis.com/androiddevelopers/shareables/stories/TMSOFT_Compulsive_gpgs.pdf", + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/TMSOFT_Compulsive_gpgs.pdf", "timestamp": null, - "image": "http://storage.googleapis.com/androiddevelopers/shareables/stories/TMSOFT_Compulsive_gpgs.png", + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/TMSOFT_Compulsive_gpgs.png", "title": "Compulsive by TMSOFT — Cross-platform", "summary": "TMSOFT finds that users who authenticate with Play Games Services on Android and iOS play Compulsive twice as much and purchase in-app products over four times as much.", "keywords": ["stories"], @@ -2037,9 +2121,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://storage.googleapis.com/androiddevelopers/shareables/stories/Noodlecake_SuperStickmanGolf2_gpgs.pdf", + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Noodlecake_SuperStickmanGolf2_gpgs.pdf", "timestamp": null, - "image": "http://storage.googleapis.com/androiddevelopers/shareables/stories/Noodlecake_SuperStickmanGolf2_gpgs.png", + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Noodlecake_SuperStickmanGolf2_gpgs.png", "title": "Super Stickman Golf 2 by Noodlecake Studios — Multiplayer", "summary": "Noodlecake Studios finds that Google Play Game Services’ multiplayer feature helps reduce attrition.", "keywords": ["stories"], @@ -2050,9 +2134,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://storage.googleapis.com/androiddevelopers/shareables/stories/TinyRebel_DoctorWhoLegacy_gpgs.pdf", + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/TinyRebel_DoctorWhoLegacy_gpgs.pdf", "timestamp": null, - "image": "http://storage.googleapis.com/androiddevelopers/shareables/stories/TinyRebelGames_DrWhoLegacy_pgps.png", + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/TinyRebelGames_DrWhoLegacy_pgps.png", "title": "Dr. Doctor Who: Legacy by Tiny Rebel Games — Achievements", "summary": "After integrating achievements and cloud services from Google Play Game Services, Tiny Rebel Games saw a dramatic increase in daily revenues as a result of an increase in daily installs and an increase in the average revenue per install.", "keywords": ["stories"], @@ -2063,9 +2147,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://storage.googleapis.com/androiddevelopers/shareables/stories/Senri_LeosFortune_gpgs.pdf", + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Senri_LeosFortune_gpgs.pdf", "timestamp": null, - "image": "http://storage.googleapis.com/androiddevelopers/shareables/stories/Senri_LeosFortune_gpgs.png", + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Senri_LeosFortune_gpgs.png", "title": "Leo’s Fortune by 1337 & Senri — Saved games", "summary": "1337 + Senri finds that Google Play Game Services is easy to integrate and provides essential game functions like cloud saved games, achievements and leaderboards which have a very large adoption rate amongst players.", "keywords": ["stories"], @@ -2141,9 +2225,9 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://www.google.com/tagmanager/", + "url": "https://www.google.com/tagmanager/", "timestamp": null, - "image": "http://www.google.com/tagmanager/images/gtm-hero-illustration-small.png", + "image": "https://www.google.com/tagmanager/images/gtm-hero-illustration-small.png", "title": "Google Tag Manager", "summary": "Google Tag Manager enables you to change configuration values in your mobile apps using the Google Tag Manager interface, without having to rebuild and resubmit application binaries to app marketplaces.", "keywords": ["analytics", "tagmanager"], @@ -2338,7 +2422,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [], "url": "https://support.google.com/tagmanager/answer/6003007", "timestamp": null, - "image": "http://www.google.com/tagmanager/images/gtm-hero-illustration-small.png", + "image": "https://www.google.com/tagmanager/images/gtm-hero-illustration-small.png", "title": "In-App A/B Testing", "summary": "With content experiments in Google Tag Manager you can test multiple variations of your app to find which works best.", "keywords": ["tagmanager"], @@ -2664,7 +2748,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "lang": "en", "group": "", "tags": [], - "url": "http://analyticsacademy.withgoogle.com/mobile-app", + "url": "https://analyticsacademy.withgoogle.com/mobile-app", "timestamp": null, "image": "distribute/images/advertising.jpg", "title": "Analytics Academy for Mobile Apps", @@ -3024,7 +3108,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["wear", "wearable", "watch face"], "tags": [], - "image":"http://i1.ytimg.com/vi/AK38PJZmIW8/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/AK38PJZmIW8/maxresdefault.jpg", "lang":"en", "type":"video" }, @@ -3036,7 +3120,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["support", "compatibility"], "tags": [], - "image":"http://i1.ytimg.com/vi/3PIc-DuEU2s/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/3PIc-DuEU2s/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3048,7 +3132,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["support", "compatibility","design-code"], "tags": [], - "image":"http://i1.ytimg.com/vi/5Be2mJzP-Uw/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/5Be2mJzP-Uw/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3060,7 +3144,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["tools", "studio","gradle"], "tags": [], - "image":"http://i1.ytimg.com/vi/cD7NPxuuXYY/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/cD7NPxuuXYY/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3072,7 +3156,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["tools", "studio","layout"], "tags": [], - "image":"http://i1.ytimg.com/vi/JLLnhwtDoHw/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/JLLnhwtDoHw/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3084,22 +3168,11 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["tools", "studio","debugging","profiling","performance"], "tags": [], - "image":"http://i1.ytimg.com/vi/2I6fuD20qlY/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/2I6fuD20qlY/maxresdefault.jpg", "lang":"en", "type":"Video" }, { - "tags": [ - "android", - "developerstory", - "googleplay", - "featured" - ], - "title": "Android Developer Story: Jelly Button Games — Growing globally through data driven development", - "type": "youtube", - "url": "http://www.youtube.com/watch?v=Pd49vTkvu0U" - }, - { "title":"Scale with Google Cloud Platform", "titleFriendly":"", "summary":"Build, test, and deploy applications on Google's highly-scalable and reliable infrastructure for your web, mobile and backend solutions.", @@ -3127,7 +3200,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title":"Android for Work", "titleFriendly":"", "summary":"Learn more about how Android for Work makes your favorite phones and tablets the perfect business tools.", - "url":"http://www.android.com/work/", + "url":"https://www.android.com/work/", "group":"", "keywords": ["work", "enterprise", "emm"], "tags": [], @@ -3143,7 +3216,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["work", "enterprise", "emm"], "tags": [], - "image":"http://i1.ytimg.com/vi/jQWB_-o1kz4/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/jQWB_-o1kz4/maxresdefault.jpg", "lang":"en", "type":"youtube" }, @@ -3155,7 +3228,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["work", "enterprise", "emm"], "tags": [], - "image":"http://i1.ytimg.com/vi/39NkpWkaH8M/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/39NkpWkaH8M/maxresdefault.jpg", "lang":"en", "type":"youtube" }, @@ -3167,7 +3240,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["work", "enterprise", "emm"], "tags": [], - "image":"http://i1.ytimg.com/vi/dH41OutAMNM/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/dH41OutAMNM/maxresdefault.jpg", "lang":"en", "type":"youtube" }, @@ -3179,7 +3252,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["work", "enterprise", "emm"], "tags": [], - "image":"http://i1.ytimg.com/vi/j3QC6hcpy90/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/j3QC6hcpy90/maxresdefault.jpg", "lang":"en", "type":"youtube" }, @@ -3215,7 +3288,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/yYU4DHLwoRk/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/yYU4DHLwoRk/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3227,7 +3300,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/ndBdf1_oOGA/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/ndBdf1_oOGA/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3239,7 +3312,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/VOn7VrTRlA4/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/VOn7VrTRlA4/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3251,7 +3324,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/OW1A4XFRuyc/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/OW1A4XFRuyc/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3263,7 +3336,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/HXacyy0HSW0/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/HXacyy0HSW0/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3275,7 +3348,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/vcSj8ln-BlE/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/vcSj8ln-BlE/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3287,7 +3360,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/j3QC6hcpy90/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/j3QC6hcpy90/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3299,7 +3372,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/C8lUdPVSzDk/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/C8lUdPVSzDk/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3311,7 +3384,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/N72ksDKrX6c/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/N72ksDKrX6c/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3323,7 +3396,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/U9tw5ypqEN0/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/U9tw5ypqEN0/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3335,7 +3408,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/iZqDdvhTZj0/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/iZqDdvhTZj0/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3347,7 +3420,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/5sCQjeGoE7M/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/5sCQjeGoE7M/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3359,7 +3432,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/LQoohRwojmw/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/LQoohRwojmw/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3371,7 +3444,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group":"", "keywords": ["Marshmallow"], "tags": [], - "image":"http://i1.ytimg.com/vi/f17qe9vZ8RM/maxresdefault.jpg", + "image":"https://i1.ytimg.com/vi/f17qe9vZ8RM/maxresdefault.jpg", "lang":"en", "type":"Video" }, @@ -3384,7 +3457,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group": "", "keywords": [], "tags": [], - "image": "http://img.youtube.com/vi/xelYnWcYkuE/hqdefault.jpg", + "image": "https://img.youtube.com/vi/xelYnWcYkuE/hqdefault.jpg", "type": "youtube" }, { @@ -3396,7 +3469,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group": "", "keywords": [], "tags": [], - "image": "http://img.youtube.com/vi/lJdjY3z6-LY/hqdefault.jpg", + "image": "https://img.youtube.com/vi/lJdjY3z6-LY/hqdefault.jpg", "type": "youtube" }, { @@ -3404,11 +3477,11 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title": "Android Wear 関連の動画に日本語字幕が付きました", "titleFriendly": "", "summary": "", - "url": "http://googledevjp.blogspot.jp/2014/12/android-wear.html", + "url": "https://googledevjp.blogspot.jp/2014/12/android-wear.html", "group": "", "keywords": [], "tags": [], - "image": "http://i1.ytimg.com/vi/4JcDYkgqksY/maxresdefault.jpg", + "image": "https://i1.ytimg.com/vi/4JcDYkgqksY/maxresdefault.jpg", "type": "blog" }, { @@ -3416,11 +3489,11 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title": "Android Studio 1.0 をリリースしました", "titleFriendly": "", "summary": "", - "url": "http://googledevjp.blogspot.jp/2014/12/android-studio-10.html", + "url": "https://googledevjp.blogspot.jp/2014/12/android-studio-10.html", "group": "", "keywords": [], "tags": [], - "image": "http://3.bp.blogspot.com/-1hV3sD1At74/VIaQSWBasUI/AAAAAAAABAU/9vYLJMsmMuQ/s1600/studio-logo.png", + "image": "https://3.bp.blogspot.com/-1hV3sD1At74/VIaQSWBasUI/AAAAAAAABAU/9vYLJMsmMuQ/s1600/studio-logo.png", "type": "blog" }, { @@ -3428,11 +3501,11 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title": "Google Play 開発者サービス 6.5 のご紹介", "titleFriendly": "", "summary": "", - "url": "http://googledevjp.blogspot.jp/2014/12/google-play-65.html", + "url": "https://googledevjp.blogspot.jp/2014/12/google-play-65.html", "group": "", "keywords": [], "tags": [], - "image": "http://1.bp.blogspot.com/-4BNREC0Jojo/VGo7ahW35wI/AAAAAAAABAc/9thZl94F6fY/s1600/GMS%2B-%2BRelease%2BBlog%2BNacho%2B-%2BMap%2BToolbar.png", + "image": "https://1.bp.blogspot.com/-4BNREC0Jojo/VGo7ahW35wI/AAAAAAAABAc/9thZl94F6fY/s1600/GMS%2B-%2BRelease%2BBlog%2BNacho%2B-%2BMap%2BToolbar.png", "type": "blog" }, { @@ -3476,7 +3549,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title": "Google Play アプリ ポリシー センター", "titleFriendly": "", "summary": "", - "url": "http://support.google.com/googleplay/android-developer/answer/4430948?hl=ja", + "url": "https://support.google.com/googleplay/android-developer/answer/4430948?hl=ja", "group": "", "keywords": [], "tags": [], @@ -3512,11 +3585,11 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title": "Google Cloud Platform が支える、新感覚リアルタイム RPG ユニゾンリーグ - 株式会社エイチームの GCP 導入事例", "titleFriendly": "", "summary": "スケーラブルなバックエンドを実現する Google Cloud Platform の最新導入事例。", - "url": "http://googleforwork-japan.blogspot.jp/2014/12/gcp-google-cloud-platform-rpg-gcp.html", + "url": "https://googleforwork-japan.blogspot.jp/2014/12/gcp-google-cloud-platform-rpg-gcp.html", "group": "", "keywords": [], "tags": [], - "image": "http://3.bp.blogspot.com/-xp7KoPkbne4/VI_PfoFil3I/AAAAAAAAA3U/-k1UZ0zjCBc/s1600/unison-league.jpeg", + "image": "https://3.bp.blogspot.com/-xp7KoPkbne4/VI_PfoFil3I/AAAAAAAAA3U/-k1UZ0zjCBc/s1600/unison-league.jpeg", "type": "distribute" }, { @@ -3540,7 +3613,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group": "", "keywords": [], "tags": [], - "image": "http://img.youtube.com/vi/7X9Ue0Nfdh4/hqdefault.jpg", + "image": "https://img.youtube.com/vi/7X9Ue0Nfdh4/hqdefault.jpg", "type": "youtube" }, { @@ -3552,7 +3625,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "group": "", "keywords": [], "tags": [], - "image": "http://img.youtube.com/vi/83FpwuschCQ/hqdefault.jpg", + "image": "https://img.youtube.com/vi/83FpwuschCQ/hqdefault.jpg", "type": "youtube" }, { @@ -3560,7 +3633,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title": "안드로이드 5.0 롤리팝을 맞이하는 개발자를 위한 안내서", "titleFriendly": "", "summary": "", - "url": "http://googledevkr.blogspot.com/2014/11/android50guidefordevelopers.html", + "url": "https://googledevkr.blogspot.com/2014/11/android50guidefordevelopers.html", "group": "", "keywords": [], "tags": [], @@ -3572,7 +3645,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title": "안드로이드 앱을 위한 머티리얼 디자인 체크 리스트", "titleFriendly": "", "summary": "", - "url": "http://googledevkr.blogspot.com/2014/10/material-design-on-android-checklist.html", + "url": "https://googledevkr.blogspot.com/2014/10/material-design-on-android-checklist.html", "group": "", "keywords": [], "tags": [], @@ -3584,11 +3657,11 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "title": "App Compat 라이브러리", "titleFriendly": "", "summary": "", - "url": "http://googledevkr.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html", + "url": "https://googledevkr.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html", "group": "", "keywords": [], "tags": [], - "image": "http://2.bp.blogspot.com/-7fF9ayZ6PgI/U9iFpk5FNEI/AAAAAAAAAs0/4P4SCvdB_4M/s640/image00.png", + "image": "https://2.bp.blogspot.com/-7fF9ayZ6PgI/U9iFpk5FNEI/AAAAAAAAAs0/4P4SCvdB_4M/s640/image00.png", "type": "blog" }, { @@ -3709,7 +3782,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ }, { "url":"https://www.youtube.com/watch?v=wcjqBSei3a0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", - "image": "http://i1.ytimg.com/vi/wcjqBSei3a0/maxresdefault.jpg", + "image": "https://i1.ytimg.com/vi/wcjqBSei3a0/maxresdefault.jpg", "title": "Developers connecting the world through Google Play", "summary": "The mobile ecosystem is empowering developers to make good on the dream of connecting the world through technology to improve people's lives.", "tags":["io15","googleplay"], @@ -3718,7 +3791,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ }, { "url":"https://www.youtube.com/watch?v=B6ydLpkhq04&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", - "image": "http://i1.ytimg.com/vi/B6ydLpkhq04/maxresdefault.jpg", + "image": "https://i1.ytimg.com/vi/B6ydLpkhq04/maxresdefault.jpg", "title": "Store Listing Experiments for Google Play", "summary": "Learn how to use Google Play’s new store listing optimization feature to get more installs of your app, and how to test different graphics and text to find out which options perform the best. ", "tags":["io15","googleplay","store listing"], @@ -3727,7 +3800,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ }, { "url":"https://www.youtube.com/watch?v=jyO3-rF4Mu0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", - "image": "http://i1.ytimg.com/vi/jyO3-rF4Mu0/maxresdefault.jpg", + "image": "https://i1.ytimg.com/vi/jyO3-rF4Mu0/maxresdefault.jpg", "title": "Growing games with Google", "summary": "The games industry has never been more promising and full of opportunities. This talk covers how Google is helping developers across a broad range of existing and emerging platforms.", "tags":["io15","android", "googleplay","games"], @@ -3735,7 +3808,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "type":"youtube" }, { - "url":"http://www.youtube.com/watch?v=yJisuP94lHU", + "url":"https://www.youtube.com/watch?v=yJisuP94lHU", "image": "images/distribute/hero-playtime-opener.jpg", "title": "Playtime 2015: Innovation happens everywhere", "type":"Video", @@ -3743,7 +3816,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "summary": "Watch the opening video from Google Play's annual event series, Playtime, which celebrates inspirational developers who are changing the world around them.", }, { - "url":"http://www.youtube.com/watch?v=JrR6o5tYMWQ", + "url":"https://www.youtube.com/watch?v=JrR6o5tYMWQ", "image": "images/distribute/hero-acquisition-devbyte.jpg", "title": "User acquisition and tracking on Google Play", "type" : "Video", @@ -3765,7 +3838,7 @@ var CAROUSEL_OVERRIDE = { "title": "Android 5.0 Lollipop", "summary": "The Android 5.0 update adds a variety of new features for your apps, such as notifications on the lock screen, an all-new camera API, OpenGL ES 3.1, the new naterial design interface, and much more.", }, - "http://www.youtube.com/watch?v=yJisuP94lHU": { + "https://www.youtube.com/watch?v=yJisuP94lHU": { "url":"https://www.youtube.com/watch?v=yJisuP94lHU&index=1&list=PLWz5rJ2EKKc_QRBk7Zkl5uGjR1He7vG-w", "image": "images/distribute/hero-playtime-opener.jpg", "title": "Playtime 2015: Innovation happens everywhere", @@ -3773,76 +3846,76 @@ var CAROUSEL_OVERRIDE = { "summary": "Watch the opening video from Google Play's annual event series, Playtime, which celebrates inspirational developers who are changing the world around them.", }, "http://www.youtube.com/watch?v=rcU7VEs1hiE": { - "url":"http://www.youtube.com/watch?v=rcU7VEs1hiE&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "url":"https://www.youtube.com/watch?v=rcU7VEs1hiE&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-rogervoice-story.jpg", "title": "RogerVoice uses beta testing to launch on Android first", "type" : "youtube", "summary": "RogerVoice helps people who are hearing impaired make phone calls through voice recognition and text captions. Hear how they used material design and beta testing to create a UI that's accessible and intuitive to navigate.", }, "http://www.youtube.com/watch?v=JFlX9rW7Epc": { - "url":"http://www.youtube.com/watch?v=JFlX9rW7Epc&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "url":"https://www.youtube.com/watch?v=JFlX9rW7Epc&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-domain-story.jpg", "title": "Domain increases installs by 44% with Material Design", "type" : "youtube", "summary": "Learn how Domain, a premier real-estate portal in Australia, drastically improved their Google Play app reviews, ratings and downloads by investing in their Android app experience.", }, "http://www.youtube.com/watch?v=4CqXCkcN_d4": { - "url":"http://www.youtube.com/watch?v=4CqXCkcN_d4&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "url":"https://www.youtube.com/watch?v=4CqXCkcN_d4&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-dots-story.jpg", "title": "Dots increases installs with Store Listing Experiments", "type" : "youtube", "summary": "Hear how US-founded game developer, Dots, used the Store Listing Experiments feature in the Google Play Developer Console to test what icon, graphics, and text worked the best at converting visitors to installs.", }, - "http://www.youtube.com/watch?v=JrR6o5tYMWQ": { - "url":"http://www.youtube.com/watch?v=JrR6o5tYMWQ", + "https://www.youtube.com/watch?v=JrR6o5tYMWQ": { + "url":"https://www.youtube.com/watch?v=JrR6o5tYMWQ", "image": "images/distribute/hero-acquisition-devbyte.jpg", "title": "User acquisition and tracking on Google Play", "type" : "youtube", "summary": "Learn how to get new users, using Universal app campaigns directly within the Google Play Developer Console to increase your installs from ads, and find out how your acquisition channels perform.", }, - "http://www.youtube.com/watch?v=Pd49vTkvu0U": { - "url":"http://www.youtube.com/watch?v=Pd49vTkvu0U&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "https://www.youtube.com/watch?v=Pd49vTkvu0U": { + "url":"https://www.youtube.com/watch?v=Pd49vTkvu0U&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-jelly-button.jpg", "title": "How Jelly Button Games are growing globally through data", "summary": "To really understand their users, Jelly Button Games analyzes over 3 billion events each month using Google Analytics and Google BigQuery.", }, - "http://www.youtube.com/watch?v=700gYRkhkLM": { - "url":"http://www.youtube.com/watch?v=700gYRkhkLM&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "https://www.youtube.com/watch?v=700gYRkhkLM": { + "url":"https://www.youtube.com/watch?v=700gYRkhkLM&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-outfit7.jpg", "title": "Outfit7 — Building an entertainment company with Google", "summary": "Outfit7, creators of My Talking Tom and My Talking Angela, offer a complete entertainment experience to users spanning mobile apps, user generated and original YouTube content, and a range of toys, clothing, and accessories....", }, - "http://www.youtube.com/watch?v=MPnH7h12h0U": { - "url":"http://www.youtube.com/watch?v=MPnH7h12h0U&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "https://www.youtube.com/watch?v=MPnH7h12h0U": { + "url":"https://www.youtube.com/watch?v=MPnH7h12h0U&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-haystack.jpg", "summary": "Haystack TV built a scalable business with six employees and Android TV. Two weeks was all it took for them to bring their mobile app to the big screen.", }, - "http://www.youtube.com/watch?v=ekxABqJeRBc": { - "url":"http://www.youtube.com/watch?v=ekxABqJeRBc&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "https://www.youtube.com/watch?v=ekxABqJeRBc": { + "url":"https://www.youtube.com/watch?v=ekxABqJeRBc&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-ginlemon.jpg", "title": "How GinLemon is breaking through with Google Play", "summary": "Meet Vincenzo Colucci, developer and founder of GinLemon, which started as a summer holiday joke and has now become a successful global app business on Google Play based in Manfredonia, southern Italy.", }, - "http://www.youtube.com/watch?v=0r36OJaeMo4": { - "url":"http://www.youtube.com/watch?v=0r36OJaeMo4&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "https://www.youtube.com/watch?v=0r36OJaeMo4": { + "url":"https://www.youtube.com/watch?v=0r36OJaeMo4&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-shifty-jelly.jpg", "title": "Shifty Jelly — building a number 1 podcast app", "summary": "Shifty Jelly is an Adelaide based mobile development company that has seen great success building Pocket Casts, a premium podcast manager app.", }, - "http://www.youtube.com/watch?v=1Iw7Tg_afKk": { + "https://www.youtube.com/watch?v=1Iw7Tg_afKk": { "image": "images/distribute/hero-wooga.jpg", - "url":"http://www.youtube.com/watch?v=1Iw7Tg_afKk&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "url":"https://www.youtube.com/watch?v=1Iw7Tg_afKk&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "title": "Wooga’s fast iterations on Google Play", "summary": "The speed at which Wooga is able to iterate its live and under development games with the Android and Google Play tools has been key to delivering hits such as Diamond Dash, Jelly Splash, and Agent Alice.", }, - "http://www.youtube.com/watch?v=TieksFvD-7o": { - "url":"http://www.youtube.com/watch?v=TieksFvD-7o&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "https://www.youtube.com/watch?v=TieksFvD-7o": { + "url":"https://www.youtube.com/watch?v=TieksFvD-7o&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-trello.jpg", "title": "Trello lifts engagement by double digits with material design", "summary": "Trello recently redesigned their collaborative planning app using the material design guidelines, and their efforts paid off.", }, - "http://www.youtube.com/watch?v=MCoh4Pxs_ok": { - "url":"http://www.youtube.com/watch?v=MCoh4Pxs_ok&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "https://www.youtube.com/watch?v=MCoh4Pxs_ok": { + "url":"https://www.youtube.com/watch?v=MCoh4Pxs_ok&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-the-hunt.jpg", "title": "The Hunt — growing engagement with material design and Google Play", "summary": "Material design has helped The Hunt to enhance engagement in their style advice and product discovery app. ", diff --git a/docs/html/jd_extras_en.js b/docs/html/jd_extras_en.js new file mode 100644 index 000000000000..34a779bf0d06 --- /dev/null +++ b/docs/html/jd_extras_en.js @@ -0,0 +1,4793 @@ +/* Metadata represendations of resources that are outside of the autogenerated + local resource lists, or that override local resource representations. + + Resources listed here are referenced from queries and collections, + matched by url string. + + Currently, these articles can override only the generated resources + in DISTRIBUTE_RESOURCES. A representation defined here will not be applied + when a collection or section specifies a url that's not in DISTRIBUTE_RESOURCEs. + Also + So if a section url refers to a static doc that's + not in a distribute section, you need to create an item for + it in this file. Fix is to compare across + ALL_RESOURCES_BY_URL. */ + +METADATA['en'].extras = METADATA['en'].extras.concat([ + /* TODO Remove standard resources from here, such as below + */ + { + "title":"Measure your app’s user acquisition channels", + "category":"google", + "summary":"Get details on how to use the Developer Console User Acquisitions reports to discover where your users come from.", + "url":"https://support.google.com/googleplay/android-developer/answer/6263332", + "group":"", + "keywords": [], + "tags": [], + "image":"images/cards/google-play_2x.png", + "type":"distribute" + }, + { + "title":"Set up native app install banners in Chrome", + "category":"google", + "summary":"Get the details you need to add your native app or game to your site’s web app manifest file.", + "url":"https://developers.google.com/web/updates/2015/03/increasing-engagement-with-app-install-banners-in-chrome-for-android#native", + "group":"", + "keywords": [], + "tags": [], + "image":"images/cards/google-play_2x.png", + "type":"distribute" + }, + { + "title":"Optimize your store listing pages with experiments", + "category":"google", + "summary":"You can run experiments to find the most effective graphics and localized text for your app.", + "url":"https://support.google.com/googleplay/android-developer/answer/6227309", + "group":"", + "keywords": [], + "tags": [], + "image":"images/cards/google-play_2x.png", + "type":"distribute" + }, + { + "title":"Content Experiments for Mobile Apps", + "category":"google", + "summary":"Google Analytics Content Experiments allows you to test multiple variations of a given web page.", + "url":"https://support.google.com/tagmanager/answer/6003007", + "group":"", + "keywords": [], + "tags": [], + "image":"images/cards/google-play_2x.png", + "type":"distribute" + }, + { + "title":"Use alpha/beta testing & staged rollouts", + "category":"google play", + "summary":"Using the Google Play Developer Console, you can choose groups of users to test different versions of your app.", + "url":"https://support.google.com/googleplay/android-developer/answer/3131213", + "group":"", + "keywords": [], + "tags": [], + "image":"images/cards/google-play_2x.png", + "type":"distribute" + }, + { + "title":"Quizlet Developer Story", + "category":"google play", + "summary":"Quizlet is an extremely popular online learning tool for students. See how they optimized for the classroom with Android and the power of Google Play for Education.", + "url":"https://www.youtube.com/watch?v=Idu7VcTTXfk", + "group":"", + "keywords": [], + "tags": [ + "#gpfe", + "#googleplay" + ], + "image":"https://i1.ytimg.com/vi/Idu7VcTTXfk/maxresdefault.jpg", + "type":"video" + }, + { + "title":"What's New in GPFE", + "category":"google play", + "summary":"Learn about the vision and philosophy behind Google Play for Education", + "url":"https://www.youtube.com/watch?v=IKhU180eJMo", + "group":"", + "keywords": [], + "tags": [ + "#gpfe", + "#googleplay" + ], + "image":"https://i1.ytimg.com/vi/IKhU180eJMo/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Get started with Google Cast", + "category":"google", + "summary":"Build multi-screen experiences, let the user send video and audio content to TVs and speakers.", + "url":"https://developers.google.com/cast/docs/ux_guidelines", + "group":"", + "keywords": ["cast", "chromecast", "video", "audio"], + "tags": [], + "image":"images/cards/card-cast_2x.jpg", + "type":"develop" + }, + { + "title":"Android Sender Applications", + "category":"google", + "summary":"Get an overview of how your Android app can act as a Google Cast sender app.", + "url":"https://developers.google.com/cast/docs/android_sender", + "group":"", + "keywords": ["cast", "sender"], + "tags": [], + "image":"images/cards/card-cast_2x.jpg", + "type":"develop" + }, + { + "title":"Cast sample apps", + "category":"google", + "summary":"Get example Google Cast applications for both senders and receivers.", + "url":"https://www.github.com/googlecast", + "group":"", + "keywords": ["cast", "samples"], + "tags": [], + "image":"images/cards/card-cast_2x.jpg", + "type":"Samples" + }, + { + "title":"Get Cardboard", + "category":"Google", + "summary":"Get your own Cardboard, today. Buy one from a manufacturer or build your own, and start developing.", + "url":"https://www.google.com/get/cardboard/get-cardboard/", + "group":"", + "keywords": ["carboard","vr"], + "tags": [], + "image":"images/cards/card-cardboard_2x.png", + "type":"develop" + }, + { + "title":"Download the Cardboard SDK", + "category":"google", + "summary":"Grab the Cardboard libraries from GitHub and start creating VR apps in your favorite development environment.", + "url":"https://developers.google.com/cardboard/android/download", + "group":"", + "keywords": ["carboard","vr"], + "tags": [], + "image":"images/cards/card-cardboard_2x.png", + "type":"develop" + }, + { + "title":"Cardboard design guidelines", + "category":"design", + "summary":"Focus on overall usability and avoiding common VR pitfalls while creating an immersive experience of your own.", + "url":"https://www.google.com/design/spec-vr", + "group":"", + "keywords": ["carboard","vr"], + "tags": [], + "image":"images/cards/card-cardboard_2x.png", + "type":"Design" + }, + { + "title":"Maps", + "category":"google", + "summary":"Give users the map that more than a billion people use every month.", + "url":"https://developers.google.com/maps/documentation/android/", + "group":"", + "keywords": ["maps"], + "tags": [], + "image":"images/google/gps-maps.png", + "type":"develop" + }, + { + "title":"Places API", + "category":"google", + "summary":"give your users contextual information about where they are, when they’re there.", + "url":"https://developers.google.com/places/android/", + "group":"", + "keywords": ["places","location", "context"], + "tags": [], + "image":"images/cards/card-places_2x.png", + "type":"develop" + }, + { + "title":"GCM Client for Android", + "category":"google", + "summary":"Send push notifications and pubsub from your server to Android devices around the world.", + "url":"https://developers.google.com/cloud-messaging/android/client", + "group":"", + "keywords": ["push","gcm"], + "tags": [], + "image":"images/cards/card-google-cloud-messaging_16-9_2x.png", + "type":"develop" + }, + { + "title":"Google Cloud Messaging", + "category":"google", + "summary":"Learn about GCM and the kinds of services you can offer to users through push notifications", + "url":"https://developers.google.com/cloud-messaging/gcm", + "group":"", + "keywords": ["push","gcm"], + "tags": [], + "image":"images/cards/card-google-cloud-messaging_16-9_2x.png", + "type":"develop" + }, + { + "title":"ClassDojo Developer Story", + "category":"developer story", + "summary":"ClassDojo is a classroom tool that helps teachers improve behavior in their classrooms quickly and easily. See how they optimized for the classroom with Android and the power of Google Play for Education.", + "url":"https://www.youtube.com/watch?v=iokH4SAIfRw", + "group":"", + "keywords": [], + "tags": [ + "#gpfe", + "#googleplay" + ], + "image":"https://i1.ytimg.com/vi/iokH4SAIfRw/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Plan for Success", + "category":"google play", + "summary":"5 tips from developers on creating great EDU apps.", + "url":"https://www.youtube.com/watch?v=Eh2adsAyTKc", + "group":"", + "keywords": [], + "tags": [ + "#gpfe", + "#googleplay" + ], + "image":"https://i1.ytimg.com/vi/Eh2adsAyTKc/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Optimizing Apps for Education", + "category":"google play", + "summary":"Learn how to optimize your app for teachers and students.", + "url":"https://www.youtube.com/watch?v=_AZ6UcPz-_g", + "group":"", + "keywords": [], + "tags": [ + "#gpfe", + "#googleplay" + ], + "image":"https://i1.ytimg.com/vi/_AZ6UcPz-_g/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Ideas and Tools for Building Innovative Education Apps", + "category":"google play", + "summary":"Are you hungry to build an awesome app for education but don't quite know where to start? Come hear about apps that teachers want, and the APIs you're going to need to build them! In particular, we'll talk about app ideas that combine APIs for Google Drive, Google Login, Android Single Task Mode and more to build transformative Educational apps that will delight educators and kids in and out of the classroom.", + "url":"https://www.youtube.com/watch?v=iulXz8QTD1g", + "group":"", + "keywords": [], + "tags": [ + "#gpfe", + "#googleplay" + ], + "image":"https://i1.ytimg.com/vi/iulXz8QTD1g/maxresdefault.jpg", + "type":"video" + }, + { + "title":"DesignBytes: Intro To Material Design", + "category":"material design", + "summary":"These days, UI designers need to be thinking about phones, tablets, laptops, TVs, smartwatches, and beyond. In this DesignByte we talk about how Google designers have been working on making cross-platform and multi-screen design easier. We wanted to build a design system that felt at home on every screen, from the smallest watch to the largest TV.", + "url":"https://www.youtube.com/watch?v=p4gmvHyuZzw", + "group":"", + "keywords": [], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/p4gmvHyuZzw/maxresdefault.jpg", + "type":"video" + }, + { + "title":"DesignBytes: Paper and Ink: The Materials that Matter", + "category":"material design", + "summary":"Join Rich Fulcher to learn about the materials of material design. See how virtual paper and ink form the foundation of your tactile user interface and master the rules that govern their behaviour.", + "url":"https://www.youtube.com/watch?v=YaG_ljfzeUw", + "group":"", + "keywords": [], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/YaG_ljfzeUw/maxresdefault.jpg", + "type":"video" + }, + { + "title":"DesignBytes: Material Design in the Google I/O App", + "category":"", + "summary":"Roman Nurik shares details on the design process for the Google I/O 2014 app. To check out the app's source code, visit github.com/google/iosched.", + "url":"https://www.youtube.com/watch?v=XOcCOBe8PTc", + "group":"", + "keywords": [], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/XOcCOBe8PTc/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Toolbars for a flexible Action Bar & more", + "category":"", + "summary":"Toolbars are a flexible View you can add to your Android app which provides many of the same APIs as the system provided Action Bar, but can also do so much more such as reacting to scrolling or being integrated directly into your layouts.", + "url":"https://www.youtube.com/watch?v=kmUGLURRPkI", + "group":"", + "keywords": [], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/kmUGLURRPkI/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Protecting Implicit Intents with Runtime Checks", + "category":"", + "summary":"Make sure you protect your implicit intents with a simple runtime check.", + "url":"https://www.youtube.com/watch?v=HGElAW224dE", + "group":"", + "keywords": [], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/HGElAW224dE/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Tabs and ViewPager", + "category":"", + "summary":"Showing multiple screens or pages of content is easy with the help of ViewPager and a PagerAdapter. Combining that with tabs make for an effective top level navigation strategy for your app or for moving between content at the same level of hierarchy within your app.", + "url":"https://www.youtube.com/watch?v=zQekzaAgIlQ", + "group":"", + "keywords": [], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/zQekzaAgIlQ/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Battery Drain and Networking", + "category":"", + "summary":"Let’s take a moment to make something insanely clear: As far as battery is concerned, NETWORKING is the biggest, baddest, dirtiest offender there is. And optimizing performance here isn’t easy. Since the chip isn’t always awake and draining power, means you can optimize how it wakes up, sends traffic, and saves battery.", + "url":"https://www.youtube.com/watch?v=fEEulSk1kNY", + "group":"", + "keywords": [], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/fEEulSk1kNY/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Batching Background Work Until Later", + "category":"", + "summary":"Yes, your app is special. But when it comes to battery use, sometimes it’s better to be part of the crowd. Why not spread the battery blame around a bit? Ian Ni-Lewis shows you how ridiculously easy it is to go from battery hog to team player in this video.", + "url":"https://www.youtube.com/watch?v=-3ry8PxcJJA", + "group":"", + "keywords": [], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/-3ry8PxcJJA/maxresdefault.jpg", + "type":"video" + }, + { + "title":"The Performance Lifecycle", + "category":"", + "summary":"Performance problems surface in your application at the least-wanted times (like right before you’re about to ship your first build). But don’t freak out: There’s a simple process that you can follow to help get your performance back under control.", + "url":"https://www.youtube.com/watch?v=_kKTGK-Cb_4", + "group":"", + "keywords": [], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/_kKTGK-Cb_4/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Introduction to Android Studio", + "category":"", + "summary":"Learn why you should migrate your projects to Android Studio now and how it can help you be more productive as a developer. Rich layout editor, handy suggestions and fixes, new Android project view - these are just some of the things you can expect from the IDE, which is built on the successful IntelliJ IDEA.", + "url":"https://www.youtube.com/watch?v=K2dodTXARqc&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ", + "group":"", + "keywords": ["studio", "tools"], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/K2dodTXARqc/maxresdefault.jpg", + "type":"video" + }, + + { + "title":"Google Play Services 7.5", + "category":"", + "summary":"This update brings App Invites, topics to GCM, GCMNetworkManager, Cast Remote Display API, Smart Lock for Passwords, Maps API for Android Wear, Google Fit extensions and more.", + "url":"https://www.youtube.com/watch?v=M3Udfu6qidk&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf", + "group":"", + "keywords": ["google play services"], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/M3Udfu6qidk/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Google Play Services 7.3", + "category":"", + "summary":"This update brings the ability to connect multiple wearables simultaneously to a single phone. There are also some great new updates to Google Fit, including nutrition types, and to Location.", + "url":"https://www.youtube.com/watch?v=FOn64iqlphk&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf", + "group":"", + "keywords": ["google play services"], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/FOn64iqlphk/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Google Play Services 6.5", + "category":"", + "summary":"Google Play services 6.5 includes new features in Google Maps, Google Drive and Google Wallet as well as the recently launched Google Fit API. ", + "url":"https://www.youtube.com/watch?v=fvtMtfCuEpw&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf", + "group":"", + "keywords": ["google play services"], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/fvtMtfCuEpw/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Google Play Services 7.0", + "category":"", + "summary":"Google Play services 7.0 is here! we've added the Places API, made enhancements to Location and Google Fit, and you can also remote control your Android TV through the new Nearby Connections API.", + "url":"https://www.youtube.com/watch?v=F0Kh_RnSM0w&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf", + "group":"", + "keywords": ["google play services"], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/F0Kh_RnSM0w/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Running a Successful Games Business with Google", + "category":"", + "summary":"Sure, we all want to make the next great gaming masterpiece. But we also want to feed our families and/or dogs. Join Bob Meese from the Google Play team as he gives you some key pointers on how to make sure you're best taking advantage of Google Play and running a successful games business.", + "url":"https://www.youtube.com/watch?v=tDmnGNkTtlE", + "group":"", + "keywords": [], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/tDmnGNkTtlE/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Introduction to Android TV", + "category":"", + "summary":"Android TV brings the Android platform to the living room with rich content and entertaining app experiences. In this video, Timothy introduces the design philosophy and developer components that make building TV experiences easier than ever before.", + "url":"https://www.youtube.com/watch?v=6K_jxccHv5M&index=1&list=PLOU2XLYxmsILFBfx66ens76VMLMEPJAB0", + "group":"", + "keywords": ["tv"], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/6K_jxccHv5M/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Introduction to Android Auto", + "category":"", + "summary":"Android Auto brings the Android platform to the car in a way that's optimized for the driving experience. It's the same platform you already use for phones, tablets, televisions, wearables, and more. ", + "url":"https://www.youtube.com/watch?v=ctiaVxgclsg&list=PLWz5rJ2EKKc9BdE_PSLNIGjXXr3h_orXM", + "group":"", + "keywords": ["auto"], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/ctiaVxgclsg/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Debugging and testing in Android Studio", + "titleFriendly":"", + "summary":"This video introduces the state of unit testing support in Studio and Google’s new Android Testing Support Library for functional UI testing and running instrumented tests on a device.", + "url":"https://www.youtube.com/watch?v=2I6fuD20qlY", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/2I6fuD20qlY/maxresdefault.jpg", + "type":"video" + }, + { + "title":"Android Testing (Android Dev Summit 2015)", + "titleFriendly":"", + "summary":"Overview of the testing tools and frameworks provided by Google and how they can help you to iterate more quickly and maintain a more healthy codebase.", + "url":"https://www.youtube.com/watch?v=vdasFFfXKOY", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"https://i1.ytimg.com/vi/vdasFFfXKOY/maxresdefault.jpg", + "type":"video" + }, + { + "title":"dumpsys", + "titleFriendly":"", + "summary":"A tool that runs on the device and provides information about the status of system services.", + "url":"https://source.android.com/devices/tech/debug/dumpsys.html", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"", + "type":"google" + }, + { + "title":"Android Testing Samples", + "titleFriendly":"", + "summary":"A collection of samples demonstrating different frameworks and techniques for automated testing.", + "url":"https://github.com/googlesamples/android-testing", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"images/testing/testing-icon.png", + "type":"Samples" + }, + { + "title":"Android Testing Templates", + "titleFriendly":"", + "summary":"A collection of Google's Android testing tools and frameworks, all integrated in a single application project.", + "url":"https://github.com/googlesamples/android-testing-templates", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"images/testing/testing-icon.png", + "type":"Samples" + }, + { + "title":"Android Testing Support Library (GitHub)", + "titleFriendly":"", + "summary":"A resource page on GitHub for the Android Testing Support Library.", + "url":"https://google.github.io/android-testing-support-library", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"images/testing/testing-icon.png", + "type":"Samples" + }, + { + "title":"Android Testing Codelab", + "titleFriendly":"", + "summary":"This codelab shows how to build an Android app from the ground up in Android Studio, using a Model View Presenter architecture, Unit Tests and Instrumentation Tests.", + "url":"https://codelabs.developers.google.com/codelabs/android-testing/index.html", + "group":"", + "keywords": ["testing"], + "tags": [ + ], + "image":"images/testing/testing-icon.png", + "type":"google" + }, + { + "title":"Developer Registration", + "category":"google play", + "summary":"Additional information about the registration process.", + "url":"https://support.google.com/googleplay/android-developer/answer/113468", + "group":"", + "keywords": [], + "tags": [], + "image":"images/cards/google-play_2x.png", + "type":"distribute" + }, + { + "title": "Google Play Distribution and Seller Countries", + "category":"google play", + "summary": "List of countries and territories where you can distribute your apps in Google Play.", + "url":"https://support.google.com/googleplay/android-developer/answer/138294", + "group":"", + "keywords": [], + "tags": [], + "image":"images/cards/google-play_2x.png", + "type":"distribute" + }, + { + "title":"Google Play Content Policies", + "category":"google play", + "summary":"Details on policies relating to your developer account and app distribution is governed.", + "url":"https://support.google.com/googleplay/android-developer/topic/3453577", + "group":"", + "keywords": [], + "tags": ["#developersupport"], + "image":"images/cards/google-play_2x.png", + "type":"distribute" + }, + { + "title":"Google Play Badge Generator", + "category":"google play", + "summary":"Build badges for your app in just a few clicks, or download hi-res badge assets localized for a variety of languages.", + "url":"https://play.google.com/intl/en_us/badges/", + "group":"", + "keywords": [], + "tags": ["#developersupport"], + "image":"images/gp-badges-set.png", + "type":"distribute" + }, + { + "lang": "en", + "group": "", + "tags": ["#developersupport #termsandpolicies"], + "url": "https://support.google.com/googleplay/android-developer/answer/4407611", + "timestamp": 1194884220000, + "image": 'images/play_dev.jpg', + "title": "Google Play Terms and Policies", + "summary": "Developer terms and policies that apply when you distribute apps in Google Play.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "title":"Google Play Policy Center", + "category":"google play", + "summary":"A central resource for you to learn about Google Play policies and guidelines.", + "url":"https://support.google.com/googleplay/android-developer/answer/4430948", + "group":"", + "keywords": [], + "tags": [], + "image":"https://storage.googleapis.com/support-kms-prod/SNP_712EA2784949DDF085C46E3BE7B1DC618A09_4389397_en_v0", + "type":"distribute" + }, + { + "title":"Developer Help Center", + "category":"Support", + "summary":"Complete details on getting started, publishing, troubleshooting, and more.", + "url":"https://support.google.com/googleplay/android-developer", + "group":"", + "keywords": [], + "tags": [], + "image":"images/cards/google-play_2x.png", + "type":"distribute" + }, + { + "title":"Google for Education", + "category":"google play", + "summary":"Find out more about how Google can support your work with apps and tablets.", + "url":"https://www.google.com/edu/tablets/", + "group":"", + "keywords": [], + "tags": [], + "image":"distribute/images/gp-edu-apps-image.jpg", + "type":"distribute" + }, + { + "title":"Google Play Game Services", + "category":"google", + "summary":"Make your games social with Google Play game services. Add achievements, leaderboards, real-time multiplayer, and other popular features using the Google Play game services SDK.", + "url":"https://developers.google.com/games/services/", + "group":"", + "keywords": ["games","play games"], + "tags": [], + "image":"images/google/gps-play_games_logo.png", + "type":"distribute" + }, + { + "title":"Get Started with Analytics", + "category":"google", + "summary":"Get advanced insight into how players discover and play your games.", + "url":"distribute/analyze/start.html", + "group":"", + "keywords": ["analytics"], + "tags": [], + "image": "images/cards/analytics-mobile_2x.jpg", + "type": "distribute" + }, + { + "title":"Monetize your apps intelligently", + "category":"google", + "summary":"Generate revenue from your free games with ads tailored to match your game's look and feel.", + "url":"https://www.google.com/admob/", + "group":"", + "keywords": ["AdMob"], + "tags": [], + "image":"images/cards/admob-analytics_2x.png", + "type": "distribute" + }, + { + "lang": "en", + "group": "", + "tags": [ + "versions", "blog", "googleplay" + ], + "url": "https://android-developers.blogspot.com/", + "timestamp": 1004884220000, + "image": "images/blog.jpg", + "title": "Android Developers Blog", + "summary": "Follow the latest news on Android design, development, and distribution.", + "keywords": [], + "type": "blog", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://android-developers.blogspot.com/2011/11/making-android-games-that-play-nice.html", + "timestamp": 1194884220000, + "image": null, + "title": "Making Android Apps that Play Nice", + "summary": "Audio lifecycle and expected audio behaviors for Android apps.", + "keywords": [], + "type": "blog", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://android-developers.blogspot.com/2010/07/multithreading-for-performance.html", + "timestamp": 1194884220000, + "image": null, + "title": "Multithreading for Performance", + "summary": "Ways to improve performance through multi-threading.", + "keywords": [], + "type": "blog", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://play.google.com/about/developer-content-policy.html", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Developer Program Policies", + "summary": "Guidelines acceptable content in Google Play. Please read and understand the policies before publishing.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/188189", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Rating your application content for Google Play", + "summary": "How to choose the appropriate content ratings level for your apps.", + "keywords": [], + "type": "distribute", + "category": "Support" + }, + { + "lang": "en", + "group": "", + "tags": ["devices", "nexus", "testing"], + "url": "https://developers.google.com/android/nexus/images", + "timestamp": 1194884220000, + "image": "images/cards/card-download_16-9_2x.png", + "title": "Factory Images for Nexus Devices", + "summary": "System image files for Android 6.0 and other Android releases.", + "keywords": ["nexus, downloads"], + "type": "develop", + "category": "Tools" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://android-developers.blogspot.com/2011/10/android-market-featured-image.html", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Google Play Featured Image Guidelines", + "summary": "How to create attractive, effective Featured Images for your apps.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, +{ + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/113477", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Supporting your users", + "summary": "Options for supporting users.", + "keywords": [], + "type": "distribute", + "category": "Support" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "guide/practices/screens_support.html#ConfigurationExamples", + "timestamp": 1194884220000, + "image": null, + "title": "Configuration examples", + "summary": "How to declare layouts and other resources for specific screen sizes.", + "keywords": [], + "type": "develop", + "category": "guide" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "training/design-navigation/multiple-sizes.html", + "timestamp": 1194884220000, + "image": null, + "title": "Planning for Multiple Touchscreen Sizes", + "summary": "", + "keywords": [], + "type": "develop", + "category": "guide" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "training/multiscreen/index.html", + "timestamp": 1194884220000, + "image": null, + "title": "Designing for Multiple Screens", + "summary": "Designing an intuitive, effective navigation for tablets and other devices.", + "keywords": [], + "type": "develop", + "category": "guide" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "guide/topics/resources/providing-resources.html", + "timestamp": 1194884220000, + "image": null, + "title": "Providing Resources", + "summary": "Layouts and drawable resources for specific ranges of device screens.", + "keywords": [], + "type": "develop", + "category": "guide" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "training/basics/supporting-devices/screens.html", + "timestamp": 1194884220000, + "image": null, + "title": "Supporting Different Screens", + "summary": "Optimizing the user experience for different screen sizes and densities.", + "keywords": [], + "type": "develop", + "category": "guide" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "guide/topics/appwidgets/index.html#MetaData", + "timestamp": 1194884220000, + "image": null, + "title": "Adding the AppWidgetProviderInfo Metadata", + "summary": "How to set the height and width dimensions of a widget.", + "keywords": [], + "type": "develop", + "category": "guide" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "guide/topics/manifest/uses-sdk-element.html#ApiLevels", + "timestamp": 1194884220000, + "image": null, + "title": "Android API Levels", + "summary": "Introduction to API levels and how they relate to compatibility.", + "keywords": [], + "type": "develop", + "category": "compatibility" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "guide/practices/screens_support.html#DeclaringScreenSizeSupport", + "timestamp": 1194884220000, + "image": null, + "title": "Declaring screen size support", + "summary": "How to declare support for screen sizes in your app\'s manifest.", + "keywords": [], + "type": "develop", + "category": "compatibility" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "guide/topics/manifest/uses-feature-element.html#testing", + "timestamp": 1194884220000, + "image": null, + "title": "Checking for hardware feature requirements", + "summary": "Determining an app’s hardware and software requirements.", + "keywords": [], + "type": "develop", + "category": "compatibility" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://play.google.com/apps/publish/", + "timestamp": 1194884220000, + "image": null, + "title": "Google Play Developer Console", + "summary": "The tools console for publishing your app.", + "keywords": [], + "type": "distribute", + "category": "Google Play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://youtu.be/SkHHPf3EdzE", + "timestamp": 1194884220000, + "image": "https://i1.ytimg.com/vi/SkHHPf3EdzE/maxresdefault.jpg", + "title": "Level Up Your Android Game", + "summary": "Learn how to take your game to the next level on Google Play.", + "keywords": [], + "type": "video", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/+/mobile/android/share/interactive-post", + "timestamp": 1194884220000, + "image": 'images/google/gps-googleplus.png', + "title": "Sharing interactive posts to Google+ from your Android app", + "summary": "Interactive posts provide an easy and prominent way to allow users to share your site or app with their friends and invite them to take a specific action.", + "keywords": ["Interactive", "Google+"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://play.google.com/about/developer-distribution-agreement.html", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Developer Distribution Agreement", + "summary": "Terms for distributing and selling apps and in-app products in Google Play.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/113417", + "timestamp": 1194884220000, + "image": null, + "title": "Inappropriate content in comments and applications", + "summary": "More details on what content is appropriate.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/legal/troubleshooter/1114905", + "timestamp": 1194884220000, + "image": null, + "title": "Removing content from Google", + "summary": "Find how how to request the removal of content that infringes on your trademark.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://play.google.com/about/developer-distribution-agreement-addendum.html", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Google Play for Education Addendum", + "summary": "Review the education-specific requirements.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://android-developers.blogspot.com/2013/03/native-rtl-support-in-android-42.html", + "timestamp": null, + "image": null, + "title": "Native RTL Support in Android 4.2", + "summary": "Blog post that explains how to support RTL in your UI.", + "keywords": [], + "type": "blog", + "category": "Localization" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "guide/topics/resources/string-resource.html#Plurals", + "timestamp": 1194884220000, + "image": null, + "title": "Quantity Strings (Plurals)", + "summary": "How to work with string plurals according to rules of grammar in a given locale.", + "keywords": [], + "type": "develop", + "category": "Localization" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "reference/java/util/Locale.html", + "timestamp": 1194884220000, + "image": null, + "title": "Locale", + "summary": "Determine what CLDR data or version of the Unicode spec a particular Android platform version uses.", + "keywords": [], + "type": "develop", + "category": "Localization" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "guide/topics/resources/string-resource.html", + "timestamp": 1194884220000, + "image": null, + "title": "String Resources", + "summary": "Explains how to use string resources in your UI.", + "keywords": ["localization"], + "type": "develop", + "category": "guide" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "distribute/tools/localization-checklist.html#strings", + "timestamp": 1194884220000, + "image": null, + "title": "Manage strings for localization", + "summary": "Guidance on having your strings translation ready.", + "keywords": [], + "type": "distribute", + "category": "localization" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "distribute/googleplay/policies/index.html", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Google Play Policies and Guidelines", + "summary": "An overview of Google Play policies for spam, intellectual property, and ads, with examples of common problems.", + "keywords": [], + "type": "distribute", + "category": "google play " + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/topic/2364761", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Policy and Best Practices", + "summary": "Help Center document describing various content policies and processes.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/wallet/instant-buy/", + "timestamp": 1194884220000, + "image": "", + "title": "Android Pay APIs", + "summary": "Developer documentation describing Instant Buy and how to support it in your apps.", + "keywords": [], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/1169947", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Selling Apps in Multiple Currencies", + "summary": "Help Center document describing how pricing works in Google Play.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/138412", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Prices and supported currencies", + "summary": "Help Center document listing supported currencies for pricing your apps.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/112622", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Transaction Fees", + "summary": "Help Center document describing transaction fees for priced apps and in-app products.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/138000", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Specifying tax rates", + "summary": "Help Center document describing how to set tax rates for different countries.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "guide/topics/resources/localization.html", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Localizing with Resources", + "summary": "Developer guide to localizing resources in your app.", + "keywords": [], + "type": "develop", + "category": "localization" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/113475", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Category types", + "summary": "Help Center document listing available categories for apps.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/113476", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Updates", + "summary": "Requirements for app updates in Google Play.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/1153479", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "In-app Billing", + "summary": "Help Center document describing how to correctly set up In-app Billing.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [ + "#gpfe", + "#googleplay" + ], + "url": "https://youtu.be/vzvpcEffvaE", + "timestamp": 1383243492000, + "image": "https://i1.ytimg.com/vi/vzvpcEffvaE/maxresdefault.jpg", + "title": "Introducing Tablets with Google Play for Education", + "summary": "Schools in Hillsborough, New Jersey were among the first to try out Nexus 7 tablets with Google Play for Education. See the difference it made for students, teachers, and administrators.", + "keywords": [], + "type": "video", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [ + "#engagement", + ], + "url": "https://www.youtube.com/yt/dev/", + "timestamp": 1383243492000, + "image": "https://www.youtube.com/yt/dev/media/images/yt-dev-home-hero.jpg", + "title": "YouTube for Developers", + "summary": "The YouTube APIs and Tools enable you to integrate YouTube's video content and functionality into your website, app, or device.", + "keywords": [], + "type": "video", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [ + "#engagement", + ], + "url": "https://www.google.com/analytics/mobile/", + "timestamp": 1383243492000, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Mobile App Analytics", + "summary": "Mobile App Analytics measures what matters most at all key stages: from first discovery and download to in-app purchases. ", + "keywords": ["analytics,user behavior"], + "type": "distribute", + "category": "google" + }, + + + { + "lang": "en", + "group": "", + "tags": [ + "#gcm", + ], + "url": "https://www.youtube.com/watch?v=y76rjidm8cU", + "timestamp": 1383243492000, + "image": "https://1.bp.blogspot.com/-IF-1-1kA0sg/UYwTidxdi3I/AAAAAAAAAEU/ellLeQ-E1vs/s800/google-io-lockup-2.png", + "title": "Google Cloud Messaging at I/O 2013", + "summary": "Google Cloud Messaging allows your services to efficiently send data to applications on Android devices. See what's new, and learn how to use GCM to make your apps more efficient.", + "keywords": ["gcm"], + "type": "youtube", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [ + "#gcm", + ], + "url": "https://developer.chrome.com/apps/cloudMessagingV2", + "timestamp": 1383243492000, + "image": "images/kk-chromium-icon.png", + "title": "Google Cloud Messaging for Chrome", + "summary": "Google Cloud Messaging for Chrome (GCM) is a service for signed-in Chrome users that helps developers send message data from servers to their Chrome apps and extensions.", + "keywords": ["gcm"], + "type": "distribute", + "category": "google" + }, + + { + "lang": "en", + "group": "", + "tags": [ + "#sdkupdates" + ], + "url": "https://android-developers.blogspot.com/2013/07/making-beautiful-android-app-icons.html", + "timestamp": 1194884220000, + "image": null, + "title": "Make Beautiful Android App Icons", + "summary": "Follow these in-depth launcher icon tips on the Android Developers blog.", + "keywords": [], + "type": "blog", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [ + "#sdkupdates" + ], + "url": "https://android-developers.blogspot.com/2012/12/localize-your-promotional-graphics-on.html", + "timestamp": 1194884220000, + "image": null, + "title": "Localize Your Promotional Graphics", + "summary": "Learn how to capitalise on international audiences.", + "keywords": [], + "type": "blog", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [ + "#sdkupdates" + ], + "url": "https://android-developers.blogspot.com/2013/10/making-your-app-content-more-accessible.html", + "timestamp": 1194884220000, + "image": null, + "title": "Make your App Content more Accessible with App Linking", + "summary": "About using search and deep linking to get more users.", + "keywords": [], + "type": "blog", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/+/mobile/android/share/interactive-post", + "timestamp": 1194884220000, + "image": 'images/google/gps-googleplus.png', + "title": "Sharing interactive posts to Google+ from your Android app", + "summary": "Interactive posts provide an easy and prominent way to allow users to share your site or app with their friends and invite them to take a specific action.", + "keywords": ["Interactive", "Google+"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/+/mobile/android/", + "timestamp": 1194884220000, + "image": 'images/google/gps-googleplus.png', + "title": "Google+ Platform", + "summary": "Find out about features such as interactive posts, Hangouts, accessing basic user details and their social graphs to make your app more personal.", + "keywords": ["Google+"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/2528691", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "How to add multiple user accounts to your Developer Console for testing and more.", + "summary": "", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "google/play/licensing/index.html", + "timestamp": 1194884220000, + "image": null, + "title": "Application Licensing", + "summary": "Information on the features of Google Play to protect your apps’ licences.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "design/style/writing.html", + "timestamp": 1194884220000, + "image": null, + "title": "Writing Style", + "summary": "Design guidelines for voice and style in your UI.", + "keywords": [], + "type": "design", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://en.wikipedia.org/wiki/XLIFF", + "timestamp": 1194884220000, + "image": null, + "title": "XML Localisation Interchange File Format (XLIFF)", + "summary": "Background information on XLIFF.", + "keywords": [], + "type": "develop", + "category": "localization" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/1078870", + "timestamp": 1194884220000, + "image": "images/cards/google-play_2x.png", + "title": "Graphic Assets for your Application", + "summary": "Details about the graphics you can add to your product listing.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/payments/answer/2741495", + "timestamp": null, + "image": null, + "title": "Issuing Refunds", + "summary": "Help Center document describing how to issue refunds.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://android-developers.blogspot.com/2013/11/bring-your-apps-into-classroom-with.html", + "timestamp": null, + "image": "distribute/images/gp-edu-apps-image.jpg", + "title": "Google play for education", + "summary": " ", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": ["localization", "pricing", "developer support"], + "url": "https://support.google.com/googleplay/android-developer/table/3541286", + "timestamp": null, + "image": "images/cards/google-play_2x.png", + "title": "Supported locations for distributing your apps in Google Play", + "summary": "Countries and regions where you can distribute your app in Google Play.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": ["games", "localization", "quality"], + "url": "https://www.youtube.com/watch?v=SkHHPf3EdzE", + "timestamp": null, + "image": "https://developers.google.com/apps/images/io_2013/google-io-logo.png", + "title": "Level Up Your Android Game", + "summary": "Learn how to take your game to the next level in this Google I/O session.", + "keywords": [], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": ["support"], + "url": "https://support.google.com/plus/topic/2888488", + "timestamp": null, + "image": null, + "title": "Google+ Communities", + "summary": "Host a Google+ community for testers or users.", + "keywords": [], + "type": "distribute", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": ["monetize", "ads"], + "url": "https://www.google.com/doubleclick/publishers/small-business/index.html", + "timestamp": null, + "image": "https://www.google.com/doubleclick/publishers/small-business/images/define_ad.png", + "title": "DoubleClick for Publishers", + "summary": "A free ad management solution that helps growing publishers sell, schedule, deliver, and measure all of their digital ad inventory.", + "keywords": ["ads"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": ["monetize", "ads"], + "url": "https://support.google.com/googleplay/android-developer/topic/2985714", + "timestamp": null, + "image":"images/cards/google-play_2x.png", + "title": "Policy Center: Ads", + "summary": "Introduction to ads and system interference policies in Google Play.", + "keywords": ["ads"], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/analytics/answer/2611404", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Create Audience lists in Google Analytics", + "summary": "Find out how to use your analytics data to discover high value users and create remarketing audiences to use in AdMob.", + "keywords": ["ads, analytics, monetize"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://admob.blogspot.com/", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Inside Admob", + "summary": "Google’s official blog for news, tips, and information on the AdMob developer platform.", + "keywords": ["ads, analytics, monetize"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/admob/answer/3111064", + "timestamp": null, + "image": "distribute/images/advertising.jpg", + "title": "AdMob in-app conversion tracking", + "summary": "Use in-app conversion tracking to attribute revenue back to your IAP promotion campaigns and determine which ones earn you the most.", + "keywords": ["ads, analytics, conversions"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": ["monetize", "giftcards"], + "url": "https://play.google.com/about/giftcards/", + "timestamp": null, + "image": "images/gp-balance.png", + "title": "Google Play Gift Cards", + "summary": "Buy Google Play gift cards online or at a variety of retail stores.", + "keywords": ["gift card"], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": ["monetize", "paymentmethods"], + "url": "https://support.google.com/googleplay/answer/2651410", + "timestamp": null, + "image": "images/cards/google-play_2x.png", + "title": "Google Play Accepted Payment Methods", + "summary": "Support details on the payment methods supported in Google Play.", + "keywords": ["gift card"], + "type": "distribute", + "category": "google play" + }, + { + "lang": "en", + "group": "", + "tags": ["plus", "social"], + "url": "https://plus.google.com/+AndroidDevelopers/", + "timestamp": null, + "image": "images/plus.jpg", + "title": "+Android Developers", + "summary": "Sharing news, ideas, and techniques for success.", + "keywords": ["+AndroidDevelopers"], + "type": "develop", + "category": "Social" + }, + { + "lang": "en", + "group": "", + "tags": ["plus", "social"], + "url": "https://plus.google.com/+GooglePlay", + "timestamp": null, + "image": "images/cards/google-play_2x.png", + "title": "+Google Play", + "summary": "News and discussion about Google Play, apps, and other content in Google+.", + "keywords": ["+GooglePlay"], + "type": "distribute", + "category": "Social" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/analytics/devguides/collection/android/", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Mobile App Analytics SDK", + "summary": "Measure everything about your app. Get started with the Google Analytics SDK for Android.", + "keywords": ["analytics, user behavior"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/edu/guidelines", + "timestamp": null, + "image": "https://developer.android.com/distribute/images/edu-guidelines.jpg", + "title": "Education Guidelines", + "summary": "These guidelines and requirements help you develop great apps for students, which offer compelling content and an intuitive user experience on Android tablets.", + "keywords": [], + "type": "", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/edu/faq", + "timestamp": null, + "image": "https://developer.android.com/distribute/images/gpfe-faq.jpg", + "title": "Education FAQ", + "summary": "Answers to common questions you might have about Google Play for Education.", + "keywords": [], + "type": "", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/edu/", + "timestamp": null, + "image": "https://developers.google.com/edu/images/home-android.png", + "title": "Chrome Apps in Google Play for Education", + "summary": "Find out more about Chrome apps in Google Play for Education.", + "keywords": [], + "type": "", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://www.google.com/edu/tablets/#tablets-family", + "timestamp": null, + "image": "https://www.google.com/edu/images/tablets/big-tablet.png", + "title": "Google Play for Education Tablets", + "summary": "Google Play for Education leverages a diverse set up tablets approved for the classroom which may help inform you how to build educational apps.", + "keywords": [], + "type": "", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_Deerhunter2014_gpgs.pdf", + "timestamp": null, + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_Deerhunter2014_gpgs.png", + "title": "Deer Hunter 2014 by Glu — Sign-in", + "summary": "Glu finds that Google Play Game Services helps improve the user experience which leads to increased player happiness. They also find that Play Games Services signed in users tend to play longer and have a higher lifetime value.", + "keywords": ["stories"], + "type": "Case Study Deck", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/ConcreteSoftware_PBABowling_gpgs.pdf", + "timestamp": null, + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/ConcreteSoftware_PBABowling_gpgs.png", + "title": "PBA® Bowling Challenge by Concrete Software — Quests", + "summary": "Concrete Software finds that Google Play Game Services' quests are a great way to create new content for users that leads to higher engagement.", + "keywords": ["stories"], + "type": "Case Study Deck", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Dragonplay_DragonplaySlots_gpgs.pdf", + "timestamp": null, + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Dragonplay_DragonplaySlots_gpgs.png", + "title": "Dragonplay Slots by Dragonplay — Sign-in", + "summary": "Dragonplay finds that players who sign in with Google Play Games services tend to be high quality users who were highly engaged. They also tend to be easier to convert to paying users.", + "keywords": ["stories"], + "type": "Case Study Deck", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Gameloft_Asphalt8_gpgs.pdf", + "timestamp": null, + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Gameloft_Asphalt8_gpgs.png", + "title": "Asphalt 8 by Gameloft — Friends invitations", + "summary": "Gameloft finds that Google Play Game Services users are more engaged than the average Android user and more likely to convert to paying players.", + "keywords": ["stories"], + "type": "Case Study Deck", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_EternityWarriors3_gpgs.pdf", + "timestamp": null, + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_EternityWarriors3_gpgs.png", + "title": "Eternity Warriors 3 by Glu — Gifting", + "summary": "Glu finds that Google Play Game Services gifting outperforms other implementations (including those with incentives) because of its seamless flow and consistent performance.", + "keywords": ["stories"], + "type": "Case Study Deck", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/HotheadGames_RivalsatWar_gpgs.pdf", + "timestamp": null, + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/HotheadGames_RivalsatWar_gpgs.jpg", + "title": "Rivals at War: Firefight by Hothead Games — Leaderboards", + "summary": "Hothead Games is planning to include Google Play Game Services features in all their games going forwards after seeing that players that signed in with Play Games Services tend to show higher retention and a higher average revenue.", + "keywords": ["stories"], + "type": "Case Study Deck", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/TMSOFT_Compulsive_gpgs.pdf", + "timestamp": null, + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/TMSOFT_Compulsive_gpgs.png", + "title": "Compulsive by TMSOFT — Cross-platform", + "summary": "TMSOFT finds that users who authenticate with Play Games Services on Android and iOS play Compulsive twice as much and purchase in-app products over four times as much.", + "keywords": ["stories"], + "type": "Case Study Deck", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Noodlecake_SuperStickmanGolf2_gpgs.pdf", + "timestamp": null, + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Noodlecake_SuperStickmanGolf2_gpgs.png", + "title": "Super Stickman Golf 2 by Noodlecake Studios — Multiplayer", + "summary": "Noodlecake Studios finds that Google Play Game Services’ multiplayer feature helps reduce attrition.", + "keywords": ["stories"], + "type": "Case Study Deck", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/TinyRebel_DoctorWhoLegacy_gpgs.pdf", + "timestamp": null, + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/TinyRebelGames_DrWhoLegacy_pgps.png", + "title": "Dr. Doctor Who: Legacy by Tiny Rebel Games — Achievements", + "summary": "After integrating achievements and cloud services from Google Play Game Services, Tiny Rebel Games saw a dramatic increase in daily revenues as a result of an increase in daily installs and an increase in the average revenue per install.", + "keywords": ["stories"], + "type": "Case Study Deck", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Senri_LeosFortune_gpgs.pdf", + "timestamp": null, + "image": "https://storage.googleapis.com/androiddevelopers/shareables/stories/Senri_LeosFortune_gpgs.png", + "title": "Leo’s Fortune by 1337 & Senri — Saved games", + "summary": "1337 + Senri finds that Google Play Game Services is easy to integrate and provides essential game functions like cloud saved games, achievements and leaderboards which have a very large adoption rate amongst players.", + "keywords": ["stories"], + "type": "Case Study Deck", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "shareables/auto/AndroidAuto-audio-apps.pdf", + "timestamp": null, + "image": "auto/images/assets/icons/media_app_playback.png", + "title": "Android Auto Audio Apps UI Guidelines", + "summary": "Guidelines for designing audio apps that work with Auto. ", + "keywords": ["design", "Auto", "Automotive"], + "type": "Design", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "shareables/auto/AndroidAuto-messaging-apps.pdf", + "timestamp": null, + "image": "auto/images/assets/icons/messaging_app_notifications.png", + "title": "Android Auto Messaging Apps UI Guidelines", + "summary": "Guidelines for designing messaging apps that work with Auto. ", + "keywords": ["design", "Auto", "Automotive"], + "type": "Design", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "shareables/auto/AndroidAuto-custom-colors.pdf", + "timestamp": null, + "image": "auto/images/ui/gearhead_generic_UI.png", + "title": "Android Auto Color Customization UI Guidelines", + "summary": "Guidelines for color-customizing apps that work with Auto. ", + "keywords": ["design", "Auto", "Automotive"], + "type": "Design", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/analytics/solutions/mobile-implementation-guide", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Mobile Analytics Implementation Guide", + "summary": "Learn how you can implement additional Google Analytics features to better understand your users and their behavior.", + "keywords": ["analytics", "Play", "users"], + "type": "distribute", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://www.google.com/tagmanager/", + "timestamp": null, + "image": "https://www.google.com/tagmanager/images/gtm-hero-illustration-small.png", + "title": "Google Tag Manager", + "summary": "Google Tag Manager enables you to change configuration values in your mobile apps using the Google Tag Manager interface, without having to rebuild and resubmit application binaries to app marketplaces.", + "keywords": ["analytics", "tagmanager"], + "type": "distribute", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://analyticsacademy.withgoogle.com/course04", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Mobile App Analytics Fundamentals", + "summary": "This self-paced online course on mobile app measurement shows you how Google Analytics data can help you make your app more discoverable and profitable.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://github.com/googleanalytics/google-analytics-plugin-for-unity", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Analytics Plugin for Unity", + "summary": "If you're building games with Unity, you can now implement Analytics once and ship it on multiple platforms automatically.", + "keywords": ["analytics", "unity"], + "type": "Open Source Project", + "category": "" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/analytics/devguides/collection/android/v4/enhanced-ecommerce", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "In-App Purchases & Ecommerce", + "summary": "If your app sells virtual or real goods, ecommerce tracking can help you understand what behaviors lead to purchases.", + "keywords": ["analytics, ecommerce"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/analytics/answer/1032415", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Goals", + "summary": "Track important actions in your app as goals and measure performance against your objectives.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/analytics/answer/2568874?ref_topic=6012392", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Active Users", + "summary": "The active user report displays your 1-day, 7-day, 14-day and 30-day trailing active users next to each other, to help you analyze performance over time.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/analytics/devguides/collection/android/v4/events", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Events", + "summary": "Events let you measure granular in-app activities and understand user journeys.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/analytics/devguides/collection/android/v4/customdimsmets", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Custom Dimensions", + "summary": "Custom dimensions enable the association of metadata with hits, users, and sessions in Google Analytics.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/analytics/devguides/collection/android/v4/user-id", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "User ID", + "summary": "The User ID feature enables Google Analytics to measure user activities that span across devices.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/analytics/devguides/collection/android/v4/display-features", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Demographic Reporting", + "summary": "By enabling display features, you can see just how different user segments engage and monetize.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/analytics/answer/3123906", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "User Segmentation", + "summary": "Segments let you compare metrics for different subsets of users to identify trends and opportunities for your apps.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/analytics/devguides/collection/android/v4/campaigns", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Campaign Tracking", + "summary": "Measuring campaigns in Google Analytics enables the attribution of campaigns and traffic sources to user activity within your app.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/analytics/answer/2956981", + "timestamp": null, + "image": "images/cards/google-play_2x.png", + "title": "Google Play Integration", + "summary": "By linking Analytics and the Play Developer Console, you can gain additional insights into the acquisition flow.", + "keywords": ["play, analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/analytics/answer/1033961", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "AdWords Integration", + "summary": "Link Analytics and AdWords to see the entire picture of customer behavior, from ad click or impression through your site to conversion. ", + "keywords": ["adwords, analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/analytics/devguides/collection/android/v4/campaigns#google-play-url-builder", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Campaign URL builder for Google Play", + "summary": "Easily create your URLs to track install campaigns.", + "keywords": ["play, analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/tagmanager/answer/6003007", + "timestamp": null, + "image": "https://www.google.com/tagmanager/images/gtm-hero-illustration-small.png", + "title": "In-App A/B Testing", + "summary": "With content experiments in Google Tag Manager you can test multiple variations of your app to find which works best.", + "keywords": ["tagmanager"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/analytics/answer/2785577", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Behavior Flow", + "summary": "The Behavior Flow report visualizes the path users traveled from one Screen or Event to the next. This report can help you discover what content keeps users engaged with your app.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/analytics/answer/1151300", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Custom Reports", + "summary": "Custom Reports let you create your own reports in your Google Analytics account.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/analytics/answer/2611268", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Audience Lists & Remarketing", + "summary": "Remarketing with Google Analytics lets you deliver targeted ads to users who've already been to your site or app. You can even base those ads on the behavior those users displayed during their sessions.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/admob/answer/3508177", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "AdMob Integration", + "summary": "With Google Analytics in AdMob, you can view Google Analytics data for your linked apps from within your AdMob account.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/analytics/solutions/mobile-campaign-deep-link", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Deep-Linking", + "summary": "Google Analytics gives you a full view of how returning users are interacting with your app, for a holistic view beyond the install.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/admob/answer/3508177", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "AdMob Integration", + "summary": "With Google Analytics in AdMob, you can view Google Analytics data for your linked apps from within your AdMob account.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/analytics/answer/2568874", + "timestamp": null, + "image": "images/cards/analytics-mobile_2x.jpg", + "title": "Active User Report", + "summary": "Active user report displays your 1-day, 7-day, 14-day and 30-day trailing active users next to each other, to help you run benchmark analyses of their performance over time.", + "keywords": ["analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://www.google.com/design/spec/animation/", + "timestamp": null, + "image": "images/cards/material-animation_2x.png", + "title": "Animation", + "summary": "", + "keywords": [], + "type": "design", + "category": "material design" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://www.google.com/design/spec/style/", + "timestamp": null, + "image": "images/cards/material-style_2x.jpg", + "title": "Style", + "summary": "", + "keywords": [], + "type": "design", + "category": "material design" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://www.google.com/design/spec/layout/", + "timestamp": null, + "image": "images/cards/material-layout_2x.png", + "title": "Layout", + "summary": "", + "keywords": [], + "type": "design", + "category": "material design" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://www.google.com/design/spec/components/", + "timestamp": null, + "image": "images/cards/material-components_2x.jpg", + "title": "Components", + "summary": "", + "keywords": [], + "type": "design", + "category": "material design" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://www.google.com/design/spec/patterns/", + "timestamp": null, + "image": "images/cards/material-patterns_2x.png", + "title": "Patterns", + "summary": "", + "keywords": [], + "type": "design", + "category": "material design" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://www.google.com/design/spec/usability/", + "timestamp": null, + "image": "images/cards/material-usability_2x.png", + "title": "Usability", + "summary": "", + "keywords": [], + "type": "design", + "category": "material design" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://www.google.com/design/spec/resources/color-palettes.html", + "timestamp": null, + "image": "images/cards/material-color-palette_2x.jpg", + "title": "Color Palettes", + "summary": "", + "keywords": [], + "type": "design", + "category": "material design" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://www.google.com/design/spec/resources/layout-templates.html", + "timestamp": null, + "image": "images/cards/material-layout-template_2x.jpg", + "title": "Layout Templates", + "summary": "", + "keywords": [], + "type": "design", + "category": "material design" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://www.google.com/design/spec/resources/sticker-sheets-icons.html", + "timestamp": null, + "image": "images/cards/material-sticker-sheet_2x.jpg", + "title": "Sticker Sheets & Icons", + "summary": "", + "keywords": [], + "type": "design", + "category": "material design" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://www.google.com/design/spec/resources/roboto-noto-fonts.html", + "timestamp": null, + "image": "images/cards/material-typography_2x.jpg", + "title": "Typography: Roboto and Noto Sans fonts", + "summary": "", + "keywords": [], + "type": "design", + "category": "material design" + }, + { + "lang": "en", + "group": "", + "tags": [ + "icons", + "material", + "iconography" + ], + "url": "https://www.google.com/design/icons/index.html", + "timestamp": null, + "image": "images/cards/card-material-icons-16x9_2x.jpg", + "title": "Material icon collection", + "summary": "", + "keywords": ["icons"], + "type": "design", + "category": "material design" + }, + + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/adwords/answer/6032059", + "timestamp": null, + "image": "distribute/images/advertising.jpg", + "title": "Setting up Mobile App Install Ads", + "summary": "With Mobile app installs campaigns on the Search and Display Networks, and TrueView for mobile app promotion on YouTube, you can create custom app install ads that run exclusively on phones and tablets.", + "keywords": ["marketing", "admob"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/adwords/answer/6167164", + "timestamp": null, + "image": "distribute/images/advertising.jpg", + "title": "Best practices for Mobile App Engagement", + "summary": "Learn how to market to your user base to drive re-engagement with your app. ", + "keywords": ["marketing", "admob"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [ + "marketing", + "engagement", + "adwords1" + ], + "url": "https://support.google.com/adwords/answer/6032073", + "timestamp": null, + "image": "https://www.gstatic.com/images/icons/material/product/2x/adwords_64dp.png", + "title": "Setting up Mobile App Engagement Ads", + "summary": "Mobile app engagement campaigns are a great choice for advertisers focused on connecting with people who already have their app.", + "keywords": [ + "marketing", + "engagement", + "adwords" + ], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [ + "marketing", + "engagement" + ], + "url": "https://support.google.com/adwords/answer/6167162", + "timestamp": null, + "image": "https://www.gstatic.com/images/icons/material/product/2x/adwords_64dp.png", + "title": "Best Practices for Mobile App Installs", + "summary": "Getting your mobile app discovered can be challenging. Learn how to drive downloads of your app and grow a valuable user base.", + "keywords": ["marketing", "adwords"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/admob/topic/2784623", + "timestamp": null, + "image": "distribute/images/advertising.jpg", + "title": "Set up your AdMob account", + "summary": "Setting up your AdMob account in the right way will help you get the most value, check out the Setup and Basics guide.", + "keywords": ["marketing", "admob"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://analyticsacademy.withgoogle.com/mobile-app", + "timestamp": null, + "image": "distribute/images/advertising.jpg", + "title": "Analytics Academy for Mobile Apps", + "summary": "Learn how to use Google Analytics to make your app more discoverable and profitable.", + "keywords": ["marketing", "analytics"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/mobile-ads-sdk/download", + "timestamp": null, + "image": "distribute/images/advertising.jpg", + "title": "Admob Ads", + "summary": "Use the Mobile Ads SDK to start showing AdMob ads in your apps.", + "keywords": ["marketing", "adwords"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/admob/", + "timestamp": null, + "image": "distribute/images/advertising.jpg", + "title": "AdMob Help Center", + "summary": "For setup assistance, general info, and fixes for specific problems check out the AdMob Help Center.", + "keywords": ["admob"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://support.google.com/admob/answer/2753860", + "timestamp": null, + "image": "distribute/images/advertising.jpg", + "title": "AdMob Policy Guidelines", + "summary": "Learn about best practices for displaying AdMob ads in your apps to maximize revenue.", + "keywords": ["admob"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/app-invites/", + "timestamp": 1383243492000, + "image": "images/cards/google-search_2x.png", + "title": "Set up App Invites", + "summary": "Bring new users to your apps with personal recommendations, incentives, and offers.", + "keywords": ["invites", "appinvites", "engagement", "getusers"], + "type": "distribute", + "category": "google" + }, + + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/app-indexing/", + "timestamp": 1383243492000, + "image": "images/cards/google-search_2x.png", + "title": "Set Up App Indexing", + "summary": "Surface your app content in Google seaerch. Deep link direct to your apps.", + "keywords": ["search", "appindexing", "engagement", "getusers"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/app-indexing/webmasters/details", + "timestamp": null, + "image": "images/cards/google-search_2x.png", + "title": "Index your app", + "summary": "Index your app today by adding deep links and verifying its official web site to ensure it starts appearing in Google Search results. ", + "keywords": ["appindexing","search","getusers"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/identity/sign-in/android/people", + "timestamp": 1383243492000, + "image": "images/cards/google-sign-in_2x.png", + "title": "Get user profile details", + "summary": "After users sign-in with Google, you can access their age range, language, and public profile information.", + "keywords": ["signin", "identity", "google"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/identity/sign-in/android/", + "timestamp": "", + "image": "images/cards/google-sign-in_2x.png", + "title": "Google Sign-In", + "summary": "Discover how you can enhance user experiences on your website or in your app using information provided by their Google identity.", + "keywords": ["signin", "identity", "google"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/+/features/play-installs", + "timestamp": 1383243492000, + "image": "images/cards/google-sign-in_2x.png", + "title": "Over-the-air installs", + "summary": "Follow this step-by-step guide to quickly add Google Sign-in and over-the-air app installs to your website.", + "keywords": ["signin", "google", "installs"], + "type": "distribute", + "category": "google" + }, + { + "lang": "en", + "group": "", + "tags": [], + "url": "https://developers.google.com/+/features/analytics", + "timestamp": 1383243492000, + "image": 'images/google/gps-googleplus.png', + "title": "Google+ Insights", + "summary": "Measure impressions of the over-the-air install prompt, resulting installs, and success rate by day, week, and month.", + "keywords": ["signin", "identity"], + "type": "distribute", + "category": "google" + }, + + // Online courses + + { + "title":"UX Design for Mobile Developers", + "category":"online course", + "summary":"Learn how to design a 5-star app.", + "url":"https://www.udacity.com/course/ud849", + "group":"", + "keywords": ["mobile","ux","design"], + "tags": ["courses, start"], + "image":"images/cards/courses/mobile_ux_course.jpg", + "lang":"en", + "type":"design" + }, + { + "title":"Developing Android Apps", + "category":"online course", + "summary":"Learn Android and build an app!", + "url":"https://www.udacity.com/course/ud853", + "group":"", + "keywords": ["android", "start","firstapp","sdk"], + "tags": ["courses, start"], + "image":"images/cards/courses/android_fundamentals_course.jpg", + "lang":"en", + "type":"develop" + }, + { + "title":"Android Performance", + "category":"online course", + "summary":"Optimize your apps for speed and usability.", + "url":"https://www.udacity.com/course/ud825", + "group":"", + "keywords": ["android, performance","battery"], + "tags": ["courses, performance"], + "image":"images/cards/courses/android_performance_course.jpg", + "lang":"en", + "type":"develop" + }, + { + "title":"Enroll in the Android Nanodegree", + "category":"online course", + "summary":"Enroll in the Android Nanodegree to build the skills to work as an Android developer.", + "url":"https://www.udacity.com/android", + "group":"", + "keywords": ["android, nanodegree"], + "tags": ["courses"], + "image":"images/cards/courses/android_nanodegree.png", + "lang":"en", + "type":"develop" + }, + { + "title":"Advanced Android App Development", + "category":"online course", + "summary":"Productionize and publish your apps.", + "url":"https://www.udacity.com/course/ud855", + "group":"", + "keywords": ["android, experts"], + "tags": ["courses, expert"], + "image":"images/cards/courses/advanced_android_course.jpg", + "lang":"en", + "type":"develop" + }, + { + "title":"Material Design for Android Developers", + "category":"online course", + "summary":"Learn how to make your apps material.", + "url":"https://www.udacity.com/course/ud862", + "group":"", + "keywords": ["android, design, pure, material"], + "tags": ["courses, start, material"], + "image":"images/cards/courses/android_design_course.jpg", + "lang":"en", + "type":"design" + }, + { + "title":"Android for Beginners", + "category":"online course", + "summary":"Make your first Android app, even if you don't write code.", + "url":"https://www.udacity.com/course/ud837", + "group":"", + "keywords": ["android, sdk, firstapp"], + "tags": ["courses, start"], + "image":"images/cards/courses/beginning_android_course.jpg", + "lang":"en", + "type":"develop" + }, + { + "title":"Gradle for Android and Java", + "category":"online course", + "summary":"Build better apps through automation", + "url":"https://www.udacity.com/course/ud867", + "group":"", + "keywords": ["gradle","studio", "sdk"], + "tags": ["courses, gradle, sdk"], + "image":"images/cards/courses/gradle_course.jpg", + "lang":"en", + "type":"develop" + }, + { + "title":"Add Location and Context to your app", + "category":"online course", + "summary":"Make Your Android App Location Aware.", + "url":"https://www.udacity.com/course/ud876-1", + "group":"", + "keywords": ["google services, context, location"], + "tags": ["courses, google, location, context"], + "image":"images/cards/courses/android_location_course.png", + "lang":"en", + "type":"develop" + }, + { + "title":"Analytics and Tag Manager for Android", + "category":"online course", + "summary":"Use Analytics and Tag Manager in Your Apps.", + "url":"https://www.udacity.com/course/ud876-2", + "group":"", + "keywords": ["google services, analytics, tag manager"], + "tags": ["courses, google, analytics"], + "image":"images/cards/courses/android_analytics_course.png", + "lang":"en", + "type":"distribute" + }, + { + "title":"AdMob for Android", + "category":"online course", + "summary":"Monetize Your App by Displaying Ads.", + "url":"https://www.udacity.com/course/ud876-3", + "group":"", + "keywords": ["monetize, google services, ads, admob"], + "tags": ["courses, google, ads, admob"], + "image":"images/cards/courses/admob_course.png", + "lang":"en", + "type":"distribute" + }, + { + "title":"Add Maps to your Android app", + "category":"online course", + "summary":"Use maps, cameras, markers and more in your app.", + "url":"https://www.udacity.com/course/ud876-4", + "group":"", + "keywords": ["google, maps, marker, camera"], + "tags": ["courses, google, maps"], + "image":"images/cards/courses/android_maps_course.png", + "lang":"en", + "type":"develop" + }, + { + "title":"Add Sign-in to your Android app", + "category":"online course", + "summary":"Build a Seamless Sign-In Experience.", + "url":"https://www.udacity.com/course/ud876-5", + "group":"", + "keywords": ["google services, signin, authorization"], + "tags": ["courses, google, auth"], + "image":"images/cards/courses/android_identity_course.png", + "lang":"en", + "type":"develop" + }, + { + "title":"Android Wear Development", + "category":"online course", + "summary":"Extend your Apps to Android Smartwatches.", + "url":"https://www.udacity.com/course/ud875A", + "group":"", + "keywords": ["wear, wearables, smartwatch"], + "tags": ["courses, wear, wearable"], + "image":"images/cards/courses/android_wear_course.jpg", + "lang":"en", + "type":"develop" + }, + { + "title":"Android TV and Google Cast Development", + "category":"online course", + "summary":"Extend your Apps to the Big Screen.", + "url":"https://www.udacity.com/course/ud875B", + "group":"", + "keywords": ["cast, living room"], + "tags": ["courses, cast, tv"], + "image":"images/cards/courses/android_tv_cast_course.jpg", + "lang":"en", + "type":"develop" + }, + { + "title":"Android Auto Development", + "category":"online course", + "summary":"Put your apps in the driver's seat.", + "url":"https://www.udacity.com/course/ud875C", + "group":"", + "keywords": ["auto"], + "tags": ["courses, auto"], + "image":"images/cards/courses/android_auto_course.jpg", + "lang":"en", + "type":"develop" + }, + + + // TODO remove this? + { + "title":"Android Wear Materials", + "category":"design", + "summary":"Drag and drop your way to beautifully designed Android Wear apps.", + "url":"design/downloads/index.html#Wear", + "group":"", + "keywords": ["icons","stencils","color swatches"], + "tags": ["icons","stencils","colorswatches"], + "image":"images/cards/android-wear-materials_2x.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Watch Faces for Android Wear", + "category":"design", + "summary":"Watch faces let you customize the most prominent UI feature of Android wearables. The API is simple enough for rapid development and flexible enough to build something awesome.", + "url":"https://www.youtube.com/watch?v=AK38PJZmIW8&list=PLWz5rJ2EKKc-kIrPiq098QH9dOle-fLef", + "group":"", + "keywords": ["wear", "wearable", "watch face"], + "tags": [], + "image":"https://i1.ytimg.com/vi/AK38PJZmIW8/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Android Support Library", + "category":"Tools", + "summary":"These essential components help you build a great app that works on the huge variety of Android devices, faster.", + "url":"https://www.youtube.com/watch?v=3PIc-DuEU2s&list=PLWz5rJ2EKKc9e0d55YHgJFHXNZbGHEXJX", + "group":"", + "keywords": ["support", "compatibility"], + "tags": [], + "image":"https://i1.ytimg.com/vi/3PIc-DuEU2s/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Consistent Design with the AppCompat Support Library", + "category":"design", + "summary":"Getting a great looking app doesn't have to be hard: AppCompat, part of the Android Support Library, gives you a consistent design baseline that works on all Android 2.1 or higher devices.", + "url":"https://www.youtube.com/watch?v=5Be2mJzP-Uw&list=PLWz5rJ2EKKc9e0d55YHgJFHXNZbGHEXJX", + "group":"", + "keywords": ["support", "compatibility","design-code"], + "tags": [], + "image":"https://i1.ytimg.com/vi/5Be2mJzP-Uw/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Introducing Gradle", + "category":"tools", + "summary":"Android Studio uses an entirely new and flexible Gradle-based build system. You will be able to create multiple build variants for a single project, manage library dependencies and always be sure that your application builds correctly across different environments.", + "url":"https://www.youtube.com/watch?v=cD7NPxuuXYY&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ", + "group":"", + "keywords": ["tools", "studio","gradle"], + "tags": [], + "image":"https://i1.ytimg.com/vi/cD7NPxuuXYY/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Android Studio Layout Editor", + "category":"tools", + "summary":"Android Studio includes a rich, visual layout editor that helps developers create better user interfaces. It eliminates the need to deploy the APK on a real device with each change, making iterations faster and helping eliminate common errors earlier in the development process.", + "url":"https://www.youtube.com/watch?v=JLLnhwtDoHw&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ", + "group":"", + "keywords": ["tools", "studio","layout"], + "tags": [], + "image":"https://i1.ytimg.com/vi/JLLnhwtDoHw/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Debugging and testing in Android Studio", + "category":"tools", + "summary":"Learn about new debugger features in Android Studio 1.2: value inlining, quick access to referring objects and a Java .class decompiler, just to name a few. See some new tools and views that let you monitor the CPU and memory performance of your app from within the IDE. ", + "url":"https://www.youtube.com/watch?v=2I6fuD20qlY&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ", + "group":"", + "keywords": ["tools", "studio","debugging","profiling","performance"], + "tags": [], + "image":"https://i1.ytimg.com/vi/2I6fuD20qlY/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Scale with Google Cloud Platform", + "category":"google", + "summary":"Build, test, and deploy applications on Google's highly-scalable and reliable infrastructure for your web, mobile and backend solutions.", + "url":"https://cloud.google.com/docs/", + "group":"", + "keywords": [], + "tags": [], + "image":"images/cards/cloud-platform_2x.png", + "lang":"en", + "type":"distribute" + }, + { + "title":"Opportunities & Programs", + "category":"Google Play", + "summary":"Take advantage of the many ways you can distribute your app to consumers, students, and businesses through Google Play.", + "url":"distribute/googleplay/index.html#opportunities", + "group":"", + "keywords": [], + "tags": [], + "image":"images/cards/program-edu_2x.jpg", + "lang":"en", + "type":"distribute" + }, + { + "title":"Android for Work", + "category":"Enterprise", + "summary":"Learn more about how Android for Work makes your favorite phones and tablets the perfect business tools.", + "url":"https://www.android.com/work/", + "group":"", + "keywords": ["work", "enterprise", "emm"], + "tags": [], + "image":"images/cards/card-android-work_2x.png", + "lang":"en", + "type":"about" + }, + { + "title":"Android for Work DevBytes", + "category":"Enterprise", + "summary":"Watch the videos in this playlist to understand more about Android for Work and get tips on developing enterprise apps.", + "url":"https://www.youtube.com/watch?v=jQWB_-o1kz4&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX", + "group":"", + "keywords": ["work", "enterprise", "emm"], + "tags": [], + "image":"https://i1.ytimg.com/vi/jQWB_-o1kz4/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"App Configurations, Testing and Launchers", + "category":"Enterprise", + "summary":"With Android for Work you can make your apps remotely configurable. We also cover how to test your app in a managed environment.", + "url":"https://www.youtube.com/watch?v=39NkpWkaH8M&index=2&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX", + "group":"", + "keywords": ["work", "enterprise", "emm"], + "tags": [], + "image":"https://i1.ytimg.com/vi/39NkpWkaH8M/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Building an enterprise ready app", + "category":"Enterprise", + "summary":"A holistic view of Android for Work for developers.", + "url":"https://www.youtube.com/watch?v=dH41OutAMNM", + "group":"", + "keywords": ["work", "enterprise", "emm"], + "tags": [], + "image":"https://i1.ytimg.com/vi/dH41OutAMNM/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Android for Work: Single Use Devices", + "category":"Enterprise", + "summary":"Single-purpose computers are everywhere, and Android can meet that need.", + "url":"https://www.youtube.com/watch?v=j3QC6hcpy90", + "group":"", + "keywords": ["work", "enterprise", "emm"], + "tags": [], + "image":"https://i1.ytimg.com/vi/j3QC6hcpy90/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Discover YouTube cards", + "category":"google", + "summary":"Find out more about YouTube cards, the options available, and how to use them to get the most from your YouTube content.", + "url":"https://support.google.com/youtube/answer/6140493", + "group":"", + "keywords": ["youtube", "video", "users", "installs"], + "tags": [], + "image":"images/cards/card-youtube_2x.png", + "lang":"en", + "type":"distribute" + }, + { + "title":"What is YouTube account good standing?", + "category":"Google", + "summary":"Learn what it means for an account to be in good standing from the YouTube Help Center.", + "url":"https://support.google.com/youtube/answer/2797387", + "group":"", + "keywords": ["youtube", "video", "users", "installs"], + "tags": [], + "image":"images/cards/card-youtube_2x.png", + "lang":"en", + "type":"distribute" + }, + { + "title":"Developing for Android 6.0 (Marshmallow)", + "category":"", + "summary":"This video covers how to get started with the preview, important APIs to test and how to provide feedback on the preview.", + "url":"https://www.youtube.com/watch?v=yYU4DHLwoRk", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/yYU4DHLwoRk/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Google I/O 2015 - What's new in Android", + "category":"", + "summary":"This session will highlight the most exciting new developer features of the Android platform.", + "url":"https://www.youtube.com/watch?v=ndBdf1_oOGA", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/ndBdf1_oOGA/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Fingerprint and payments APIs", + "category":"", + "summary":"New fingerprint and payments APIs are introduced in M, to enable enhanced UX and security for online purchasing, banking, and retail payments.", + "url":"https://www.youtube.com/watch?v=VOn7VrTRlA4", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/VOn7VrTRlA4/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Introduction to Voice Interaction API", + "category":"", + "summary":"This video covers how to use the Voice Interaction API to support system or custom voice actions.", + "url":"https://www.youtube.com/watch?v=OW1A4XFRuyc", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/OW1A4XFRuyc/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"Android Auto Backup for Apps", + "category":"", + "summary":"Android Backup is the automatic, cloud-based backup and restore of users’ apps when they set up a new device.", + "url":"https://www.youtube.com/watch?v=HXacyy0HSW0", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/HXacyy0HSW0/maxresdefault.jpg", + "lang":"en", + "type":"video" + }, + { + "title":"New APIs in M for Android for Work", + "category":"", + "summary":"Android M extends Android for Work functionality with a new set of APIs for Enterprise Mobility Management providers to offer new features and policy controls to IT Departments.", + "url":"https://www.youtube.com/watch?v=vcSj8ln-BlE", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/vcSj8ln-BlE/maxresdefault.jpg", + "lang":"en", + "type":"Video" + }, + { + "title":"Android for Work: Single Use Devices", + "category":"", + "summary":"Android M is bringing the power of Android to all kinds of workplaces.", + "url":"https://www.youtube.com/watch?v=j3QC6hcpy90", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/j3QC6hcpy90/maxresdefault.jpg", + "lang":"en", + "type":"Video" + }, + { + "title":"Runtime Permissions in Android 6.0 Marshmallow", + "category":"", + "summary":"Learn how to integrate runtime permissions into your Android app.", + "url":"https://www.youtube.com/watch?v=C8lUdPVSzDk", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/C8lUdPVSzDk/maxresdefault.jpg", + "lang":"en", + "type":"Video" + }, + { + "title":"Introduction to Doze", + "category":"", + "summary":"An overview of Doze and how to make sure that your app behaves as expected both in and out of Doze mode. ", + "url":"https://youtu.be/N72ksDKrX6c", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/N72ksDKrX6c/maxresdefault.jpg", + "lang":"en", + "type":"Video" + }, + { + "title":"The Nexus 5X, Nexus 6P and Android Marshmallow", + "category":"", + "summary":"The new Nexus 5X and Nexus 6P along with some of the most significant developer features in the latest Android release,.", + "url":"https://youtu.be/U9tw5ypqEN0", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/U9tw5ypqEN0/maxresdefault.jpg", + "lang":"en", + "type":"Video" + }, + { + "title":"Asking For Permission", + "category":"", + "summary":"Picking the right way and time to ask for a permission is critical to it being granted. ", + "url":"https://youtu.be/iZqDdvhTZj0", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/iZqDdvhTZj0/maxresdefault.jpg", + "lang":"en", + "type":"Video" + }, + { + "title":"Data Binding Library", + "category":"", + "summary":"Data Binding Library is a way to write declarative layouts and minimize the glue code necessary to bind your application logic and layouts. ", + "url":"https://youtu.be/5sCQjeGoE7M", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/5sCQjeGoE7M/maxresdefault.jpg", + "lang":"en", + "type":"Video" + }, + { + "title":"App Links", + "category":"", + "summary":"App Links is a new feature of Android Marshmallow that brings a faster way of opening website links for domains that you own.", + "url":"https://youtu.be/LQoohRwojmw", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/LQoohRwojmw/maxresdefault.jpg", + "lang":"en", + "type":"Video" + }, + { + "title":"Android M Permissions", + "category":"", + "summary":"An introduction to Android M runtime permissions in Android M from Google I/O 2015. ", + "url":"https://www.youtube.com/watch?v=f17qe9vZ8RM", + "group":"", + "keywords": ["Marshmallow"], + "tags": [], + "image":"https://i1.ytimg.com/vi/f17qe9vZ8RM/maxresdefault.jpg", + "lang":"en", + "type":"Video" + }, + { + "url":"https://www.youtube.com/watch?v=QDM52bblwlg", + "image": "images/distribute/hero-family-discovery.jpg", + "title": "Introducing the new family discovery experience on Google Play", + "summary": "Help families create little moments on Google Play. Opt-in your apps now.", + "tags":["families","googleplay"], + "type":"video" + }, + { + "url":"https://www.youtube.com/watch?v=wcjqBSei3a0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", + "image": "https://i1.ytimg.com/vi/wcjqBSei3a0/maxresdefault.jpg", + "title": "Developers connecting the world through Google Play", + "summary": "The mobile ecosystem is empowering developers to make good on the dream of connecting the world through technology to improve people's lives.", + "tags":["io15","googleplay"], + "keywords":["Google I/O 2015","io"], + "type":"video" + }, + { + "url":"https://www.youtube.com/watch?v=B6ydLpkhq04&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", + "image": "https://i1.ytimg.com/vi/B6ydLpkhq04/maxresdefault.jpg", + "title": "Store Listing Experiments for Google Play", + "summary": "Learn how to use Google Play’s new store listing optimization feature to get more installs of your app, and how to test different graphics and text to find out which options perform the best. ", + "tags":["io15","googleplay","store listing"], + "tags":["google i/o","google play","store listing"], + "type":"video" + }, + { + "url":"https://www.youtube.com/watch?v=jyO3-rF4Mu0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", + "image": "https://i1.ytimg.com/vi/jyO3-rF4Mu0/maxresdefault.jpg", + "title": "Growing games with Google", + "summary": "The games industry has never been more promising and full of opportunities. This talk covers how Google is helping developers across a broad range of existing and emerging platforms.", + "tags":["io15","android", "googleplay","games"], + "keywords":["Google I/O","google play","games"], + "type":"video" + }, + { + "url":"https://www.youtube.com/watch?v=yJisuP94lHU", + "image": "images/distribute/hero-playtime-opener.jpg", + "title": "Playtime 2015: Innovation happens everywhere", + "type":"Video", + "tags":["googleplay"], + "summary": "Watch the opening video from Google Play's annual event series, Playtime, which celebrates inspirational developers who are changing the world around them.", + }, + { + "url":"https://www.youtube.com/watch?v=JrR6o5tYMWQ", + "image": "images/distribute/hero-acquisition-devbyte.jpg", + "title": "User acquisition and tracking on Google Play", + "type" : "Video", + "tags" : "users,googleplay,googleio", + "summary": "Learn how to get new users, using Universal app campaigns directly within the Google Play Developer Console to increase your installs from ads, and find out how your acquisition channels perform.", + }, + { + "url":"panel1", + "image": "", + "title": "", + "type" : "", + "tags" : "", + "summary": "", + }, + { + "url":"panel2", + "image": "", + "title": "", + "type" : "", + "tags" : "", + "summary": "", + }, + { + "url":"panel3", + "image": "", + "title": "", + "type" : "", + "tags" : "", + "summary": "", + }, + { + "url":"panel4", + "image": "", + "title": "", + "type" : "", + "tags" : "", + "summary": "", + } +]); + +/** + * Metadata overrides for carousels/heros. + */ +METADATA['en'].carousel = { + "panel2": { + "image": "images/tools/and-studio_shortcuts-included_2x.png", + "title": "Shortcuts included", + "type":"Android Studio", + "heroColor": "#fff", + "url":"", + "summary": "No need to start from scratch, Android Studio includes prebuilt template patterns from navigation drawers to view pagers and GitHub integration to help guide you along quickly.", + }, + "panel4": { + "image": "images/tools/and-studio_feat-gradle_2x.png", + "title": "Evolved Android builds, with Gradle", + "type":"Android Studio", + "heroColor": "#fff", + "summary": "Create multiple APKs for your Android app with different features using the same project. Manage app dependencies with Maven. Build APKs from Android Studio or the command line.", + }, + "panel1": { + "image": "images/tools/codeeditor-low.gif", + "title": "Fast, intelligent coding", + "type":"Android Studio", + "heroColor": "#fff", + "summary": "Advanced code completion, refactoring and code analysis in an environment that’s purpose-built for Android, the powerful code editor helps you be a more productive Android app developer.", + }, + "panel3": { + "image": "images/tools/studio-hero-screens_2x.png", + "title": " All shapes, sizes and scenarios", + "type":"Android Studio", + "heroColor": "#fff", + "summary": "Create multiple APKs for your Android app with different features using the same project. Manage app dependencies with Maven. Build APKs from Android Studio or the command line.", + }, + "distribute/googleplay/guide.html": { + "image": "images/distribute/hero-secrets-to-app-success.jpg", + "title": "Secrets to App Success on Google Play", + "summary": "Get the updated guide full of useful features, tips, and best practices that will help you grow a successful app or game business on Google Play.", + }, + "about/versions/lollipop.html": { + "image": "images/home/hero-lollipop_2x.png", + "heroColor": "#263238", + "heroInvert": true, + "title": "Android 5.0 Lollipop", + "summary": "The Android 5.0 update adds a variety of new features for your apps, such as notifications on the lock screen, an all-new camera API, OpenGL ES 3.1, the new naterial design interface, and much more.", + }, + "https://www.youtube.com/watch?v=yJisuP94lHU": { + "url":"https://www.youtube.com/watch?v=yJisuP94lHU&index=1&list=PLWz5rJ2EKKc_QRBk7Zkl5uGjR1He7vG-w", + "image": "images/distribute/hero-playtime-opener.jpg", + "title": "Playtime 2015: Innovation happens everywhere", + "type":"video", + "summary": "Watch the opening video from Google Play's annual event series, Playtime, which celebrates inspirational developers who are changing the world around them.", + }, + "http://www.youtube.com/watch?v=rcU7VEs1hiE": { + "url":"https://www.youtube.com/watch?v=rcU7VEs1hiE&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-rogervoice-story.jpg", + "title": "RogerVoice uses beta testing to launch on Android first", + "type" : "youtube", + "summary": "RogerVoice helps people who are hearing impaired make phone calls through voice recognition and text captions. Hear how they used material design and beta testing to create a UI that's accessible and intuitive to navigate.", + }, + "http://www.youtube.com/watch?v=JFlX9rW7Epc": { + "url":"https://www.youtube.com/watch?v=JFlX9rW7Epc&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-domain-story.jpg", + "title": "Domain increases installs by 44% with Material Design", + "type" : "youtube", + "summary": "Learn how Domain, a premier real-estate portal in Australia, drastically improved their Google Play app reviews, ratings and downloads by investing in their Android app experience.", + }, + "http://www.youtube.com/watch?v=4CqXCkcN_d4": { + "url":"https://www.youtube.com/watch?v=4CqXCkcN_d4&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-dots-story.jpg", + "title": "Dots increases installs with Store Listing Experiments", + "type" : "youtube", + "summary": "Hear how US-founded game developer, Dots, used the Store Listing Experiments feature in the Google Play Developer Console to test what icon, graphics, and text worked the best at converting visitors to installs.", + }, + "https://www.youtube.com/watch?v=JrR6o5tYMWQ": { + "url":"https://www.youtube.com/watch?v=JrR6o5tYMWQ", + "image": "images/distribute/hero-acquisition-devbyte.jpg", + "title": "User acquisition and tracking on Google Play", + "type" : "youtube", + "summary": "Learn how to get new users, using Universal app campaigns directly within the Google Play Developer Console to increase your installs from ads, and find out how your acquisition channels perform.", + }, + "https://www.youtube.com/watch?v=Pd49vTkvu0U": { + "url":"https://www.youtube.com/watch?v=Pd49vTkvu0U&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-jelly-button.jpg", + "title": "How Jelly Button Games are growing globally through data", + "summary": "To really understand their users, Jelly Button Games analyzes over 3 billion events each month using Google Analytics and Google BigQuery.", + }, + "https://www.youtube.com/watch?v=700gYRkhkLM": { + "url":"https://www.youtube.com/watch?v=700gYRkhkLM&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-outfit7.jpg", + "title": "Outfit7 — Building an entertainment company with Google", + "summary": "Outfit7, creators of My Talking Tom and My Talking Angela, offer a complete entertainment experience to users spanning mobile apps, user generated and original YouTube content, and a range of toys, clothing, and accessories....", + }, + "https://www.youtube.com/watch?v=MPnH7h12h0U": { + "url":"https://www.youtube.com/watch?v=MPnH7h12h0U&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-haystack.jpg", + "summary": "Haystack TV built a scalable business with six employees and Android TV. Two weeks was all it took for them to bring their mobile app to the big screen.", + }, + "https://www.youtube.com/watch?v=ekxABqJeRBc": { + "url":"https://www.youtube.com/watch?v=ekxABqJeRBc&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-ginlemon.jpg", + "title": "How GinLemon is breaking through with Google Play", + "summary": "Meet Vincenzo Colucci, developer and founder of GinLemon, which started as a summer holiday joke and has now become a successful global app business on Google Play based in Manfredonia, southern Italy.", + }, + "https://www.youtube.com/watch?v=0r36OJaeMo4": { + "url":"https://www.youtube.com/watch?v=0r36OJaeMo4&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-shifty-jelly.jpg", + "title": "Shifty Jelly — building a number 1 podcast app", + "summary": "Shifty Jelly is an Adelaide based mobile development company that has seen great success building Pocket Casts, a premium podcast manager app.", + }, + "https://www.youtube.com/watch?v=1Iw7Tg_afKk": { + "image": "images/distribute/hero-wooga.jpg", + "url":"https://www.youtube.com/watch?v=1Iw7Tg_afKk&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "title": "Wooga’s fast iterations on Google Play", + "summary": "The speed at which Wooga is able to iterate its live and under development games with the Android and Google Play tools has been key to delivering hits such as Diamond Dash, Jelly Splash, and Agent Alice.", + }, + "https://www.youtube.com/watch?v=TieksFvD-7o": { + "url":"https://www.youtube.com/watch?v=TieksFvD-7o&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-trello.jpg", + "title": "Trello lifts engagement by double digits with material design", + "summary": "Trello recently redesigned their collaborative planning app using the material design guidelines, and their efforts paid off.", + }, + "https://www.youtube.com/watch?v=MCoh4Pxs_ok": { + "url":"https://www.youtube.com/watch?v=MCoh4Pxs_ok&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-the-hunt.jpg", + "title": "The Hunt — growing engagement with material design and Google Play", + "summary": "Material design has helped The Hunt to enhance engagement in their style advice and product discovery app. ", + }, + "https://www.youtube.com/watch?v=QDM52bblwlg": { + "url":"distribute/googleplay/families/about.html", + "image": "images/distribute/hero-family-discovery.jpg", + "title": "Designed for families", + "summary": "Introducing the new family discovery experience in Google Play. Your apps can benefit from enhanced discoverability and maintain their existing categories, rankings, and reviews elsewhere in the store. Opt-in your apps today.", + "type":"distribute", + }, + "https://www.youtube.com/watch?v=wcjqBSei3a0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS": { + "url":"https://www.youtube.com/watch?v=wcjqBSei3a0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", + "image": "images/distribute/hero-IO15-google-play.jpg", + "title": "Connecting the world through Google Play", + "tags":["io15"], + "summary": "In this this Google I/O talk, hear how the mobile ecosystem is empowering developers to connect the world through technology and improve people's lives.", + }, + "https://www.youtube.com/watch?v=B6ydLpkhq04&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS": { + "image": "images/distribute/hero-store-listing-experience.jpg", + "title": "Using Google Play store listing experiments", + "tags":["io15"], + "summary": "Learn how to use Google Play store listing experiments to get more installs in this Google I/O talk. Test different graphics and text to find out which options perform the best. ", + }, + "https://www.youtube.com/watch?v=jyO3-rF4Mu0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS": { + "image": "images/distribute/hero-IO15-growing-games.jpg", + "title": "Growing games with Google", + "tags":["io15"], + "summary": "The games industry has never been more promising and full of opportunities. This talk from Google I/O 2015 covers how Google is helping developers across a broad range of existing and emerging platforms.", + }, +}; + +/** + * Static metadata collections. + */ +METADATA['en'].collections = { + "index/carousel": { + "title": "", + "resources": [ + "about/versions/lollipop.html" + ] + }, + "index/primary": { + "title": "", + "resources": [ + "training/building-wearables.html", + "training/material/index.html", + "sdk/index.html" + ] + }, + "index/secondary/carousel": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=yJisuP94lHU", + "http://www.youtube.com/watch?v=rcU7VEs1hiE", + "http://www.youtube.com/watch?v=JFlX9rW7Epc", + "http://www.youtube.com/watch?v=4CqXCkcN_d4" + ] + }, + "index/multiscreen": { + "title": "", + "resources": [ + "wear/index.html", + "tv/index.html", + "auto/index.html" + ] + }, + "design/landing/latest": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=p4gmvHyuZzw", + "https://www.youtube.com/watch?v=YaG_ljfzeUw", + "https://www.youtube.com/watch?v=XOcCOBe8PTc" + ] + }, + "design/landing/materialdesign": { + "title": "", + "resources": [ + "https://www.google.com/design/spec/animation/", + "https://www.google.com/design/spec/style/", + "https://www.google.com/design/spec/layout/", + "https://www.google.com/design/spec/components/", + "https://www.google.com/design/spec/patterns/", + "https://www.google.com/design/spec/usability/" + ] + }, + "design/landing/pureandroid": { + "title": "", + "resources": [ + "design/get-started/creative-vision.html", + "design/material/index.html", + "training/material/index.html", + "design/patterns/pure-android.html", + "design/patterns/new.html", + "design/devices.html" + ] + }, + "design/landing/resources": { + "title": "", + "resources": [ + "https://www.google.com/design/spec/resources/color-palettes.html", + "https://www.google.com/design/spec/resources/layout-templates.html", + "https://www.google.com/design/spec/resources/sticker-sheets-icons.html", + "https://www.google.com/design/spec/resources/roboto-noto-fonts.html", + "https://www.google.com/design/icons/index.html", + "design/downloads/index.html#Wear" + ] + }, + "develop/landing/mainlinks": { + "title": "", + "resources": [ + "tools/studio/index.html", + "samples/new/index.html", + "tools/projects/templates.html" + ] + }, + "develop/landing/latest": { + "title": "", + "resources": [ + "https://android-developers.blogspot.com/2015/04/new-android-code-samples.html", + "https://android-developers.blogspot.com/2015/04/android-support-library-221.html", + "https://android-developers.blogspot.com/2015/03/a-new-reference-app-for-multi-device.html" + ] + }, + "develop/landing/devpatterns": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=kmUGLURRPkI", + "https://www.youtube.com/watch?v=HGElAW224dE", + "https://www.youtube.com/watch?v=zQekzaAgIlQ" + ] + }, + "develop/landing/performance": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=fEEulSk1kNY", + "https://www.youtube.com/watch?v=-3ry8PxcJJA", + "https://www.youtube.com/watch?v=_kKTGK-Cb_4" + ] + }, + "develop/landing/buildwithgoogle": { + "title": "", + "resources": [ + ] + }, + "develop/landing/ubicomp": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=AK38PJZmIW8&list=PLWz5rJ2EKKc-kIrPiq098QH9dOle-fLef", + "https://www.youtube.com/watch?v=6K_jxccHv5M&index=1&list=PLOU2XLYxmsILFBfx66ens76VMLMEPJAB0", + "https://www.youtube.com/watch?v=ctiaVxgclsg&list=PLWz5rJ2EKKc9BdE_PSLNIGjXXr3h_orXM" + ] + }, + "develop/landing/tools": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=K2dodTXARqc&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ", + "https://www.youtube.com/watch?v=3PIc-DuEU2s&list=PLWz5rJ2EKKc9e0d55YHgJFHXNZbGHEXJX", + "https://www.youtube.com/watch?v=cD7NPxuuXYY&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ", + "https://www.youtube.com/watch?v=JLLnhwtDoHw&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ", + "https://www.youtube.com/watch?v=2I6fuD20qlY&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ", + "https://www.youtube.com/watch?v=5Be2mJzP-Uw&list=PLWz5rJ2EKKc9e0d55YHgJFHXNZbGHEXJX" + ] + }, + "google/landing/services": { + "title": "", + "resources": [ + "https://developers.google.com/analytics/devguides/collection/android/", + "https://developers.google.com/maps/documentation/android/", + "https://developers.google.com/identity/sign-in/android/", + "https://developers.google.com/mobile-ads-sdk/download", + "https://developers.google.com/cloud-messaging/gcm", + "https://developers.google.com/app-indexing/" + ] + }, + "google/landing/videos": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=M3Udfu6qidk&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf", + "https://www.youtube.com/watch?v=FOn64iqlphk&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf", + "https://www.youtube.com/watch?v=F0Kh_RnSM0w&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf", + "https://www.youtube.com/watch?v=fvtMtfCuEpw&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf" + ] + }, + "google/landing/googleplay": { + "title": "", + "resources": [ + "google/play/billing/index.html", + "google/play/billing/billing_subscriptions.html", + "google/play/developer-api.html" + ] + }, + "develop/landing/courses": { + "title": "", + "resources": [ + "https://www.udacity.com/course/ud849", + "https://www.udacity.com/course/ud853", + "https://www.udacity.com/course/ud825", + "https://www.udacity.com/android", + "https://www.udacity.com/course/ud855", + "https://www.udacity.com/course/ud875A", + "https://www.udacity.com/course/ud875B", + "https://www.udacity.com/course/ud875C", + "https://www.udacity.com/course/ud876--1", + "https://www.udacity.com/course/ud876--2", + "https://www.udacity.com/course/ud876--3", + "https://www.udacity.com/course/ud876--4", + "https://www.udacity.com/course/ud876--5", + "https://www.udacity.com/course/ud862", + "https://www.udacity.com/course/ud837", + "https://www.udacity.com/course/ud867" + ] + }, + "distribute/landing/carousel": { + "title": "", + "resources": [ + "distribute/googleplay/guide.html", + "https://www.youtube.com/watch?v=JrR6o5tYMWQ", + "https://www.youtube.com/watch?v=B6ydLpkhq04&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", + "https://www.youtube.com/watch?v=yJisuP94lHU", + ] + }, + "distribute/landing/googleplay": { + "title": "", + "resources": [ + "distribute/googleplay/about.html", + "distribute/googleplay/developer-console.html", + "distribute/googleplay/index.html#opportunities" + ] + }, + "distribute/landing/more": { + "title": "", + "resources": [ + "distribute/users/promote-with-ads.html", + "distribute/monetize/ads.html", + "distribute/analyze/index.html", + "distribute/engage/deep-linking.html", + "distribute/engage/easy-signin.html", + "https://cloud.google.com/docs/" + ] + }, + "distribute/edu/videos/stories": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=Idu7VcTTXfk", + "https://www.youtube.com/watch?v=iokH4SAIfRw" + ] + }, + "distribute/edu/videos/bestpractices": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=iulXz8QTD1g", + "https://www.youtube.com/watch?v=IKhU180eJMo", + "https://www.youtube.com/watch?v=_AZ6UcPz-_g", + "https://www.youtube.com/watch?v=Eh2adsAyTKc" + ] + }, + "distribute/edu/videos/experience": { + "title": "", + "resources": [ + "https://youtu.be/vzvpcEffvaE" + ] + }, + "distribute/gp/gplanding": { + "resources": [ + "distribute/googleplay/about.html", + "distribute/googleplay/start.html", + "distribute/googleplay/developer-console.html" + ] + }, + "distribute/gp/gpfelanding": { + "resources": [ + "distribute/googleplay/wear.html", + "distribute/googleplay/tv.html", + "distribute/googleplay/auto.html", + "distribute/googleplay/families/about.html", + "distribute/googleplay/work/about.html", + "distribute/googleplay/edu/about.html", + "distribute/googleplay/cast.html", + "distribute/googleplay/cardboard.html", + "distribute/googleplay/guide.html" + ] + }, + "distribute/googleplay/gpfw": { + "resources": [ + "https://www.android.com/work/", + "https://www.youtube.com/watch?v=jQWB_-o1kz4&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX", + "training/enterprise/index.html" + ] + }, + "distribute/essentials": { + "resources": [ + "distribute/essentials/quality/core.html", + "distribute/essentials/quality/tablets.html", + "distribute/essentials/quality/tv.html", + "distribute/essentials/quality/wear.html", + "distribute/essentials/quality/auto.html", + "https://developers.google.com/edu/guidelines" + ] + }, + "distribute/users": { + "title": "", + "resources": [ + "distribute/users/your-listing.html", + "distribute/users/promote-with-ads.html", + "distribute/users/appindexing.html", + "distribute/googleplay/index.html#opportunities", + "distribute/analyze/improve-roi.html", + "distribute/users/expand-to-new-markets.html", + "distribute/users/promote-with-ads.html", + "distribute/analyze/index.html", + "distribute/users/app-invites.html", + "distribute/users/ota-installs.html", + "distribute/users/youtube.html", + "distribute/users/house-ads.html", + "distribute/users/experiments.html", + "distribute/users/user-acquisition.html", + "distribute/users/banners.html", + "distribute/users/beta.html" + ] + }, + "distribute/engagelanding": { + "resources": [ + "distribute/engage/intents.html", + "distribute/engage/widgets.html", + "distribute/engage/notifications.html", + "distribute/engage/deep-linking.html", + "distribute/engage/ads.html", + "distribute/engage/game-services.html", + "distribute/engage/easy-signin.html", + "distribute/analyze/build-better-apps.html", + "distribute/engage/gcm.html", + "distribute/engage/beta.html" + ] + }, + "distribute/monetize": { + "resources": [ + "distribute/monetize/premium.html", + "distribute/monetize/freemium.html", + "distribute/monetize/subscriptions.html", + "distribute/monetize/ads.html", + "distribute/monetize/ecommerce.html", + "distribute/monetize/payments.html", + "distribute/analyze/understand-user-value.html", + ] + }, + "distribute/analyzelanding": { + "resources": [ + "distribute/analyze/start.html", + "distribute/analyze/measure.html", + "distribute/analyze/understand-user-value.html", + "distribute/analyze/improve-roi.html", + "distribute/analyze/build-better-apps.html", + "distribute/analyze/google-services.html" + ] + }, + "distribute/analyzestart": { + "resources": [ + "https://analyticsacademy.withgoogle.com/course04", + "google/play-services/index.html", + "https://developers.google.com/analytics/solutions/mobile-implementation-guide", + "https://developers.google.com/analytics/devguides/collection/android/", + "https://www.google.com/tagmanager/", + "https://github.com/googleanalytics/google-analytics-plugin-for-unity" + ] + }, + "distribute/analyzemeasure": { + "resources": [ + + "https://developers.google.com/analytics/solutions/mobile-implementation-guide", + "https://developers.google.com/analytics/devguides/collection/android/v4/enhanced-ecommerce", + "https://support.google.com/analytics/answer/1032415", + "https://developers.google.com/analytics/devguides/collection/android/v4/events", + "https://developers.google.com/analytics/devguides/collection/android/v4/customdimsmets", + "https://developers.google.com/analytics/devguides/collection/android/v4/user-id" + ] + }, + "distribute/analyzeunderstand": { + "resources": [ + "https://developers.google.com/analytics/devguides/collection/android/v4/display-features", + "https://support.google.com/analytics/answer/3123906", + "https://support.google.com/analytics/answer/2568874?ref_topic=6012392", + "https://developers.google.com/analytics/devguides/collection/android/v4/enhanced-ecommerce", + "https://support.google.com/analytics/answer/1032415", + ] + }, + "distribute/analyzeimprove": { + "resources": [ + + "https://developers.google.com/analytics/devguides/collection/android/v4/campaigns", + "https://support.google.com/analytics/answer/2956981", + "https://support.google.com/analytics/answer/1033961", + "https://developers.google.com/analytics/devguides/collection/android/v4/campaigns#google-play-url-builder", + "https://developers.google.com/analytics/solutions/mobile-campaign-deep-link" + ] + }, + "distribute/analyzebuild": { + "resources": [ + "https://support.google.com/tagmanager/answer/6003007", + "https://support.google.com/analytics/answer/2785577", + "https://support.google.com/analytics/answer/1151300" + ] + }, + "distribute/analyzeact": { + "resources": [ + "https://support.google.com/analytics/answer/2611268", + "https://support.google.com/analytics/answer/1033961", + "https://support.google.com/admob/answer/3508177", + "https://support.google.com/analytics/answer/2956981", + "https://support.google.com/tagmanager/answer/6003007" + ] + }, + "distribute/essentials/guidelines": { + "title": "", + "resources": [ + "distribute/essentials/quality/core.html", + "distribute/essentials/quality/tablets.html", + "distribute/essentials/quality/wear.html", + "distribute/essentials/quality/tv.html", + "distribute/essentials/quality/auto.html", + "https://developers.google.com/edu/guidelines" + ] + }, + "distribute/essentials/tools": { + "title": "", + "resources": [ + "distribute/tools/launch-checklist.html", + "distribute/tools/localization-checklist.html", + "https://support.google.com/googleplay/android-developer", + "distribute/tools/promote/brand.html", + "distribute/tools/promote/device-art.html", + "https://play.google.com/intl/en_us/badges/", + "distribute/tools/promote/linking.html", + "distribute/tools/open-distribution.html", + "about/dashboards/index.html" + ] + }, + "distribute/tools/checklists": { + "title": "", + "resources": [ + "distribute/tools/launch-checklist.html", + "distribute/tools/localization-checklist.html" + ] + }, + "distribute/tools/promote": { + "resources": [ + "distribute/tools/promote/device-art.html", + "https://play.google.com/intl/en_us/badges/", + "distribute/tools/promote/linking.html" + ] + }, + "distribute/tools/support": { + "title": "Google Play", + "resources": [ + "https://support.google.com/googleplay/android-developer", + "https://support.google.com/googleplay/android-developer/answer/4430948", + "support.html" + ] + }, + "distribute/tools/news": { + "title": "", + "resources": [ + "https://android-developers.blogspot.com/", + "https://plus.google.com/+AndroidDevelopers/" + ] + }, + "distribute/tools/more": { + "title": "Google Play", + "resources": [ + "distribute/tools/promote/brand.html", + "distribute/tools/open-distribution.html", + "about/dashboards/index.html" + ] + }, + "distribute/googleplay": { + "title": "Google Play", + "resources": [ + "distribute/googleplay/developer-console.html", + "distribute/essentials/best-practices/apps.html", + "distribute/tools/launch-checklist.html", + "distribute/essentials/best-practices/games.html", + ] + }, + "distribute/googleplay/gettingstarted": { + "title": "Get Started", + "resources": [ + "distribute/googleplay/developer-console.html", + "https://support.google.com/googleplay/android-developer/answer/113468", + "https://support.google.com/googleplay/android-developer/answer/138294", + "https://support.google.com/googleplay/android-developer" + ] + }, + "distribute/googleplay/developerconsole/related": { + "title": "Developer Console", + "resources": [ + "google/play/billing/index.html", + "https://support.google.com/googleplay/android-developer/answer/138294" + ] + }, + "distribute/googleplay/developerconsole": { + "title": "Developer Console", + "resources": [ + "google/play/billing/index.html", + "https://support.google.com/googleplay/android-developer/answer/138294" + ] + }, + "distribute/googleplay/beta": { + "title": "Alpha and Beta Testing", + "resources": [ + "https://support.google.com/googleplay/android-developer/answer/3131213", + "https://support.google.com/googleplay/android-developer/answer/3131213#games", + "distribute/googleplay/experiments.html" + ] + }, + "distribute/googleplay/experiments/successes": { + "title": "Store Listing Experiment successes", + "resources": [ + ] + }, + "distribute/googleplay/experiments/related": { + "title": "Store Listing Experiments", + "resources": [ + "https://support.google.com/googleplay/android-developer/answer/6227309", + "https://www.youtube.com/watch?v=B6ydLpkhq04", + "https://support.google.com/tagmanager/answer/6003007" + ] + }, + "distribute/googleplay/banners/related": { + "title": "App Install Banners", + "resources": [ + "https://developers.google.com/web/updates/2015/03/increasing-engagement-with-app-install-banners-in-chrome-for-android#native" + ] + }, + "distribute/googleplay/useracquisition/related": { + "title": "User Acquisition", + "resources": [ + "https://support.google.com/googleplay/android-developer/answer/6263332" + ] + }, + "distribute/googleplay/cast": { + "title": "Google Cast", + "resources": [ + "https://developers.google.com/cast/docs/ux_guidelines", + "https://developers.google.com/cast/docs/android_sender", + "https://www.github.com/googlecast" + ] + }, + "distribute/googleplay/cardboard": { + "title": "Google Cast", + "resources": [ + "https://www.google.com/get/cardboard/get-cardboard/", + "https://developers.google.com/cardboard/android/download", + "https://www.google.com/design/spec-vr" + ] + }, + "distribute/googleplay/gpfe/highlight": { + "title": "About Google Play for Education", + "resources": [ + "https://youtu.be/vzvpcEffvaE" + ] + }, + "distribute/googleplay/gpfe/dev/about": { + "title": "About Google Play for Education / Developers", + "resources": [ + "distribute/googleplay/edu/start.html", + "https://developers.google.com/edu/guidelines", + "https://developers.google.com/edu/faq", + "distribute/essentials/quality/tablets.html", + "https://developers.google.com/edu/", + "https://www.google.com/edu/tablets/#tablets-family" + ] + }, + "distribute/googleplay/gpfe/dev": { + "title": "About Google Play for Education / Developers", + "resources": [ + "distribute/googleplay/edu/about.html", + "https://developers.google.com/edu/guidelines", + "distribute/essentials/quality/tablets.html", + "distribute/googleplay/developer-console.html", + "https://play.google.com/about/developer-distribution-agreement-addendum.html", + ] + }, + "distribute/googleplay/aboutgpfe/educators/about": { + "title": "About Google Play for Education / Educators", + "resources": [ + "https://www.google.com/edu/tablets/", + "https://www.youtube.com/watch?v=haEmsMo0f3w" + ] + }, + "distribute/googleplay/aboutgpfe/educators": { + "title": "About Google Play for Education / Educators", + "resources": [ + "https://www.google.com/edu/tablets/", + "https://youtu.be/vzvpcEffvaE" + ] + }, + "distribute/googleplay/gettingstartedgpfe/educators": { + "title": "About Google Play for Education / Educators", + "resources": [ + "https://www.google.com/edu/tablets/", + "https://youtu.be/vzvpcEffvaE" + ] + }, + "distribute/essentials/eduessentials/developers": { + "title": "", + "resources": [ + "distribute/googleplay/developer-console.html", + "distribute/googleplay/edu/start.html", + "https://developers.google.com/edu/faq" + ] + }, + "distribute/essentials/eduessentials/educators": { + "title": "", + "resources": [ + "https://www.google.com/edu/tablets/", + "distribute/essentials/quality/tablets.html", + ] + }, + "distribute/essentials/optimizing": { + "title": "Optimizing Your App", + "resources": [ + "design/index.html", + "training/articles/perf-anr.html", + "https://android-developers.blogspot.com/2013/10/improved-app-insight-by-linking-google.html" + ] + }, + "distribute/users/appinvites": { + "title": "", + "resources": [ + "https://developers.google.com/app-invites/", + "https://developers.google.com/identity/sign-in/android/", + "https://developers.google.com/app-indexing/" + ] + }, + "distribute/users/promotewithads": { + "title": "", + "resources": [ + "https://support.google.com/adwords/answer/6032059", + "https://support.google.com/adwords/answer/6032073", + "https://support.google.com/adwords/answer/6167164", + "https://support.google.com/adwords/answer/6167162" + ] + }, + "distribute/users/buildbuzz": { + "title": "", + "resources": [ + "https://play.google.com/intl/en_us/badges/", + "distribute/tools/promote/linking.html", + "distribute/tools/promote/device-art.html", + "https://plus.google.com/+GooglePlay" + ] + }, + "distribute/users/createagreatlisting": { + "title": "", + "resources": [ + "https://support.google.com/googleplay/android-developer/answer/1078870", + "https://android-developers.blogspot.com/2011/10/android-market-featured-image.html", + "distribute/tools/launch-checklist.html", + "https://android-developers.blogspot.com/2013/07/making-beautiful-android-app-icons.html", + "https://android-developers.blogspot.com/2012/12/localize-your-promotional-graphics-on.html", + "https://android-developers.blogspot.com/2013/10/making-your-app-content-more-accessible.html" + ] + }, + "distribute/users/appindexing": { + "title": "", + "resources": [ + "https://developers.google.com/app-indexing/", + "https://developers.google.com/app-indexing/webmasters/details", + "distribute/engage/deep-linking.html", + "training/app-indexing/index.html" + ] + }, + "distribute/users/otas": { + "title": "", + "resources": [ + "https://developers.google.com/identity/sign-in/android/", + "https://developers.google.com/+/features/play-installs", + "https://developers.google.com/+/features/analytics" + ] + }, + "distribute/users/houseads": { + "title": "", + "resources": [ + "https://support.google.com/admob/topic/2784623", + "https://developers.google.com/mobile-ads-sdk/download", + "https://support.google.com/googleplay/android-developer/topic/2985714", + "https://analyticsacademy.withgoogle.com/mobile-app", + "https://support.google.com/analytics/answer/2611404", + "https://support.google.com/admob/answer/3111064" + ] + }, + "distribute/users/youtube": { + "title": "", + "resources": [ + "https://support.google.com/youtube/answer/6140493", + "https://support.google.com/youtube/answer/2797387" + ] + }, + "distribute/toolsreference/bestpractices/apps": { + "title": "", + "resources": [ + "distribute/googleplay/developer-console.html", + "https://android-developers.blogspot.com/" + ] + }, + "distribute/toolsreference/bestpractices/games": { + "title": "", + "resources": [ + "google/play-services/games.html", + "https://android-developers.blogspot.com/", + "distribute/googleplay/developer-console.html", + "https://www.youtube.com/watch?v=1RIz-cmTQB4" + ] + }, + "distribute/essentials/corequalityguidelines/visualdesign": { + "title": "", + "resources": [ + "design/index.html", + "design/patterns/navigation.html", + "design/patterns/actionbar.html", + "design/style/iconography.html", + "design/patterns/notifications.html" + ] + }, + "distribute/essentials/corequalityguidelines/functionality": { + "title": "", + "resources": [ + "https://android-developers.blogspot.com/2011/11/making-android-games-that-play-nice.html", + "guide/components/tasks-and-back-stack.html", + "training/basics/activity-lifecycle/recreating.html" + ] + }, + "distribute/essentials/tvqualityguidelines/visualdesign": { + "title": "", + "resources": [ + "design/tv/index.html", + "training/tv/start/index.html" + ] + }, + "distribute/essentials/tvqualityguidelines/functionality": { + "title": "", + "resources": [ + "training/tv/start/hardware.html", + "training/tv/games/index.html" + ] + }, + "distribute/essentials/wearqualityguidelines/visualdesign": { + "title": "", + "resources": [ + "design/wear/index.html", + "training/building-wearables.html", + "training/wearables/ui/index.html" + ] + }, + "distribute/essentials/wearqualityguidelines/functionality": { + "title": "", + "resources": [ + "training/wearables/notifications/index.html", + "training/wearables/apps/index.html", + "training/wearables/notifications/voice-input.html" + ] + }, + "distribute/essentials/autoqualityguidelines/visualdesign": { + "title": "", + "resources": [ + "training/auto/messaging/index.html", + "training/auto/start/index.html" + ] + }, + "distribute/essentials/core/performance": { + "title": "", + "resources": [ + "https://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html", + "training/articles/perf-anr.html", + "https://android-developers.blogspot.com/2010/07/multithreading-for-performance.html" + ] + }, + "distribute/essentials/core/play": { + "title": "", + "resources": [ + "distribute/tools/launch-checklist.html", + "https://play.google.com/about/developer-content-policy.html", + "https://support.google.com/googleplay/android-developer/answer/188189", + "https://support.google.com/googleplay/android-developer/answer/1078870", + "https://android-developers.blogspot.com/2011/10/android-market-featured-image.html", + "https://support.google.com/googleplay/android-developer/answer/113477" + ] + }, + "distribute/essentials/tabletguidelines/optimize": { + "title": "", + "resources": [ + "design/style/metrics-grids.html", + "design/style/devices-displays.html", + "guide/practices/screens_support.html", + ] + }, + "distribute/essentials/tabletguidelines/extrascreen": { + "title": "", + "resources": [ + "design/patterns/multi-pane-layouts.html", + "training/design-navigation/multiple-sizes.html", + "training/multiscreen/index.html", + ] + }, + "distribute/essentials/tabletguidelines/assets": { + "title": "", + "resources": [ + "design/style/iconography.html", + "guide/topics/resources/providing-resources.html", + "guide/practices/screens_support.html", + "training/basics/supporting-devices/screens.html" + ] + }, + "distribute/essentials/tabletguidelines/fonts": { + "title": "", + "resources": [ + "design/style/metrics-grids.html", + "design/style/typography.html", + "guide/practices/screens_support.html", + "training/multiscreen/screendensities.html" + ] + }, + "distribute/essentials/tabletguidelines/widgets": { + "title": "", + "resources": [ + "guide/topics/appwidgets/index.html#MetaData", + "guide/topics/appwidgets/index.html", + "design/patterns/widgets.html" + ] + }, + "distribute/essentials/tabletguidelines/versions": { + "title": "", + "resources": [ + "guide/topics/manifest/uses-sdk-element.html#ApiLevels", + "guide/topics/manifest/uses-sdk-element.html", + "training/basics/supporting-devices/platforms.html" + ] + }, + "distribute/essentials/tabletguidelines/hardware": { + "title": "", + "resources": [ + "guide/topics/manifest/uses-feature-element.html", + "guide/topics/manifest/uses-feature-element.html#testing" + ] + }, + "distribute/essentials/tabletguidelines/tabletscreens": { + "title": "", + "resources": [ + "guide/practices/screens_support.html#DeclaringScreenSizeSupport", + "guide/practices/screens_support.html" + ] + }, + "distribute/essentials/tabletguidelines/showcase": { + "title": "", + "resources": [ + "distribute/tools/launch-checklist.html", + "https://play.google.com/apps/publish/", + "https://play.google.com/intl/en_us/badges/", + "distribute/tools/promote/device-art.html" + ] + }, + "distribute/essentials/tabletguidelines/googleplay": { + "title": "", + "resources": [ + "https://android-developers.blogspot.com/2013/10/more-visibility-for-tablet-apps-in.html", + "google/play/filters.html" + ] + }, + "distribute/essentials/tabletguidelines": { + "title": "", + "resources": [ + "distribute/essentials/quality/core.html", + "https://android-developers.blogspot.com/2013/10/more-visibility-for-tablet-apps-in.html", + "distribute/tools/launch-checklist.html", + "distribute/tools/promote/device-art.html" + ] + }, + "distribute/getusers/notifications": { + "title": "", + "resources": [ + "design/patterns/notifications.html", + "distribute/engage/gcm.html", + "https://play.google.com/about/developer-content-policy.html" + ] + }, + "distribute/engage/analytics": { + "title": "", + "resources": [ + "https://www.google.com/analytics/mobile/", + "https://android-developers.blogspot.com/2013/10/improved-app-insight-by-linking-google.html", + "https://developers.google.com/analytics/devguides/collection/android/" + ] + }, + "distribute/engage/widgets": { + "title": "", + "resources": [ + "design/patterns/widgets.html", + "guide/topics/appwidgets/index.html" + ] + }, + "distribute/engage/reengage": { + "title": "", + "resources": [ + "https://support.google.com/adwords/answer/6032073", + "distribute/engage/deep-linking.html", + "https://support.google.com/adwords/answer/6167162", + "distribute/users/promote-with-ads.html" + ] + }, + "distribute/engage/appindexing": { + "title": "", + "resources": [ + "distribute/engage/intents.html", + "distribute/engage/deep-linking.html", + "distribute/users/appindexing.html", + "training/app-indexing/index.html" + ] + }, + "distribute/engage/intents": { + "title": "", + "resources": [ + "guide/components/intents-filters.html", + "distribute/engage/deep-linking.html", + "distribute/engage/ads.html" + ] + }, + "distribute/getusers/expandnewmarkets": { + "title": "", + "resources": [ + "distribute/tools/localization-checklist.html", + "https://support.google.com/googleplay/android-developer/table/3541286", + "distribute/stories/localization.html", + "https://play.google.com/intl/en_us/badges/", + "distribute/tools/promote/device-art.html", + "https://www.youtube.com/watch?v=SkHHPf3EdzE" + ] + }, + "distribute/engage/gcm": { + "title": "", + "resources": [ + "https://developers.google.com/cloud-messaging/gcm", + "https://developers.google.com/cloud-messaging/android/client", + ] + }, + "distribute/engage/gamesservices/related": { + "title": "", + "resources": [ + "https://developers.google.com/games/services/", + "distribute/analyze/start.html", + "distribute/googleplay/cardboard.html", + "https://www.google.com/admob/" + ] + }, + "distribute/engage/googleplaygames": { + "title": "", + "resources": [ + "https://developers.google.com/games/services/", + "distribute/analyze/start.html", + "distribute/googleplay/cardboard.html", + "https://www.google.com/admob/" + ] + }, + "distribute/engage/gplus": { + "title": "", + "resources": [ + "distribute/users/ota-installs.html", + "https://developers.google.com/identity/sign-in/android/people", + "https://developers.google.com/+/mobile/android/" + ] + }, + "distribute/engage/community": { + "title": "", + "resources": [ + "distribute/users/build-community.html", + "distribute/engage/video.html" + ] + }, + "distribute/engage/deeplinks": { + "title": "", + "resources": [ + "distribute/engage/easy-signin.html", + "https://developers.google.com/app-indexing/", + "https://developers.google.com/+/mobile/android/share/interactive-post" + ] + }, + "distribute/engage/appupdates": { + "title": "", + "resources": [ + "distribute/essentials/optimizing-your-app.html", + "distribute/tools/launch-checklist.html", + "distribute/googleplay/developer-console.html", + "design/patterns/notifications.html" + ] + }, + "distribute/engage/video/more": { + "title": "", + "resources": [ + "https://www.youtube.com/yt/dev/", + "distribute/essentials/best-practices/games.html", + "https://www.youtube.com/watch?v=RRelFvc6Czo" + ] + }, + "distribute/engage/community": { + "title": "", + "resources": [ + "distribute/users/build-community.html", + "distribute/engage/video.html" + ] + }, + "distribute/engage/kiwi": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=WWArLD6nqrk" + ] + }, + "distribute/toolsreference/gpfefaq": { + "title": "", + "resources": [ + "https://www.google.com/edu/tablets/", + "distribute/googleplay/edu/start.html", + "https://play.google.com/about/developer-distribution-agreement-addendum.html", + "distribute/essentials/quality/core.html", + "distribute/essentials/quality/tablets.html" + ] + }, + "distribute/toolsreference/localizationchecklist/identifylocales": { + "title": "", + "resources": [ + "https://support.google.com/googleplay/android-developer/answer/138294" + ] + }, + "distribute/tools/loc/designforloc": { + "title": "", + "resources": [ + "https://android-developers.blogspot.com/2013/03/native-rtl-support-in-android-42.html", + "guide/topics/resources/string-resource.html#Plurals", + "guide/topics/resources/string-resource.html", + "reference/java/util/Locale.html" + ] + }, + "distribute/toolsreference/localizationchecklist/managestrings": { + "title": "", + "resources": [ + "guide/topics/resources/string-resource.html", + "design/style/writing.html", + "https://en.wikipedia.org/wiki/XLIFF" + ] + }, + "distribute/toolsreference/localizationchecklist/translatestrings": { + "title": "", + "resources": [ + "distribute/stories/localization.html", + ] + }, + "distribute/toolsreference/localizationchecklist/preplaunch": { + "title": "", + "resources": [ + "https://play.google.com/intl/en_us/badges/", + "distribute/tools/promote/device-art.html" + ] + }, + "distribute/toolsreference/localizationchecklist/supportlaunch": { + "title": "", + "resources": [ + "distribute/tools/launch-checklist.html", + ] + }, + "distribute/toolsreference/launchchecklist/understanding": { + "title": "", + "resources": [ + "tools/publishing/publishing_overview.html", + "tools/publishing/preparing.html" + ] + }, + "distribute/toolsreference/launchchecklist/policies": { + "title": "", + "resources": [ + "https://support.google.com/googleplay/android-developer/answer/4430948", + "https://support.google.com/googleplay/android-developer/topic/2364761", + "https://support.google.com/googleplay/android-developer" + ] + }, + "distribute/toolsreference/launchchecklist/quality": { + "title": "", + "resources": [ + "distribute/essentials/quality/core.html", + "distribute/essentials/quality/tablets.html", + "https://developers.google.com/edu/guidelines" + ] + }, + "distribute/toolsreference/launchchecklist/rating": { + "title": "", + "resources": [ + "https://support.google.com/googleplay/android-developer/answer/188189", + ] + }, + "distribute/toolsreference/launchchecklist/country": { + "title": "", + "resources": [ + "https://support.google.com/googleplay/android-developer/answer/138294" + ] + }, + "distribute/toolsreference/launchchecklist/size": { + "title": "", + "resources": [ + "google/play/expansion-files.html", + "tools/help/proguard.html" + ] + }, + "distribute/toolsreference/launchchecklist/platform": { + "title": "", + "resources": [ + "guide/practices/screens_support.html", + "about/dashboards/index.html", + "guide/topics/manifest/uses-sdk-element.html" + ] + }, + "distribute/toolsreference/launchchecklist/price": { + "title": "", + "resources": [ + "https://support.google.com/googleplay/android-developer/table/3541286", + ] + }, + "distribute/toolsreference/launchchecklist/purchasemethod": { + "title": "", + "resources": [ + "google/play/billing/index.html", + "google/play/billing/billing_subscriptions.html" + ] + }, + "distribute/toolsreference/launchchecklist/setprice": { + "title": "", + "resources": [ + "https://support.google.com/googleplay/android-developer/answer/1169947", + "https://support.google.com/googleplay/android-developer/answer/138412", + "https://support.google.com/googleplay/android-developer/answer/112622", + "https://support.google.com/googleplay/android-developer/answer/138000" + ] + }, + "distribute/toolsreference/launchchecklist/localization": { + "title": "", + "resources": [ + "distribute/tools/localization-checklist.html", + "guide/topics/resources/localization.html", + ] + }, + "distribute/toolsreference/launchchecklist/graphics": { + "title": "", + "resources": [ + "https://support.google.com/googleplay/android-developer/answer/1078870", + "https://android-developers.blogspot.com/2011/10/android-market-featured-image.html" + ] + }, + "distribute/toolsreference/launchchecklist/productdetails": { + "title": "", + "resources": [ + "https://support.google.com/googleplay/android-developer/answer/113475", + "https://support.google.com/googleplay/android-developer/answer/1078870" + ] + }, + "distribute/toolsreference/launchchecklist/badges": { + "title": "", + "resources": [ + "https://play.google.com/intl/en_us/badges/", + "distribute/tools/promote/linking.html" + ] + }, + "distribute/toolsreference/launchchecklist/finalchecks": { + "title": "", + "resources": [ + "https://play.google.com/about/developer-content-policy.html", + "https://support.google.com/googleplay/android-developer/answer/113476", + "support.html" + ] + }, + "distribute/toolsreference/launchchecklist/afterlaunch": { + "title": "", + "resources": [ + "https://support.google.com/googleplay/android-developer/answer/113477", + "https://support.google.com/googleplay/android-developer/answer/1153479", + "https://support.google.com/payments/answer/2741495", + "distribute/essentials/optimizing-your-app.html" + ] + }, + "distribute/monetize/premium": { + "title": "", + "resources": [ + "google/play/billing/index.html", + "https://support.google.com/googleplay/android-developer/answer/4407611" + ] + }, + "distribute/monetize/freemium": { + "title": "", + "resources": [ + "google/play/billing/index.html", + "https://support.google.com/googleplay/android-developer/answer/4407611" + ] + }, + "distribute/monetize/subscriptions": { + "title": "", + "resources": [ + "google/play/billing/billing_subscriptions.html", + "https://support.google.com/googleplay/android-developer/answer/4407611" + ] + }, + "distribute/monetize/ecommerce": { + "title": "", + "resources": [ + "https://developers.google.com/wallet/instant-buy/", + "https://support.google.com/googleplay/android-developer/answer/4407611" + ] + }, + "distribute/monetize/advertising": { + "title": "", + "resources": [ + "https://www.google.com/ads/admob/#subid=us-en-et-dac", + "https://www.google.com/doubleclick/publishers/small-business/index.html", + "https://support.google.com/googleplay/android-developer/topic/2985714", + "training/monetization/ads-and-ux.html" + ] + }, + "distribute/monetize/admob": { + "title": "", + "resources": [ + "https://support.google.com/admob/topic/2784623", + "https://admob.blogspot.com/", + "https://analyticsacademy.withgoogle.com/mobile-app", + ] + }, + "distribute/monetize/paymentmethods": { + "title": "", + "resources": [ + "https://play.google.com/about/giftcards/", + "https://support.google.com/googleplay/answer/2651410" + ] + }, + "autolanding": { + "title": "", + "resources": [ + "auto/index.html", + "design/auto/index.html", + "training/auto/index.html" + ] + }, + "tvlanding": { + "title": "", + "resources": [ + "tv/index.html", + "design/tv/index.html", + "training/tv/index.html" + ] + }, + "wearlanding": { + "title": "", + "resources": [ + "design/wear/index.html", + "training/building-wearables.html", + "training/wearables/ui/index.html" + ] + }, + "design/auto/auto_ui_guidelines": { + "title": "", + "resources": [ + "shareables/auto/AndroidAuto-audio-apps.pdf", + "shareables/auto/AndroidAuto-messaging-apps.pdf", + "shareables/auto/AndroidAuto-custom-colors.pdf" + ] + }, + "training/auto/overview": { + "title": "", + "resources": [ + "training/auto/start/index.html", + "design/auto/index.html", + "shareables/auto/AndroidAuto-custom-colors.pdf" + ] + }, + "training/auto/messaging": { + "title": "", + "resources": [ + "training/auto/messaging/index.html", + "shareables/auto/AndroidAuto-messaging-apps.pdf", + "samples/MessagingService/index.html" + ] + }, + "training/auto/media": { + "title": "", + "resources": [ + "training/auto/audio/index.html", + "shareables/auto/AndroidAuto-audio-apps.pdf", + "samples/MediaBrowserService/index.html" + ] + }, + "training/auto/distribute": { + "title": "", + "resources": [ + "distribute/essentials/quality/auto.html", + "distribute/googleplay/auto.html" + ] + }, + "distribute/stories/games": { + "title": "", + "resources": [ + "https://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_Deerhunter2014_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/ConcreteSoftware_PBABowling_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/Dragonplay_DragonplaySlots_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/Gameloft_Asphalt8_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/Glu_EternityWarriors3_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/HotheadGames_RivalsatWar_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/TMSOFT_Compulsive_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/Noodlecake_SuperStickmanGolf2_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/TinyRebel_DoctorWhoLegacy_gpgs.pdf", + "https://storage.googleapis.com/androiddevelopers/shareables/stories/Senri_LeosFortune_gpgs.pdf" + ] + }, + "training/testing/overview": { + "title": "", + "resources": [ + "training/testing/start/index.html", + "tools/testing/testing_android.html", + "https://www.youtube.com/watch?v=vdasFFfXKOY" + ] + }, + "training/testing/tools": { + "title": "", + "resources": [ + "tools/testing-support-library/index.html", + "tools/help/monkey.html", + "tools/help/monkeyrunner_concepts.html", + "tools/testing/testing_otheride.html", + "https://source.android.com/devices/tech/debug/dumpsys.html" + ] + }, + "training/testing/techniques": { + "title": "", + "resources": [ + "training/testing/ui-testing/index.html", + "training/testing/unit-testing/index.html", + "training/testing/performance.html" + ] + }, + "training/testing/resources": { + "title": "", + "resources": [ + "https://github.com/googlesamples/android-testing", + "https://www.youtube.com/watch?v=2I6fuD20qlY", + "https://codelabs.developers.google.com/codelabs/android-testing/index.html", + "https://github.com/googlesamples/android-testing-templates", + "https://google.github.io/android-testing-support-library" + ] + }, + "overview/1": { + "title": "", + "resources": [ + "distribute/essentials/quality/core.html", + "distribute/essentials/quality/tablets.html", + "distribute/tools/launch-checklist.html", + "tools/publishing/publishing_overview.html", + "distribute/tools/localization-checklist.html" + ] + }, + "overview/2": { + "title": "", + "resources": [ + "google/play/billing/index.html", + "google/play/billing/api.html", + "google/play/billing/billing_admin.html", + "google/play/billing/billing_testing.html", + "google/play/billing/billing_best_practices.html" + ] + }, + "overview/3": { + "title": "", + "resources": [ + "https://play.google.com/intl/en_us/badges/", + "distribute/tools/promote/device-art.html", + "distribute/tools/promote/linking.html", + "distribute/tools/promote/brand.html", + "tools/help/proguard.html" + ] + }, + "overview/4": { + "title": "", + "resources": [ + "design/style/writing.html", + "training/basics/fragments/fragment-ui.html", + "training/multiscreen/index.html", + "training/monitoring-device-state/index.html" + ] + }, + "training/work/apps": { + "title": "", + "resources": [ + "training/enterprise/app-compatibility.html", + "training/enterprise/app-restrictions.html", + "https://www.youtube.com/watch?v=39NkpWkaH8M&index=2&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX", + "samples/AppRestrictionSchema/index.html", + "samples/AppRestrictionEnforcer/index.html", + "https://www.youtube.com/watch?v=dH41OutAMNM" + ] + }, + "training/work/admin": { + "title": "", + "resources": [ + "training/enterprise/work-policy-ctrl.html", + "samples/BasicManagedProfile/index.html", + "https://www.youtube.com/watch?v=j3QC6hcpy90" + ] + }, + "tools/performance/rendering": { + "title": "", + "resources": [ + "tools/performance/debug-gpu-overdraw/index.html", + "tools/performance/profile-gpu-rendering/index.html", + "tools/performance/hierarchy-viewer/setup.html", + "tools/performance/hierarchy-viewer/index.html", + "tools/performance/hierarchy-viewer/profiling.html" + ] + }, + "tools/performance/memory": { + "title": "", + "resources": [ + "tools/performance/memory-monitor/index.html", + "tools/performance/heap-viewer/index.html", + "tools/performance/allocation-tracker/index.html", + "tools/performance/comparison.html" + ] + }, + "tools/performance/cpu": { + "title": "", + "resources": [ + "tools/performance/traceview/index.html", + "tools/performance/systrace/index.html" + ] + }, + "tools/performance/battery": { + "title": "", + "resources": [ + "tools/performance/batterystats-battery-historian/index.html", + "tools/performance/batterystats-battery-historian/charts.html" + ] + }, + "marshmallow/landing/resources": { + "title": "", + "resources": [ + "about/versions/marshmallow/android-6.0-changes.html", + "about/versions/marshmallow/android-6.0.html", + "about/versions/marshmallow/samples.html" + ] + }, + "marshmallow/landing/videos": { + "title": "", + "resources": [ + "https://youtu.be/U9tw5ypqEN0", + "https://youtu.be/N72ksDKrX6c", + "https://youtu.be/iZqDdvhTZj0", + "https://www.youtube.com/watch?v=vcSj8ln-BlE", + "https://youtu.be/LQoohRwojmw", + "https://www.youtube.com/watch?v=VOn7VrTRlA4", + "https://youtu.be/5sCQjeGoE7M", + "https://www.youtube.com/watch?v=C8lUdPVSzDk", + "https://www.youtube.com/watch?v=HXacyy0HSW0", + "https://www.youtube.com/watch?v=OW1A4XFRuyc", + "https://www.youtube.com/watch?v=j3QC6hcpy90", + "https://www.youtube.com/watch?v=f17qe9vZ8RM", + "https://www.youtube.com/watch?v=ndBdf1_oOGA" + ] + }, + "marshmallow/landing/more": { + "title": "", + "resources": [ + "training/permissions/requesting.html", + "training/backup/autosyncapi.html", + "training/monitoring-device-state/doze-standby.html", + "training/app-links/index.html", + "training/articles/assistant.html", + "training/testing/performance.html", + "https://developers.google.com/android/nexus/images" + ] + }, + "tools/landing/carousel": { + "title": "", + "resources": [ + "panel1", + "panel2", + "panel3", + "panel4", + ] + }, + "tools/landing/resources": { + "title": "", + "resources": [ + "tools/studio/index.html", + "tools/studio/studio-features.html", + "sdk/installing/studio-tips.html", + ] + }, +}; + +/** + * Static search results. + */ +METADATA['en'].searchHeroCollections = { + "material": { + "title":"Material Design for Android", + "category":"", + "summary":"Material design is a comprehensive guide for visual, motion, and interaction design across platforms and devices. Android now includes support for material design apps.", + "url":"design/material/index.html", + "group":"", + "keywords": ["material","design"], + "tags": ["material","design"], + "image":"images/cards/design-material-for-android_2x.jpg", + "lang":"en", + "type":"design" + } +}; diff --git a/docs/html/jd_extras_es.js b/docs/html/jd_extras_es.js new file mode 100644 index 000000000000..7ced2595579e --- /dev/null +++ b/docs/html/jd_extras_es.js @@ -0,0 +1,13 @@ + +//must use intl/nn to override translated resources +METADATA['es'].carousel = { + "intl/es/distribute/googleplay/guide.html": { + "image": "images/distribute/hero-secrets-to-app-success.jpg", + }, +}; + +/** + * Static metadata collections for this language. + */ +METADATA['es'].collections = { +};
\ No newline at end of file diff --git a/docs/html/jd_extras_ja.js b/docs/html/jd_extras_ja.js new file mode 100644 index 000000000000..390c23ced3e8 --- /dev/null +++ b/docs/html/jd_extras_ja.js @@ -0,0 +1,185 @@ +/* Metadata represendations of resources that are outside of the autogenerated + local resource lists, or that override local resource representations. + + Resources listed here are referenced from sitemap sections and collections, + matched by url string if there is no resource existing in ALL_RESOURCES. + + Currently, these articles can override only the generated resources + in DISTRIBUTE_RESOURCES. A representation defined here will not be applied + when a collection or section specifies a url that's not in DISTRIBUTE_RESOURCEs. + Also + So if a section url refers to a static doc that's + not in a distribute section, you need to create an item for + it in this file. Fix is to compare across + ALL_RESOURCES_BY_URL. */ + +METADATA['ja'].extras = METADATA['ja'].extras.concat([ + /* TODO Remove standard resources from here, such as below + */ + { + "lang": "ja", + "title": "Gaming Everywhere", + "category": "", + "summary": "東京ゲームショウ 2014 の基調講演より。", + "url": "https://www.youtube.com/watch?v=xelYnWcYkuE", + "group": "", + "keywords": [], + "tags": [], + "image": "https://img.youtube.com/vi/xelYnWcYkuE/hqdefault.jpg", + "type": "youtube" + }, + { + "lang": "ja", + "title": "Playtime Tokyo", + "category": "", + "summary": "アプリビジネスのノウハウを各担当者が講演しました。", + "url": "https://www.youtube.com/playlist?list=PLCOC_kP3nqGIHEgwm9mybvA04Vn4Cg9nn", + "group": "", + "keywords": [], + "tags": [], + "image": "https://img.youtube.com/vi/lJdjY3z6-LY/hqdefault.jpg", + "type": "youtube" + }, + { + "lang": "ja", + "title": "Android Wear 関連の動画に日本語字幕が付きました", + "category": "", + "summary": "", + "url": "https://googledevjp.blogspot.jp/2014/12/android-wear.html", + "group": "", + "keywords": [], + "tags": [], + "image": "https://i1.ytimg.com/vi/4JcDYkgqksY/maxresdefault.jpg", + "type": "blog" + }, + { + "lang": "ja", + "title": "Android Studio 1.0 をリリースしました", + "category": "", + "summary": "", + "url": "https://googledevjp.blogspot.jp/2014/12/android-studio-10.html", + "group": "", + "keywords": [], + "tags": [], + "image": "https://3.bp.blogspot.com/-1hV3sD1At74/VIaQSWBasUI/AAAAAAAABAU/9vYLJMsmMuQ/s1600/studio-logo.png", + "type": "blog" + }, + { + "lang": "ja", + "title": "Google Play 開発者サービス 6.5 のご紹介", + "category": "", + "summary": "", + "url": "https://googledevjp.blogspot.jp/2014/12/google-play-65.html", + "group": "", + "keywords": [], + "tags": [], + "image": "https://1.bp.blogspot.com/-4BNREC0Jojo/VGo7ahW35wI/AAAAAAAABAc/9thZl94F6fY/s1600/GMS%2B-%2BRelease%2BBlog%2BNacho%2B-%2BMap%2BToolbar.png", + "type": "blog" + }, + { + "lang": "ja", + "title": "Alpha and Beta Testing", + "category": "", + "summary": "アプリのローンチにまつわるリスクを最小限にするために必須のツールです。[英語コンテンツ]", + "url": "intl/ja/distribute/googleplay/developer-console.html#alpha-beta", + "group": "", + "keywords": [], + "tags": [], + "image": "images/gp-dc-ab.png", + "type": "distribute" + }, + { + "lang": "ja", + "title": "Finding Success on Google Play", + "category": "", + "summary": "Google Play での成功の秘訣がこの一冊に。[英語コンテンツ]", + "url": "intl/ja/distribute/googleplay/guide.html", + "group": "", + "keywords": [], + "tags": [], + "image": "distribute/images/play_dev_guide_b.jpg", + "type": "distribute" + }, + { + "lang": "ja", + "title": "Google Play アプリ ポリシー センター", + "category": "", + "summary": "", + "url": "https://support.google.com/googleplay/android-developer/answer/4430948?hl=ja", + "group": "", + "keywords": [], + "tags": [], + "image": "https://storage.googleapis.com/support-kms-prod/SNP_712EA2784949DDF085C46E3BE7B1DC618A09_4389356_en_v0", + "type": "distribute" + }, + { + "lang": "ja", + "title": "Wear App Quality", + "category": "", + "summary": "いよいよウェアラブルの時代が到来。[英語コンテンツ]", + "url": "intl/ja/distribute/essentials/quality/wear.html", + "group": "", + "keywords": [], + "tags": [], + "image": "distribute/images/gp-wear-quality.png", + "type": "distribute" + }, + { + "lang": "ja", + "title": "Google Cloud Platform が支える、新感覚リアルタイム RPG ユニゾンリーグ - 株式会社エイチームの GCP 導入事例", + "category": "", + "summary": "スケーラブルなバックエンドを実現する Google Cloud Platform の最新導入事例。", + "url": "https://googleforwork-japan.blogspot.jp/2014/12/gcp-google-cloud-platform-rpg-gcp.html", + "group": "", + "keywords": [], + "tags": [], + "image": "https://3.bp.blogspot.com/-xp7KoPkbne4/VI_PfoFil3I/AAAAAAAAA3U/-k1UZ0zjCBc/s1600/unison-league.jpeg", + "type": "distribute" + }, + { + "lang": "ja", + "title": "Monetize with Ads", + "category": "", + "summary": "アプリ内広告成功のコツがここに。[英語コンテンツ]", + "url": "intl/ja/distribute/monetize/ads.html", + "group": "", + "keywords": [], + "tags": [], + "image": "distribute/images/advertising.jpg", + "type": "distribute" + }, +]); + +//must use intl/nn url to override a translated resource +METADATA['ja'].carousel = { + "intl/ja/distribute/googleplay/guide.html": { + "image": "images/distribute/hero-secrets-to-app-success.jpg", + "title": "Secrets to App Success on Google Play", + "summary": "Get the updated guide full of useful features, tips, and best practices that will help you grow a successful app or game business on Google Play.", + }, +}; + +/** + * Static metadata collections. + */ +METADATA['ja'].collections = { + "launch/static/ja": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=xelYnWcYkuE", + "https://www.youtube.com/playlist?list=PLCOC_kP3nqGIHEgwm9mybvA04Vn4Cg9nn", + "https://googledevjp.blogspot.jp/2014/12/android-wear.html", + "https://googledevjp.blogspot.jp/2014/12/android-studio-10.html", + "https://googledevjp.blogspot.jp/2014/12/google-play-65.html", + "distribute/googleplay/developer-console.html#alpha-beta", + "distribute/googleplay/guide.html", + "distribute/essentials/quality/core.html", + "https://support.google.com/googleplay/android-developer/answer/4430948?hl=ja", + "support.html", + "distribute/essentials/quality/wear.html", + "training/tv/start/index.html", + "https://googleforwork-japan.blogspot.jp/2014/12/gcp-google-cloud-platform-rpg-gcp.html", + "distribute/monetize/ads.html" + ] + }, +};
\ No newline at end of file diff --git a/docs/html/jd_extras_ko.js b/docs/html/jd_extras_ko.js new file mode 100644 index 000000000000..8d9059ceccda --- /dev/null +++ b/docs/html/jd_extras_ko.js @@ -0,0 +1,120 @@ +/* Metadata represendations of resources that are outside of the autogenerated + local resource lists, or that override local resource representations. + + Resources listed here are referenced from sitemap sections and collections, + matched by url string if there is no resource existing in ALL_RESOURCES. + + Currently, these articles can override only the generated resources + in DISTRIBUTE_RESOURCES. A representation defined here will not be applied + when a collection or section specifies a url that's not in DISTRIBUTE_RESOURCEs. + Also + So if a section url refers to a static doc that's + not in a distribute section, you need to create an item for + it in this file. Fix is to compare across + ALL_RESOURCES_BY_URL. */ + +METADATA['ko'].extras = METADATA['ko'].extras.concat([ + /* TODO Remove standard resources from here, such as below + */ + { + "lang": "ko", + "title": "구글 플레이 2015년 비전", + "category": "", + "summary": "G-Star 구글 컨퍼런스", + "url": "https://www.youtube.com/watch?v=7X9Ue0Nfdh4&index=2&list=PL_WJkTbDHdBksDBRoqfeyLchEQqBAOlNl", + "group": "", + "keywords": [], + "tags": [], + "image": "https://img.youtube.com/vi/7X9Ue0Nfdh4/hqdefault.jpg", + "type": "youtube" + }, + { + "lang": "ko", + "title": "구글 플레이 게임", + "category": "", + "summary": "게임 프로필, 퀘스트, 세이브드 게임 등의 신기능 소개", + "url": "https://www.youtube.com/watch?v=83FpwuschCQ", + "group": "", + "keywords": [], + "tags": [], + "image": "https://img.youtube.com/vi/83FpwuschCQ/hqdefault.jpg", + "type": "youtube" + }, + { + "lang": "ko", + "title": "안드로이드 5.0 롤리팝을 맞이하는 개발자를 위한 안내서", + "category": "", + "summary": "", + "url": "https://googledevkr.blogspot.com/2014/11/android50guidefordevelopers.html", + "group": "", + "keywords": [], + "tags": [], + "image": "https://lh5.googleusercontent.com/0Gx4Ob_WvIgNOMv3hVMuUm4O7KuSWyxCEFIvy39_6fgXh2q2azqjZf3bpZoEk-LMW-K8GwYMfyYfMUAwp38hhPQ6WFNnddhN2E2_GF3-XBQI_qjhISviz10h_mGgDWsZKA", + "type": "blog" + }, + { + "lang": "ko", + "title": "안드로이드 앱을 위한 머티리얼 디자인 체크 리스트", + "category": "", + "summary": "", + "url": "https://googledevkr.blogspot.com/2014/10/material-design-on-android-checklist.html", + "group": "", + "keywords": [], + "tags": [], + "image": "https://lh4.googleusercontent.com/JKoxeDdmsj6gYHV8rmp96U1jHj7FKeMzGBaaFu35kXp5EpJR9Ei9MQFAYghjwJoycdgydw-FZTuFNY8pDx63MWhy37rKC96ajoDXEMzvo9W0sj5yC2-uSYJdhpazVOP2cA", + "type": "blog" + }, + { + "lang": "ko", + "title": "App Compat 라이브러리", + "category": "", + "summary": "", + "url": "https://googledevkr.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html", + "group": "", + "keywords": [], + "tags": [], + "image": "https://2.bp.blogspot.com/-7fF9ayZ6PgI/U9iFpk5FNEI/AAAAAAAAAs0/4P4SCvdB_4M/s640/image00.png", + "type": "blog" + }, + { + "lang": "ko", + "title": "구글 플레이 게임 서비스", + "category": "", + "summary": "다양한 구글 플레이 게임 서비스 기능 알아보기 [영문]", + "url": "intl/ko/google/play-services/games.html", + "group": "", + "keywords": [], + "tags": [], + "image": "https://developers.google.com/games/services/images/gamescreen3.jpg", + "type": "distribute" + }, +]); + +//must use intl/nn to override translated resources +METADATA['ko'].carousel = { +}; + +/** + * Static metadata collections. + */ +METADATA['ko'].collections = { + "launch/static/ko": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=7X9Ue0Nfdh4&index=2&list=PL_WJkTbDHdBksDBRoqfeyLchEQqBAOlNl", + "https://www.youtube.com/watch?v=83FpwuschCQ", + "https://googledevkr.blogspot.com/2014/11/android50guidefordevelopers.html", + "https://googledevkr.blogspot.com/2014/10/material-design-on-android-checklist.html", + "https://googledevkr.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html", + "distribute/googleplay/developer-console.html#alpha-beta", + "distribute/googleplay/guide.html", + "distribute/essentials/quality/core.html", + "https://support.google.com/googleplay/android-developer/answer/4430948?hl=ko", + "support.html", + "distribute/essentials/quality/wear.html", + "tv/index.html", + "google/play-services/games.html", + "distribute/monetize/ads.html" + ] + }, +};
\ No newline at end of file diff --git a/docs/html/jd_extras_ru.js b/docs/html/jd_extras_ru.js new file mode 100644 index 000000000000..d6c873c49385 --- /dev/null +++ b/docs/html/jd_extras_ru.js @@ -0,0 +1,13 @@ + +//must use intl/nn to override translated resources +METADATA['ru'].carousel = { + "intl/ru/distribute/googleplay/guide.html": { + "image": "images/distribute/hero-secrets-to-app-success.jpg", + }, +}; + +/** + * Static metadata collections for this language. + */ +METADATA['ru'].collections = { +};
\ No newline at end of file diff --git a/docs/html/jd_extras_zh-cn.js b/docs/html/jd_extras_zh-cn.js new file mode 100644 index 000000000000..cb1ccb7d6ee3 --- /dev/null +++ b/docs/html/jd_extras_zh-cn.js @@ -0,0 +1,291 @@ +/* Metadata represendations of resources that are outside of the autogenerated + local resource lists, or that override local resource representations. + + Resources listed here are referenced from sitemap sections and collections, + matched by url string if there is no resource existing in ALL_RESOURCES. + + Currently, these articles can override only the generated resources + in DISTRIBUTE_RESOURCES. A representation defined here will not be applied + when a collection or section specifies a url that's not in DISTRIBUTE_RESOURCEs. + Also + So if a section url refers to a static doc that's + not in a distribute section, you need to create an item for + it in this file. Fix is to compare across + ALL_RESOURCES_BY_URL. */ + + + +METADATA['zh-cn'].extras = METADATA['zh-cn'].extras.concat([ + { + "title":"Google Play应用政策中心", + "category":"google play", + "summary":"一个方便你了解Google Play政策和指南的中心资源。", + "url":"https://support.google.com/googleplay/android-developer/answer/4430948?hl=zh-Hans", + "group":"", + "lang":"zh-cn", + "keywords": [], + "tags": [], + "image":"http://storage.googleapis.com/support-kms-prod/SNP_712EA2784949DDF085C46E3BE7B1DC618A09_4389397_en_v0", + "type":"distribute" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/1169947?hl=zh-Hans", + "timestamp": 1194884220000, + "image": "images/play_dev.jpg", + "title": "以多种货币销售应用", + "summary": "如何在Google Play为应用定价", + "keywords": [], + "type": "distribute", + "category": "guide" + }, + { + "title": "支持向Google Play用户发布应用的地区", + "lang": "zh-cn", + "category":"", + "summary": "支持向Google Play用户发布应用的国家/地区。", + "url":"https://support.google.com/googleplay/android-developer/answer/138294?hl=zh-Hans", + "group":"", + "keywords": [], + "tags": [], + "image":"images/play_dev.jpg", + "type":"google" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/188189?hl=zh-Hans", + "timestamp": 1194884220000, + "image": "images/play_dev.jpg", + "title": "针对Google Play为你的应用内容分级", + "summary": "如何为你的应用内容分级。", + "keywords": [], + "type": "support", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/113477?hl=zh-Hans", + "timestamp": 1194884220000, + "image": "images/play_dev.jpg", + "title": "为用户提供支持", + "summary": "为用户提供支持的各种选择。", + "keywords": [], + "type": "support", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://play.google.com/apps/publish/?hl=zh-Hans", + "timestamp": 1194884220000, + "image": null, + "title": "Google Play 开发者控制台", + "summary": "发布应用的开发者控制台", + "keywords": [], + "type": "guide", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/topic/2364761?hl=zh-Hans", + "timestamp": 1194884220000, + "image": "images/play_dev.jpg", + "title": "政策和最佳做法", + "summary": "内容政策和流程", + "keywords": [], + "type": "distribute", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/138412?hl=zh-Hans", + "timestamp": 1194884220000, + "image": "images/play_dev.jpg", + "title": "各国家/地区获许定价范围和货币", + "summary": "各国家/地区获许定价范围和货币列表", + "keywords": [], + "type": "guide", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/112622?hl=zh-Hans", + "timestamp": 1194884220000, + "image": "images/play_dev.jpg", + "title": "交易费用", + "summary": "销售的应用和应用内产品的交易费。", + "keywords": [], + "type": "guide", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/138000?hl=zh-Hans", + "timestamp": 1194884220000, + "image": "images/play_dev.jpg", + "title": "税率", + "summary": "如何设置不同国家/地区的税率", + "keywords": [], + "type": "guide", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/113475?hl=zh-Hans", + "timestamp": 1194884220000, + "image": "images/play_dev.jpg", + "title": "类别", + "summary": "应用的类别列表。", + "keywords": [], + "type": "guide", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/113476?hl=zh-Hans", + "timestamp": 1194884220000, + "image": "images/play_dev.jpg", + "title": "更新应用", + "summary": "更新Google Play应用的要求。", + "keywords": [], + "type": "guide", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/1153479?hl=zh-Hans", + "timestamp": 1194884220000, + "image": null, + "title": "应用内结算", + "summary": "如何正确设置应用内商品和订阅结算。", + "keywords": [], + "type": "guide", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://support.google.com/googleplay/android-developer/answer/1078870?hl=zh-Hans", + "timestamp": 1194884220000, + "image": "images/play_dev.jpg", + "title": "为你的应用的图片资源", + "summary": "如何在你的应用的商品详情页面上添加图片资源。", + "keywords": [], + "type": "guide", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://support.google.com/payments/answer/2741495?hl=zh-Hans", + "timestamp": null, + "image": null, + "title": "退回訂單款項", + "summary": "如何退还已收取的订单款项。", + "keywords": [], + "type": "guide", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": ["localization", "pricing", "developer support"], + "url": "https://support.google.com/googleplay/android-developer/table/3541286?hl=zh-Hans", + "timestamp": null, + "image": "images/play_dev.jpg", + "title": "支持向Google Play用户发布应用的地区", + "summary": "支持向Google Play用户发布应用的国家/地区。", + "keywords": [], + "type": "distribute", + "category": "" + }, + { + "lang": "zh-cn", + "group": "", + "tags": [], + "url": "https://developers.google.com/edu/guidelines?hl=zh-Hans", + "timestamp": null, + "image": "https://developer.android.com/distribute/images/edu-guidelines.jpg", + "title": "Education Guidelines", + "summary": "These guidelines and requirements help you develop great apps for students, which offer compelling content and an intuitive user experience on Android tablets.", + "keywords": [], + "type": "", + "category": "" + }, +]); + +/** + * Static metadata collections. + */ +METADATA['zh-cn'].collections = { + "overview/zhcn/1": { + "title": "", + "resources": [ + "intl/zh-cn/distribute/essentials/quality/core.html", + "intl/zh-cn/distribute/essentials/quality/tablets.html", + "intl/zh-cn/distribute/tools/launch-checklist.html", + "intl/zh-cn/tools/publishing/publishing_overview.html", + "intl/zh-cn/distribute/tools/localization-checklist.html" + ] + }, + "overview/zhcn/2": { + "title": "", + "resources": [ + "intl/zh-cn/google/play/billing/index.html", + "intl/zh-cn/google/play/billing/api.html", + "intl/zh-cn/google/play/billing/billing_admin.html", + "intl/zh-cn/google/play/billing/billing_testing.html", + "intl/zh-cn/google/play/billing/billing_best_practices.html" + ] + }, + "overview/zhcn/3": { + "title": "", + "resources": [ + "https://play.google.com/intl/en_us/badges/", + "intl/zh-cn/distribute/tools/promote/device-art.html", + "intl/zh-cn/distribute/tools/promote/linking.html", + "intl/zh-cn/distribute/tools/promote/brand.html", + "intl/zh-cn/tools/help/proguard.html" + ] + }, + "overview/zhcn/4": { + "title": "", + "resources": [ + "intl/zh-cn/design/style/writing.html", + "intl/zh-cn/training/basics/fragments/fragment-ui.html", + "intl/zh-cn/training/multiscreen/index.html", + "intl/zh-cn/training/monitoring-device-state/index.html" + ] + }, + "overview/carousel/zhcn": { + "title": "", + "resources": [ + "https://www.youtube.com/watch?v=vGV7FHGzpFU", + "https://www.youtube.com/watch?v=aqc3ZOTzpdk", + "https://www.youtube.com/watch?v=jaNrJ8uyLSc" + ] + }, +};
\ No newline at end of file diff --git a/docs/html/jd_extras_zh-tw.js b/docs/html/jd_extras_zh-tw.js new file mode 100644 index 000000000000..f41598efa12d --- /dev/null +++ b/docs/html/jd_extras_zh-tw.js @@ -0,0 +1,13 @@ + +//must use intl/nn to override translated resources +METADATA['zh-tw'].carousel = { + "intl/zh-tw/distribute/googleplay/guide.html": { + "image": "images/distribute/hero-secrets-to-app-success.jpg", + }, +}; + +/** + * Static metadata collections for this language. + */ +METADATA['zh-tw'].collections = { +};
\ No newline at end of file diff --git a/docs/html/legal.jd b/docs/html/legal.jd index 5ee6b5c31495..0a685082d5d7 100644..100755 --- a/docs/html/legal.jd +++ b/docs/html/legal.jd @@ -70,12 +70,10 @@ Policy & Terms of Service</a>.</p> restrictions. Such services include:</p> <dl> - <dt>Eclipse Android Developer Tools Plugin</dt> - <dd>If you're developing apps with the Eclipse IDE, we offer a free plugin called the -<a href="{@docRoot}tools/sdk/eclipse-adt.html">Android Developer Tools</a> (ADT) to speed up your -development and debugging. Certain code within the ADT plugin and other packages available -from the SDK Manager require that you agree to terms and conditions for use, reproduction and -distribution upon installation.</dd> + <dt>Android Studio</dt> + <dd>Android Studio and other packages available from the SDK manager require that you agree +to terms and conditions +for use, reproduction and distribution upon installation.</dd> <dt>Google Play</dt> <dd>Google Play is a publicly available service through which you can distribute your apps for diff --git a/docs/html/ndk/downloads/index.jd b/docs/html/ndk/downloads/index.jd index 391a7d5e37f0..f67499360aee 100644 --- a/docs/html/ndk/downloads/index.jd +++ b/docs/html/ndk/downloads/index.jd @@ -1,32 +1,8 @@ ndk=true page.template=sdk - - -ndk.mac64_download=android-ndk-r10e-darwin-x86_64.bin -ndk.mac64_bytes=388937326 -ndk.mac64_checksum=2cb8893a5701603519d38a7e04c50e81 - -ndk.linux64_download=android-ndk-r10e-linux-x86_64.bin -ndk.linux64_bytes=401522849 -ndk.linux64_checksum=19af543b068bdb7f27787c2bc69aba7f - -ndk.linux32_download=android-ndk-r10e-linux-x86.bin -ndk.linux32_bytes=394281908 -ndk.linux32_checksum=c3edd3273029da1cbd2f62c48249e978 - -ndk.win64_download=android-ndk-r10e-windows-x86_64.exe -ndk.win64_bytes=419616132 -ndk.win64_checksum=8412bb4991a95e08fda50b5a44d95df7 - -ndk.win32_download=android-ndk-r10e-windows-x86.exe -ndk.win32_bytes=396563176 -ndk.win32_checksum=1a82445baaf62aec3a46386ab1e5772c - - - page.title=NDK Downloads -@jd:body +@jd:body <div id="tos" style="display:none;width:760px;height:0;margin:0 auto"> @@ -320,7 +296,7 @@ injunctive remedies (or an equivalent type of urgent legal relief) in any jurisd <input id="agree" type="checkbox" name="agree" value="1" onclick="onAgreeChecked()" /> <label id="agreeLabel" for="agree">I have read and agree with the above terms and conditions</label> </p> -<p><a href="" class="button disabled ndk" id="downloadForRealz" onclick="return onDownloadNdkForRealz(this);"></a></p> +<p><a href="" class="dac-button dac-raised dac-primary disabled ndk" id="downloadForRealz" onclick="return onDownloadNdkForRealz(this);"></a></p> </div> diff --git a/docs/html/ndk/guides/guides_toc_new.cs b/docs/html/ndk/guides/guides_toc_new.cs new file mode 100644 index 000000000000..981eb5131fac --- /dev/null +++ b/docs/html/ndk/guides/guides_toc_new.cs @@ -0,0 +1,75 @@ +<?cs # Table of contents for Dev Guide. + + For each document available in translation, add an localized title to this TOC. + Do not add localized title for docs not available in translation. + Below are template spans for adding localized doc titles. Please ensure that + localized titles are added in the language order specified below. +?> + +<ul id="nav"> + <li class="nav-section"> + <div class="nav-section-header"><a href="<?cs var:toroot ?>ndk/guides/index.html"> + <span class="en">Getting Started</span></a></div> + <ul> + <li><a href="<?cs var:toroot ?>ndk/guides/setup.html">Setup</a></li> + <li><a href="<?cs var:toroot ?>ndk/guides/concepts.html">Concepts</a></li> + </ul> + </li> + + <li class="nav-section"> + <div class="nav-section-header"><a href="<?cs var:toroot ?>ndk/guides/build.html"> + <span class="en"> + Building</span></a></div> + <ul> + <li><a href="<?cs var:toroot ?>ndk/guides/android_mk.html">Android.mk</a></li> + <li><a href="<?cs var:toroot ?>ndk/guides/application_mk.html">Application.mk</a></li> + <li><a href="<?cs var:toroot ?>ndk/guides/ndk-build.html">ndk-build</a></li> + <li><a href="<?cs var:toroot ?>ndk/guides/standalone_toolchain.html">Standalone Toolchain + </a></li> + </ul> + </li> + + <li class="nav-section"> + <div class="nav-section-header"><a href="<?cs var:toroot ?>ndk/guides/arch.html"> + <span class="en">Architectures and CPUs</span></a></div> + <ul> + <li><a href="<?cs var:toroot ?>ndk/guides/abis.html">ABI Management</a></li> + <li><a href="<?cs var:toroot ?>ndk/guides/cpu-arm-neon.html">NEON</a></li> + <li><a href="<?cs var:toroot ?>ndk/guides/x86.html">x86</a></li> + <li><a href="<?cs var:toroot ?>ndk/guides/x86-64.html">x86-64</a></li> + <li><a href="<?cs var:toroot ?>ndk/guides/mips.html">MIPS</a></li> + <li><a href="<?cs var:toroot ?>ndk/guides/cpu-features.html">The cpufeatures Library</a> + </li> + </ul> + </li> + + <li class="nav-section"> + <div class="nav-section-header"><a href="<?cs var:toroot ?>ndk/guides/debug.html"> + <span class="en">Debugging</span></a></div> + <ul> + <li><a href="<?cs var:toroot ?>ndk/guides/ndk-gdb.html">ndk-gdb</a></li> + <li><a href="<?cs var:toroot ?>ndk/guides/ndk-stack.html">ndk-stack</a></li> + </ul> + </li> + + <li class="nav-section"> + <div class="nav-section-header"><a href="<?cs var:toroot ?>ndk/guides/libs.html"> + <span class="en">Libraries</span></a></div> + <ul> + <li><a href="<?cs var:toroot ?>ndk/guides/prebuilts.html">Prebuilt Libraries</a></li> + <li><a href="<?cs var:toroot ?>ndk/guides/cpp-support.html">C++ Support</a></li> + <li><a href="<?cs var:toroot ?>ndk/guides/stable_apis.html">Stable APIs</a></li> + + </ul> + </li> + +</ul> + + +<script type="text/javascript"> +<!-- + buildToggleLists(); + changeNavLang(getLangPref()); +//--> +</script> + diff --git a/docs/html/ndk/index.jd b/docs/html/ndk/index.jd index a88c15df5fb5..fc1c595e748b 100644 --- a/docs/html/ndk/index.jd +++ b/docs/html/ndk/index.jd @@ -40,11 +40,12 @@ footer.hide=1 <i class="dac-sprite dac-arrow-down-gray"></i> </a> </div> -<section class="dac-section dac-gray dac-small dac-invert" id="latest"><div class="wrap"> +<section class="dac-section dac-gray dac-small" id="latest"><div class="wrap"> <h2 class="norule">Latest</h2> <div class="resource-widget resource-flow-layout col-16" data-query="type:blog+tag:ndk" data-cardSizes="6x6" data-maxResults="9" + data-items-per-page="6" data-initial-results="3"></div> </div></section> diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd index 5db013c860d5..7d733a6eaf37 100644 --- a/docs/html/sdk/index.jd +++ b/docs/html/sdk/index.jd @@ -1,58 +1,10 @@ page.title=Download Android Studio and SDK Tools -page.tags=sdk, android studio +page.tags="sdk, android studio,tools" page.template=sdk page.image=images/cards/android-studio_2x.png header.hide=1 page.metaDescription=Download the official Android IDE and developer tools to build apps for Android phones, tablets, wearables, TVs, and more. -studio.version=1.5.1.0 - -studio.linux_bundle_download=android-studio-ide-141.2456560-linux.zip -studio.linux_bundle_bytes=380943097 -studio.linux_bundle_checksum=b8460a2197abe26979d88e3b01b3c8bfd80a37db - -studio.mac_bundle_download=android-studio-ide-141.2456560-mac.dmg -studio.mac_bundle_bytes=367456698 -studio.mac_bundle_checksum=d0807423985757195ad5ae4717d580deeba1dbd8 - -studio.win_bundle_download=android-studio-ide-141.2456560-windows.zip -studio.win_bundle_bytes=375635150 -studio.win_bundle_checksum=64882fb967f960f2142de239200104cdc9b4c75b - - -studio.win_bundle_exe_download=android-studio-bundle-141.2456560-windows.exe -studio.win_bundle_exe_bytes=1209163328 -studio.win_bundle_exe_checksum=6ffe608b1dd39041a578019eb3fedb5ee62ba545 - -studio.win_notools_exe_download=android-studio-ide-141.2456560-windows.exe -studio.win_notools_exe_bytes=351419656 -studio.win_notools_exe_checksum=8d016b90bf04ebac6ce548b1976b0c8a4f46b5f9 - - - - -sdk.linux_download=android-sdk_r24.4.1-linux.tgz -sdk.linux_bytes=326412652 -sdk.linux_checksum=725bb360f0f7d04eaccff5a2d57abdd49061326d - -sdk.mac_download=android-sdk_r24.4.1-macosx.zip -sdk.mac_bytes=102781947 -sdk.mac_checksum=85a9cccb0b1f9e6f1f616335c5f07107553840cd - -sdk.win_download=android-sdk_r24.4.1-windows.zip -sdk.win_bytes=199701062 -sdk.win_checksum=66b6a6433053c152b22bf8cab19c0f3fef4eba49 - - -sdk.win_installer=installer_r24.4.1-windows.exe -sdk.win_installer_bytes=151659917 -sdk.win_installer_checksum=f9b59d72413649d31e633207e31f456443e7ea0b - - - - - - @jd:body <style type="text/css"> @@ -257,7 +209,7 @@ This is the Android Software Development Kit License Agreement <input id="agree" type="checkbox" name="agree" value="1" onclick="onAgreeChecked()" /> <label id="agreeLabel" for="agree">I have read and agree with the above terms and conditions</label> </p> -<p><a href="" class="button disabled" id="downloadForRealz" onclick="return onDownloadForRealz(this);"></a></p> +<p><a href="" class="dac-button dac-raised dac-primary disabled ndk" id="downloadForRealz" onclick="return onDownloadForRealz(this);"></a></p> </div> @@ -278,7 +230,7 @@ width="760" alt="" /> <div style="color: #fff; width:226px; height:0; overflow:visible; position:absolute; top:40px; left:25px"> -<h1 class="studio-logo" style="margin:0 0 35px !important">Android Studio</h1> +<h1 class="studio-logo" style="margin:0 0 35px !important;padding:0 !important">Android Studio</h1> <p style="font-size: 16px; color:#bbb; position: absolute;left: 297px; top: 5px; display: block; width: 400px;text-align: center;">The official Android IDE</p> diff --git a/docs/html/sdk/installing/adding-packages.jd b/docs/html/sdk/installing/adding-packages.jd index 88619bd4084c..2911c38adce0 100644 --- a/docs/html/sdk/installing/adding-packages.jd +++ b/docs/html/sdk/installing/adding-packages.jd @@ -31,7 +31,7 @@ ol.large > li > h2 { line-height:20px; padding:0 0 0 20px; margin:0 0 20px 0; - display:inline-block; + display:inline; font-weight:normal; } ol.large > li:nth-child(1):before { diff --git a/docs/html/sdk/installing/studio-tips.jd b/docs/html/sdk/installing/studio-tips.jd index 6c944abbbb35..113388f40ea8 100644 --- a/docs/html/sdk/installing/studio-tips.jd +++ b/docs/html/sdk/installing/studio-tips.jd @@ -1,4 +1,7 @@ page.title=Android Studio Tips and Tricks +page.image=images/tools/studio-previewall.png +page.tags="sdk", "studio", "android studio" +meta.tags="studio" @jd:body <div id="qv-wrapper"> diff --git a/docs/html/sdk/sdk_vars.cs b/docs/html/sdk/sdk_vars.cs new file mode 100644 index 000000000000..c911f5a16bb6 --- /dev/null +++ b/docs/html/sdk/sdk_vars.cs @@ -0,0 +1,59 @@ +<?cs +set:studio.version='1.5.1.0' ?><?cs + + +set:studio.linux_bundle_download='android-studio-ide-141.2456560-linux.zip' ?><?cs +set:studio.linux_bundle_bytes='380943097' ?><?cs +set:studio.linux_bundle_checksum='b8460a2197abe26979d88e3b01b3c8bfd80a37db' ?><?cs + +set:studio.mac_bundle_download='android-studio-ide-141.2456560-mac.dmg' ?><?cs +set:studio.mac_bundle_bytes='367456698' ?><?cs +set:studio.mac_bundle_checksum='d0807423985757195ad5ae4717d580deeba1dbd8' ?><?cs + +set:studio.win_bundle_download='android-studio-ide-141.2456560-windows.zip' ?><?cs +set:studio.win_bundle_bytes='375635150' ?><?cs +set:studio.win_bundle_checksum='64882fb967f960f2142de239200104cdc9b4c75b' ?><?cs + +set:studio.win_bundle_exe_download='android-studio-bundle-141.2456560-windows.exe' ?><?cs +set:studio.win_bundle_exe_bytes='1209163328' ?><?cs +set:studio.win_bundle_exe_checksum='6ffe608b1dd39041a578019eb3fedb5ee62ba545' ?><?cs + +set:studio.win_notools_exe_download='android-studio-ide-141.2456560-windows.exe' ?><?cs +set:studio.win_notools_exe_bytes='351419656' ?><?cs +set:studio.win_notools_exe_checksum='8d016b90bf04ebac6ce548b1976b0c8a4f46b5f9' ?><?cs + + +set:sdk.linux_download='android-sdk_r24.4.1-linux.tgz' ?><?cs +set:sdk.linux_bytes='326412652' ?><?cs +set:sdk.linux_checksum='725bb360f0f7d04eaccff5a2d57abdd49061326d' ?><?cs + +set:sdk.mac_download='android-sdk_r24.4.1-macosx.zip' ?><?cs +set:sdk.mac_bytes='102781947' ?><?cs +set:sdk.mac_checksum='85a9cccb0b1f9e6f1f616335c5f07107553840cd' ?><?cs + +set:sdk.win_download='android-sdk_r24.4.1-windows.zip' ?><?cs +set:sdk.win_bytes='199701062' ?><?cs +set:sdk.win_checksum='66b6a6433053c152b22bf8cab19c0f3fef4eba49' ?><?cs +set:sdk.win_installer='installer_r24.4.1-windows.exe' ?><?cs +set:sdk.win_installer_bytes='151659917' ?><?cs +set:sdk.win_installer_checksum='f9b59d72413649d31e633207e31f456443e7ea0b' ?><?cs + + +set:ndk.mac64_download='android-ndk-r10e-darwin-x86_64.bin' ?><?cs +set:ndk.mac64_bytes='388937326' ?><?cs +set:ndk.mac64_checksum='2cb8893a5701603519d38a7e04c50e81' ?><?cs + +set:ndk.linux64_download='android-ndk-r10e-linux-x86_64.bin' ?><?cs +set:ndk.linux64_bytes='401522849' ?><?cs +set:ndk.linux64_checksum='19af543b068bdb7f27787c2bc69aba7f' ?><?cs +set:ndk.linux32_download='android-ndk-r10e-linux-x86.bin' ?><?cs +set:ndk.linux32_bytes='394281908' ?><?cs +set:ndk.linux32_checksum='c3edd3273029da1cbd2f62c48249e978' ?><?cs + +set:ndk.win64_download='android-ndk-r10e-windows-x86_64.exe' ?><?cs +set:ndk.win64_bytes='419616132' ?><?cs +set:ndk.win64_checksum='8412bb4991a95e08fda50b5a44d95df7' ?><?cs +set:ndk.win32_download='android-ndk-r10e-windows-x86.exe' ?><?cs +set:ndk.win32_bytes='396563176' ?><?cs +set:ndk.win32_checksum='1a82445baaf62aec3a46386ab1e5772c' +?>
\ No newline at end of file diff --git a/docs/html/sdk/win-usb.jd b/docs/html/sdk/win-usb.jd index cb3e7bdec5f8..c08f6fd904ad 100644 --- a/docs/html/sdk/win-usb.jd +++ b/docs/html/sdk/win-usb.jd @@ -155,7 +155,7 @@ This is the Android Software Development Kit License Agreement <input id="agree" type="checkbox" name="agree" value="1" onclick="onAgreeChecked()" /> <label id="agreeLabel" for="agree">I have read and agree with the above terms and conditions</label> </p> -<p><a href="" class="button disabled" id="downloadForRealz" onclick="return onDownloadForRealz(this);"></a></p> +<p><a href="" class="dac-button dac-raised dac-primary disabled ndk" id="downloadForRealz" onclick="return onDownloadForRealz(this);"></a></p> </div> diff --git a/docs/html/support.jd b/docs/html/support.jd index 9ef4a16d0075..0d87961bddc9 100644 --- a/docs/html/support.jd +++ b/docs/html/support.jd @@ -1,8 +1,7 @@ -page.title=Developer Support +page.title=Developer Support Resources page.type=about fullpage=1 -page.metaDescription=Resources available to help you report and resolve issues while you are developing apps for Android. -page.image=/images/android-support-card.png +page.metaDescription=Links to community and support resources for Android developers. @jd:body diff --git a/docs/html/tools/debugging/debugging-memory.jd b/docs/html/tools/debugging/debugging-memory.jd index 261df932c8d2..71c009d7ddf2 100644..100755 --- a/docs/html/tools/debugging/debugging-memory.jd +++ b/docs/html/tools/debugging/debugging-memory.jd @@ -42,7 +42,7 @@ memory usage with tools. This guide shows you how to do that.</p> <p>The simplest place to begin investigating your app’s memory usage is the runtime log messages. Sometimes when a GC occurs, a message is printed to <a href="{@docRoot}tools/help/logcat.html">logcat</a>. The logcat output is also available in the -Device Monitor or directly in IDEs such as Eclipse and Android Studio.</p> +Device Monitor or directly in an IDE such as Android Studio.</p> <h3 id="DalvikLogMessages">Dalvik Log Messages</h3> @@ -240,7 +240,7 @@ can view real-time updates to your app's heap in Android Studio's <h3>Memory Monitor in Android Studio</h3> <p>Use Android Studio to view your app's memory use: </p> -<ul> +<ol> <li>Start your app on a connected device or emulator.</li> <li>Open the Android run-time window, and view the free and allocated memory in the Memory Monitor. </li> @@ -260,7 +260,7 @@ can view real-time updates to your app's heap in Android Studio's </li> <li>Identify which actions in your app are likely causing too much allocation and determine where in your app you should try to reduce allocations and release resources. -</ul> +</ol> <h3>Device Monitor </h3> <ol> @@ -628,7 +628,7 @@ can track down problems you might have identified while viewing heap updates.</p <p>To retrieve your heap dump from within Android Studio, use the -<a href="{@docRoot}tools/studio/index.html#me-cpu">Memory Monitor</a> and +<a href="{@docRoot}tools/studio/index.html#mem-cpu">Memory Monitor</a> and <a href="{@docRoot}tools/studio/index.html#heap-dump">HPROF viewer</a>. <p>You can also still perform these procedures in the Android monitor:</p> @@ -655,10 +655,12 @@ HPROF tool. The major difference in an Android heap dump is due to the fact that number of allocations in the Zygote process. But because the Zygote allocations are shared across all app processes, they don’t matter very much to your own heap analysis.</p> -<p>To analyze your heap dump, you can use a standard tool like jhat or the <a href= -"http://www.eclipse.org/mat/downloads.php">Eclipse Memory Analyzer Tool</a> (MAT). However, first +<p>To analyze your heap dump, you can use <a href= +"{@docRoot}tools/help/am-memory.html">Memory Monitor</a> in Android Studio. +You can also use a standard tool like jhat. However, first you'll need to convert the HPROF file from Android's format to the J2SE HPROF format. You can do -this using the <code>hprof-conv</code> tool provided in the <code><sdk>/platform-tools/</code> +this using the <code>hprof-conv</code> tool provided in the +<code><sdk>/platform-tools/</code> directory. Simply run the <code>hprof-conv</code> command with two arguments: the original HPROF file and the location to write the converted HPROF file. For example:</p> @@ -666,11 +668,9 @@ file and the location to write the converted HPROF file. For example:</p> hprof-conv heap-original.hprof heap-converted.hprof </pre> -<p class="note"><strong>Note:</strong> If you're using the version of DDMS that's integrated into -Eclipse, you do not need to perform the HPROF conversation—it performs the conversion by -default.</p> -<p>You can now load the converted file in MAT or another heap analysis tool that understands + +<p>You can now load the converted file into a heap analysis tool that understands the J2SE HPROF format.</p> <p>When analyzing your heap, you should look for memory leaks caused by:</p> @@ -682,77 +682,6 @@ reference to the container Activity or Context.</li> </ul> -<h3 id="EclipseMat">Using the Eclipse Memory Analyzer Tool</h3> - -<p>The <a href= -"http://www.eclipse.org/mat/downloads.php">Eclipse Memory Analyzer Tool</a> (MAT) is just one -tool that you can use to analyze your heap dump. It's also quite powerful so most of its -capabilities are beyond the scope of this document, but here are a few tips to get you started. - -<p>Once you open your converted HPROF file in MAT, you'll see a pie chart in the Overview, -showing what your largest objects are. Below this chart, are links to couple of useful features:</p> - -<ul> - <li>The <strong>Histogram view</strong> shows a list of all classes and how many instances - there are of each. - <p>You might want to use this view to find extra instances of classes for which you know there - should be only a certain number. For example, a common source of leaks is additional instance of - your {@link android.app.Activity} class, for which you should usually have only one instance - at a time. To find a specific class instance, type the class name into the <em><Regex></em> - field at the top of the list. - <p>When you find a class with too many instances, right-click it and select - <strong>List objects</strong> > <strong>with incoming references</strong>. In the list that - appears, you can determine where an instance is retained by right-clicking it and selecting - <strong>Path To GC Roots</strong> > <strong>exclude weak references</strong>.</p> - </li> - - <li>The <strong>Dominator tree</strong> shows a list of objects organized by the amount - of retained heap. - <p>What you should look for is anything that's retaining a portion of heap that's roughly - equivalent to the memory size you observed leaking from the <a href="#LogMessages">GC logs</a>, - <a href="#ViewHeap">heap updates</a>, or <a href="#TrackAllocations">allocation - tracker</a>. - <p>When you see something suspicious, right-click on the item and select - <strong>Path To GC Roots</strong> > <strong>exclude weak references</strong>. This opens a - new tab that traces the references to that object which is causing the alleged leak.</p> - - <p class="note"><strong>Note:</strong> Most apps will show an instance of - {@link android.content.res.Resources} near the top with a good chunk of heap, but this is - usually expected when your app uses lots of resources from your {@code res/} directory.</p> - </li> -</ul> - - -<img src="{@docRoot}images/tools/mat-histogram@2x.png" width="760" alt="" /> -<p class="img-caption"><strong>Figure 4.</strong> The Eclipse Memory Analyzer Tool (MAT), -showing the Histogram view and a search for "MainActivity".</p> - -<p>For more information about MAT, watch the Google I/O 2011 presentation, -<a href="http://www.youtube.com/watch?v=_CruQY55HOk">Memory management for Android apps</a>, -which includes a walkthrough using MAT beginning at about <a href= -"http://www.youtube.com/watch?v=_CruQY55HOk&feature=player_detailpage#t=1270">21:10</a>. -Also refer to the <a href="http://wiki.eclipse.org/index.php/MemoryAnalyzer">Eclipse Memory -Analyzer documentation</a>.</p> - -<h4 id="MatCompare">Comparing heap dumps</h4> - -<p>You may find it useful to compare your app's heap state at two different points in time in order -to inspect the changes in memory allocation. To compare two heap dumps using MAT:</p> - -<ol> - <li>Create two HPROF files as described above, in <a href="#HeapDump">Capturing a Heap Dump</a>. - <li>Open the first HPROF file in MAT (<strong>File</strong> > <strong>Open Heap Dump</strong>). - <li>In the Navigation History view (if not visible, select <strong>Window</strong> > - <strong>Navigation History</strong>), right-click on <strong>Histogram</strong> and select - <strong>Add to Compare Basket</strong>. - <li>Open the second HPROF file and repeat steps 2 and 3. - <li>Switch to the <em>Compare Basket</em> view and click <strong>Compare the Results</strong> - (the red "!" icon in the top-right corner of the view). -</ol> - - - - <h2 id="TriggerLeaks">Triggering Memory Leaks</h2> diff --git a/docs/html/tools/help/adb.jd b/docs/html/tools/help/adb.jd index 2faff4f3fe5c..06e009948d6e 100644..100755 --- a/docs/html/tools/help/adb.jd +++ b/docs/html/tools/help/adb.jd @@ -29,7 +29,7 @@ three components: </p> <ul> <li>A client, which runs on your development machine. You can invoke a client from a shell -by issuing an adb command. Other Android tools such as the ADT plugin and DDMS also create +by issuing an adb command. Other Android tools such as DDMS also create adb clients. </li> <li>A server, which runs as a background process on your development machine. The server manages communication between the client and the adb daemon running on an emulator or device. </li> @@ -361,7 +361,7 @@ the hardware device. <p>For more information about how to create an .apk file that you can install on an emulator/device instance, see <a href="{@docRoot}tools/building/index.html">Building and Running</a></p> -<p>Note that, if you are using the Eclipse IDE and have the ADT plugin installed, you do not need to use adb (or aapt) directly to install your application on the emulator/device. Instead, the ADT plugin handles the packaging and installation of the application for you. </p> +<p>Note that, if you are using Android Studio, you do not need to use adb (or aapt) directly to install your application on the emulator/device. Instead, Android Studio handles the packaging and installation of the application for you. </p> diff --git a/docs/html/tools/help/proguard.jd b/docs/html/tools/help/proguard.jd index 5482399522ec..e26aca0e823b 100755 --- a/docs/html/tools/help/proguard.jd +++ b/docs/html/tools/help/proguard.jd @@ -1,6 +1,7 @@ page.title=ProGuard parent.title=Tools parent.link=index.html +page.metaDescription=Use ProGuard to shrink, optimize, and obfuscate your code prior to release. @jd:body <div id="qv-wrapper"> diff --git a/docs/html/tools/help/sdk-manager.jd b/docs/html/tools/help/sdk-manager.jd index cc95edf6bf6a..c8493dcfa3b5 100644..100755 --- a/docs/html/tools/help/sdk-manager.jd +++ b/docs/html/tools/help/sdk-manager.jd @@ -34,7 +34,7 @@ SDK checking: </p> </ul> <p class="note"><strong>Tip:</strong> The standalone SDK Manager is still available from the -command line, but we recommend it only for use with Eclipse ADT and standalone SDK installations.</p> +command line, but we recommend it only for use with standalone SDK installations.</p> <p>By default, the SDK Manager installs the latest packages and tools. Click the checkbox next to each additional SDK platform and tool that you want to install. Clear the @@ -99,7 +99,7 @@ Android Virtual Devices (AVDs) in the Android APIs (such as <a href="{@docRoot}guide/components/fragments.html">fragments</a>, plus others not included in the framework at all) on devices running a platform version as old as Android 1.6. All of the activity templates available when creating -a new project with the <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> +a new project with Android Studio require this. For more information, read <a href="{@docRoot}tools/support-library/index.html">Support Library</a>.</dd> diff --git a/docs/html/tools/help/zipalign.jd b/docs/html/tools/help/zipalign.jd index 184cdcb6ad22..c70810cd66df 100644..100755 --- a/docs/html/tools/help/zipalign.jd +++ b/docs/html/tools/help/zipalign.jd @@ -16,12 +16,12 @@ when running the application.</p> <p>This tool should always be used to align your .apk file before distributing it to end-users. The Android build tools can handle -this for you. When using Eclipse with the ADT plugin, the Export Wizard -will automatically zipalign your .apk after it signs it with your private key. +this for you. Android Studio automatically aligns your .apk after it signs it with your +private key. The build scripts used -when compiling your application with Ant will also zipalign your .apk, +when compiling your application with Gradle also align your .apk, as long as you have provided the path to your keystore and the key alias in -your project {@code ant.properties} file, so that the build tools +your project {@code gradle.properties} file, so that the build tools can sign the package first.</p> <p class="caution"><strong>Caution:</strong> zipalign must only be performed diff --git a/docs/html/tools/publishing/preparing.jd b/docs/html/tools/publishing/preparing.jd index 0b61aa7b3b67..3acaedcf40c8 100644 --- a/docs/html/tools/publishing/preparing.jd +++ b/docs/html/tools/publishing/preparing.jd @@ -1,4 +1,5 @@ page.title=Preparing for Release +page.metaDescription=Developer documentation on how to build the signed, release-ready APK. This process is the same for all Android apps. @jd:body <div id="qv-wrapper"> diff --git a/docs/html/tools/publishing/publishing_overview.jd b/docs/html/tools/publishing/publishing_overview.jd index e42b2fbfd716..167758a279bd 100644 --- a/docs/html/tools/publishing/publishing_overview.jd +++ b/docs/html/tools/publishing/publishing_overview.jd @@ -1,4 +1,5 @@ page.title=Publishing Overview +page.metaDescription=Start here for an overview of publishing options for Android apps. @jd:body <div id="qv-wrapper"> diff --git a/docs/html/tools/revisions/gradle-plugin.jd b/docs/html/tools/revisions/gradle-plugin.jd index b7d7630ad338..20f6b340ad4b 100644 --- a/docs/html/tools/revisions/gradle-plugin.jd +++ b/docs/html/tools/revisions/gradle-plugin.jd @@ -584,9 +584,9 @@ android { <h2>Updating the Android Plugin for Gradle Version</h2> <p>The Android Plugin for Gradle version is specified in the -<strong>File > Project Structure</strong> menu or the project-level +<strong>File > Project Structure > Project</strong> menu and the project-level <code>build.gradle</code> file. The plugin version applies to all modules built in that -Android Studio project. This example updates the Android Plugin for Gradle to version 1.1.0: +Android Studio project. This example sets the Android Plugin for Gradle to version 1.1.0 from the <code>build.gradle</code> file: <pre> ... dependencies { @@ -600,8 +600,8 @@ Android Studio project. This example updates the Android Plugin for Gradle to ve version numbers. Using this feature can cause unexpected version updates and difficulty resolving version differences. </p> -<p>If you're building with Gradle but using not Android Studio, the build process downloads the -latest Android Plugin for Gradle plugin when it runs. </p> +<p>If you're building with Gradle but not using Android Studio, the build process downloads the +latest Android Plugin for Gradle when it runs. </p> @@ -609,8 +609,8 @@ latest Android Plugin for Gradle plugin when it runs. </p> <p>Android Studio requires Gradle version 2.2.1 or later. To view and update the Gradle version, edit the Gradle distribution reference in the -<code>gradle/wrapper/gradle-wrapper.properties</code> file. This example shows the -Android Plugin for Gradle version set to 2.2.1.</p> +<code>gradle/wrapper/gradle-wrapper.properties</code> file. This example sets the +Gradle version to 2.2.1.</p> <pre> ... @@ -618,14 +618,6 @@ distributionUrl=http\://services.gradle.org/distributions/gradle-2.2.1-all.zip ... </pre> - - - <p>For more details about the supported Android Plugin for Gradle properties and syntax, click the link to the -<a href="{@docRoot}tools/building/plugin-for-gradle.html">Plugin Language Reference</a>.</p> - - - - - +<a href="{@docRoot}tools/building/plugin-for-gradle.html">Plugin Language Reference</a>.</p>
\ No newline at end of file diff --git a/docs/html/tools/studio/studio-features.jd b/docs/html/tools/studio/studio-features.jd index 46ec79db26ba..0894a257be7c 100644 --- a/docs/html/tools/studio/studio-features.jd +++ b/docs/html/tools/studio/studio-features.jd @@ -1,6 +1,7 @@ page.title=Features page.metaDescription=Learn about the Android Studio features. -page.tags=studio, features +page.tags="studio", "android studio", "sdk" +page.image=images/cards/card-studio-modules_crop_2x.png @jd:body <div id="qv-wrapper"> diff --git a/docs/html/tools/testing-support-library/index.jd b/docs/html/tools/testing-support-library/index.jd index b29d3019de44..ac21e3ac4637 100644 --- a/docs/html/tools/testing-support-library/index.jd +++ b/docs/html/tools/testing-support-library/index.jd @@ -1,4 +1,5 @@ page.title=Testing Support Library +page.image=images/tools/studio-test-module.png @jd:body diff --git a/docs/html/tools/testing/activity_test.jd b/docs/html/tools/testing/activity_test.jd deleted file mode 100644 index 036407a02eff..000000000000 --- a/docs/html/tools/testing/activity_test.jd +++ /dev/null @@ -1,1321 +0,0 @@ -page.title=Activity Testing Tutorial -parent.title=Testing -parent.link=index.html -@jd:body - <div id="qv-wrapper"> - <div id="qv"> - <h2>In this document</h2> - <ol> - <li> - <a href="#Prerequisites">Prerequisites</a> - </li> - <li> - <a href="#DownloadCode">Installing the Tutorial Sample Code</a> - </li> - <li> - <a href="#SetupEmulator">Setting Up the Emulator</a> - </li> - <li> - <a href="#SetupProjects">Setting Up the Projects</a> - </li> - <li> - <a href="#CreateTestCaseClass">Creating the Test Case Class</a> - <ol> - <li> - <a href="#AddTestCaseClass">Adding the test case class file</a> - </li> - <li> - <a href="#AddConstructor">Adding the test case constructor</a> - </li> - <li> - <a href="#AddSetupMethod">Adding the setup method</a> - </li> - <li> - <a href="#AddPreConditionsTest">Adding an initial conditions test</a> - </li> - <li> - <a href="#AddUITest">Adding a UI test</a> - </li> - <li> - <a href="#StateManagementTests">Adding state management tests</a> - </li> - </ol> - </li> - <li> - <a href="#RunTests">Running the Tests and Seeing the Results</a> - </li> - <li> - <a href="#TestFailure">Forcing Some Tests to Fail</a> - </li> - <li> - <a href="#NextSteps">Next Steps</a> - </li> -</ol> -<h2 id="#Appendix">Appendix</h2> -<ol> - <li> - <a href="#InstallCompletedTestApp">Installing the Completed Test Application File</a> - </li> - <li> - <a href="#EditorCommandLine">For Users Not Developing In Eclipse</a> - </li> -</ol> -<h2>See Also</h2> -<ol> - <li> - <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a> - </li> - <li> - {@link android.test.ActivityInstrumentationTestCase2} - </li> - <li> - {@link junit.framework.Assert} - </li> - <li> - {@link android.test.InstrumentationTestRunner} - </li> -</ol> -</div> -</div> -<p> - Android includes powerful tools for testing applications. The tools extend JUnit with additional features, provide convenience classes for mock Android system objects, and use - instrumentation to give you control over your main application while you are testing it. The entire Android testing environment is discussed in the document - <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>. -</p> -<p> - This tutorial demonstrates the Android testing tools by presenting a simple Android application and then leading you step-by-step through the creation of a test application for it. - The test application demonstrates these key points: -</p> - <ul> - <li> - An Android test is itself an Android application that is linked to the application under test by entries in its <code>AndroidManifest.xml</code> file. - </li> - <li> - Instead of Android components, an Android test application contains one or more test cases. Each of these is a separate class definition. - </li> - <li> - Android test case classes extend the JUnit {@link junit.framework.TestCase} class. - </li> - <li> - Android test case classes for activities extend JUnit and also connect you to the application under test with instrumentation. You can send keystroke or touch events directly to the UI. - </li> - <li> - You choose an Android test case class based on the type of component (application, activity, content provider, or service) you are testing. - </li> - <li> - Additional test tools in Eclipse/ADT provide integrated support for creating test applications, running them, and viewing the results. - </li> - </ul> -<p> - The test application contains methods that perform the following tests: -</p> - <ul> - <li> - Initial conditions test. Tests that the application under test initializes correctly. This is also a unit test of the application's - {@link android.app.Activity#onCreate(android.os.Bundle) onCreate()} method. Testing initial conditions also provides a confidence measure for subsequent tests. - </li> - <li> - UI test. Tests that the main UI operation works correctly. This test demonstrates the instrumentation features available in activity testing. - It shows that you can automate UI tests by sending key events from the test application to the main application. - </li> - <li> - State management tests. Test the application's code for saving state. This test demonstrates the instrumentation features of the test runner, which - are available for testing any component. - </li> - </ul> -<h2 id="Prerequisites">Prerequisites</h2> -<p> - The instructions and code in this tutorial depend on the following: -</p> - <ul> - <li> - Basic knowledge of Android programming. If you haven't yet written an Android application, - do the class - <a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a>. - If you want to learn more about Spinner, the application under test, then you - might want to review the "Spinner" sample app. - </li> - <li> - Some familiarity with the Android testing framework and concepts. If you haven't explored - Android testing yet, start by reading the - <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a> - guide. - </li> - <li> - Eclipse with ADT. This tutorial describes how to set up and run a test application using - Eclipse with ADT. If you haven't yet installed Eclipse and the ADT plugin, - follow the steps in <a href="{@docRoot}sdk/installing/index.html">Installing the SDK</a> - to install them before continuing. If you are not developing in Eclipse, you will - find instructions for setting up and running the test application in the - <a href="#EditorCommandLine">appendix</a> of this document. - </li> - </ul> -<h2 id="DownloadCode">Installing the Tutorial Sample Code</h2> -<p> - During this tutorial, you will be working with sample code that is provided as part - of the downloadable Samples component of the SDK. Specifically, you will be working - with a pair of related sample applications — an application under test and a test - application: -</p> - <ul> - <li> - Spinner is the application under test. This tutorial focuses on the - common situation of writing tests for an application that already exists, so the main - application is provided to you. - </li> - <li> - SpinnerTest is the test application. In the tutorial, you create this application - step-by-step. If you want to run quickly through the tutorial, - you can install the completed SpinnerTest application first, and then follow the - text. You may get more from the tutorial, however, if you create the test application - as you go. The instructions for installing the completed test application are in the - section - <a href="#InstallCompletedTestApp">Installing the Completed Test Application File</a>. - </li> - </ul> -<p> - The sample applications are described in more detail in the - <a href="{@docRoot}tools/samples/index.html">Samples</a> topic. Follow the instructions to - download the version of the samples that's appropriate for the platform you're working with. -</p> -<h2 id="SetupEmulator">Setting Up the Emulator</h2> -<p> - In this tutorial, you will use the Android emulator to run applications. The emulator needs - an Android Virtual Device (AVD) with an API level equal to or higher than the one you set for the projects in the previous step. - To find out how to check this and create the right AVD if necessary, - see <a href="{@docRoot}tools/devices/managing-avds.html">Creating an AVD</a>. -</p> -<p> - As a test of the AVD and emulator, run the SpinnerActivity application in Eclipse with ADT. When it starts, - click the large downward-pointing arrow to the right of the spinner text. You see the spinner expand and display the title "Select a planet" at the top. - Click one of the other planets. The spinner closes, and your selection appears below it on the screen. -</p> -<h2 id="SetupProjects">Setting Up the Projects</h2> -<p> - When you are ready to get started with the tutorial, begin by setting up Eclipse projects for - both Spinner (the application under test) and SpinnerTest (the test application). -</p> -<p> - You'll be using the Spinner application as-is, without modification, so you'll be loading it - into Eclipse as a new Android project from existing source. In the process, you'll be - creating a new test project associated with Spinner that will contain the SpinnerTest - application. The SpinnerTest application will be completely new and you'll be - using the code examples in this tutorial to add test classes and tests to it. -</p> -<p> - To install the Spinner app in a new Android project from existing source, following these steps: -</p> -<ol> - <li> - In Eclipse, select <strong>File</strong> > <strong>New</strong> > <strong>Project</strong> > <strong>Android</strong> > <strong>Android Project</strong>, - then click Next. The <strong>New Android Project</strong> dialog appears. - </li> - <li> - In the <em>Project name</em> text box, enter "SpinnerActivity". The <em>Properties</em> area is filled in automatically. - </li> - <li> - In the <em>Contents</em> area, set "Create project from existing source". - </li> - <li> - For <em>Location</em>, click <strong>Browse</strong>, navigate to the directory <code><SDK_path>/samples/android-8/Spinner</code>, - then click Open. The directory name <code><SDK_path>/samples/android-8/Spinner</code> now appears in the <em>Location</em> text box. - </li> - <li> - In the <em>Build Target</em> area, set a API level of 3 or higher. If you are already developing with a particular target, and it is API level 3 or higher, then use that target. - </li> - <li> - In the <em>Properties</em> area, in the <em>Min SDK Version:</em>, enter "3". - </li> - <li> - You should now see these values: - <ul> - <li><em>Project Name:</em> "SpinnerActivity"</li> - <li><em>Create project from existing source:</em> set</li> - <li><em>Location:</em> "<code><SDK_path>/samples/android-8/Spinner</code>"</li> - <li><em>Build Target:</em> "API level of 3 or higher" (<em>Target Name</em> "Android 1.5 or higher")</li> - <li><em>Package name:</em> (disabled, set to "<code>com.android.example.spinner</code>")</li> - <li><em>Create Activity:</em> (disabled, set to ".SpinnerActivity")</li> - <li><em>Min SDK Version:</em> "3"</li> - </ul> - <p> - The following screenshot summarizes these values: - </p> - <a href="{@docRoot}images/testing/eclipse_new_android_project_complete_callouts.png"> - <img src="{@docRoot}images/testing/eclipse_new_android_project_complete_callouts.png" alt="New Android Project dialog with filled-in values" style="height:230px"/> - </a> - - </li> -</ol> -<p> - To create a new test project for the SpinnerTest application, follow these steps: -</p> -<ol> - <li> - Click Next. The <strong>New Android Test Project</strong> dialog appears. - </li> - <li> - Set "Create a Test Project". - </li> - <li> - Leave the other values unchanged. The result should be: - <ul> - <li><em>Create a Test Project:</em> checked</li> - <li><em>Test Project Name:</em> "SpinnerActivityTest"</li> - <li><em>Use default location:</em> checked (this should contain the directory name "<code>workspace/SpinnerActivityTest</code>").</li> - <li><em>Build Target:</em> Use the same API level you used in the previous step.</li> - <li><em>Application name:</em> "SpinnerActivityTest"</li> - <li><em>Package name:</em> "<code>com.android.example.spinner.test</code>"</li> - <li><em>Min SDK Version:</em> "3"</li> - </ul> - <p> - The following screenshot summarizes these values: - </p> - <a href="{@docRoot}images/testing/eclipse_new_android_testproject_complete_callouts.png"> - <img src="{@docRoot}images/testing/eclipse_new_android_testproject_complete_callouts.png" alt="New Android Test Project dialog with filled-in values" style="height:230px"/> - </a> - </li> - <li> - Click Finish. Entries for SpinnerActivity and SpinnerActivityTest should appear in the - <strong>Package Explorer</strong>. - <p class="note"> - <strong>Note:</strong> If you set <em>Build Target</em> to an API level higher than "3", you will see the warning - "The API level for the selected SDK target does not match the Min SDK version". You do not need to change the API level or the Min SDK version. - The message tells you that you are building the projects with one particular API level, but specifying that a lower API level is required. This may - occur if you have chosen not to install the optional earlier API levels. - </p> - <p> - If you see errors listed in the <strong>Problems</strong> pane at the bottom of the Eclipse window, or if a red error marker appears next to - the entry for SpinnerActivity in the Package Explorer, highlight the SpinnerActivity entry and then select - <strong>Project</strong> > <strong>Clean</strong>. This should fix any errors. - </p> - </li> -</ol> -<p> - You now have the application under test in the SpinnerActivity project, - and an empty test project in SpinnerActivityTest. You may - notice that the two projects are in different directories, but Eclipse with - ADT handles this automatically. You should have no problem in either building or running them. -</p> -<p> - Notice that Eclipse and ADT have already done some initial setup for your test application. - Expand the SpinnerActivityTest project, and notice that it already has an - Android manifest file <code>AndroidManifest.xml</code>. - Eclipse with ADT created this when you added the test project. - Also, the test application is already set up to use instrumentation. You can see this - by examining <code>AndroidManifest.xml</code>. - Open it, then at the bottom of the center pane click <strong>AndroidManifest.xml</strong> - to display the XML contents: -</p> -<pre> -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.example.spinner.test" - android:versionCode="1" - android:versionName="1.0"> - <uses-sdk android:minSdkVersion="3" /> - <instrumentation - android:targetPackage="com.android.example.spinner" - android:name="android.test.InstrumentationTestRunner" /> - <application android:icon="@drawable/icon" android:label="@string/app_name"> - <uses-library android:name="android.test.runner" /> - ... - </application> -</manifest> -</pre> -<p> - Notice the <code><instrumentation></code> element. The attribute - <code>android:targetPackage="com.android.example.spinner"</code> tells Android that the - application under test is defined in the Android package - <code>com.android.example.spinner</code>. Android now knows to use that - package's <code>AndroidManifest.xml</code> file to launch the application under test. - The <code><instrumentation></code> element also contains the attribute - <code>android:name="android.test.InstrumentationTestRunner"</code>, which tells Android - instrumentation to run the test application with Android's instrumentation-enabled test runner. -</p> -<h2 id="CreateTestCaseClass">Creating the Test Case Class</h2> - -<p> - You now have a test project SpinnerActivityTest, and the basic structure of a test - application also called SpinnerActivityTest. The basic structure includes all the files and - directories you need to build and run a test application, except for the class that - contains your tests (the test case class). -</p> -<p> - The next step is to define the test case class. In this tutorial, you'll be creating a - test case class that includes: -</p> -<ul> - <li> - Test setup. This use of the JUnit {@link junit.framework.TestCase#setUp() setUp()} - method demonstrates some of the tasks you might perform before running an Android test. - </li> - <li> - Testing initial conditions. This test demonstrates a good testing technique. - It also demonstrates that with Android instrumentation you can look at the application - under test <em>before</em> the main activity starts. The test checks that the application's - important objects have been initialized. - If the test fails, you then know that any other tests against the application are - unreliable, since the application was running in an incorrect state. - <p class="note"> - <strong>Note:</strong> The purpose of testing initial conditions is not the same as - using <code>setUp()</code>. The JUnit {@link junit.framework.TestCase#setUp()} runs once - before <strong>each test method</strong>, and its purpose is to create a clean test - environment. The initial conditions test runs once, and its purpose is to verify that the - application under test is ready to be tested. - </p> - </li> - <li> - Testing the UI. This test shows how to control the main application's UI - with instrumentation, a powerful automation feature of Android testing. - </li> - <li> - Testing state management. This test shows some techniques for testing how - well the application maintains state in the Android environment. Remember that to - provide a satisfactory user experience, your application must never lose its current state, - even if it's interrupted by a phone call or destroyed because of memory constraints. - The Android activity lifecycle provides ways to maintain state, and the - <code>SpinnerActivity</code> application uses them. The test shows the techniques for - verifying that they work. - </li> -</ul> -<p> - Android tests are contained in a special type of Android application that contains one or more test class definitions. Each of these contains - one or more test methods that do the actual tests. In this tutorial, you will first add a test case class, and then add tests to it. -</p> -<p> - You first choose an Android test case class to extend. You choose from the base test case classes according to the Android component you are testing and the types of tests you are doing. - In this tutorial, the application under test has a single simple activity, so the test case class will be for an Activity component. Android offers several, but the one that tests in - the most realistic environment is {@link android.test.ActivityInstrumentationTestCase2}, so you will use it as the base class. Like all activity test case classes, - <code>ActivityInstrumentationTestCase2</code> offers convenience methods for interacting directly with the UI of the application under test. -</p> -<h3 id="AddTestCaseClass">Adding the test case class file</h3> -<p> - To add <code>ActivityInstrumentationTestCase2</code> as the base test case class, follow these steps: -</p> -<ol> - <li> - In the Package Explorer, expand the test project SpinnerActivityTest if it is not open already. - </li> - <li> - Within SpinnerActivityTest, expand the <code>src/</code> folder and then the package marker for - <code>com.android.example.spinner.test</code>. Right-click on the package name and select <strong>New</strong> > <strong>Class</strong>:<br/> - <a href="{@docRoot}images/testing/spinner_create_test_class_callouts.png"> - <img alt="Menu for creating a new class in the test application" src="{@docRoot}images/testing/spinner_create_test_class_callouts.png" style="height:230px"/> - </a> - <p> - The <strong>New Java Class</strong> wizard appears: - </p> - <a href="{@docRoot}images/testing/spinnertest_new_class_callouts.png"> - <img alt="New Java Class wizard dialog" src="{@docRoot}images/testing/spinnertest_new_class_callouts.png" style="height:230px"/> - </a> - </li> - <li> - In the wizard, enter the following: - <ul> - <li> - <em>Name:</em> "SpinnerActivityTest". This becomes the name of your test class. - </li> - <li> - <em>Superclass:</em> "<code>android.test.ActivityInstrumentationTestCase2<SpinnerActivity></code>". The superclass is parameterized, so - you have to provide it your main application's class name. - </li> - </ul> - <p> - Do not change any of the other settings. Click Finish. - </p> - </li> - <li> - You now have a new file <code>SpinnerActivityTest.java</code> in the project. - </li> - <li> - To resolve the reference to SpinnerActivity, add the following import: -<pre> -import com.android.example.spinner.SpinnerActivity; -</pre> - </li> -</ol> -<h3 id="AddConstructor">Adding the test case constructor</h3> - <p> - To ensure that the test application is instantiated correctly, you must set up a constructor that the test - runner will call when it instantiates your test class. This constructor has no parameters, and its sole - purpose is to pass information to the superclass's default constructor. To set up this constructor, enter the - following code in the class: - </p> -<pre> - public SpinnerActivityTest() { - super(SpinnerActivity.class); - } // end of SpinnerActivityTest constructor definition -</pre> -<p> - This calls the superclass constructor with the main activity's class (<code>SpinnerActivity.class</code>) for the application under test. Android uses this information to find the application and activity to test. -</p> -<p> - You are now ready to add tests, by adding test methods to the class. -</p> -<h3 id="AddSetupMethod">Adding the setup method</h3> -<p> - The <code>setUp()</code> method is invoked before every test. You use it to initialize variables and clean up from previous tests. You can also use - the JUnit {@link junit.framework.TestCase#tearDown() tearDown()} method, which runs <strong>after</strong> every test method. The tutorial does not use it. -</p> -<p> - The method you are going to add does the following: -</p> -<ul> - <li> - <code>super.setUp()</code>. Invokes the superclass constructor for <code>setUp()</code>, which is required by JUnit. - </li> - <li> - Calls {@link android.test.ActivityInstrumentationTestCase2#setActivityInitialTouchMode(boolean) setActivityInitialTouchMode(false)}. - This turns off <strong>touch mode</strong> in the device or emulator. If any of your test methods send key events to the application, - you must turn off touch mode <em>before</em> you start any activities; otherwise, the call is ignored. - </li> - <li> - Stores references to system objects. Retrieves and stores a reference to the activity under test, the <code>Spinner</code> - widget used by the activity, the <code>SpinnerAdapter</code> that backs the widget, and the string value of the selection that is - set when the application is first installed. These objects are used in the state management test. The methods invoked are: - <ul> - <li> - {@link android.test.ActivityInstrumentationTestCase2#getActivity()}. Gets a reference to the activity under test (<code>SpinnerActivity</code>). - This call also starts the activity if it is not already running. - </li> - <li> - {@link android.app.Activity#findViewById(int)}. Gets a reference to the <code>Spinner</code> widget of the application under test. - </li> - <li> - {@link android.widget.AbsSpinner#getAdapter()}. Gets a reference to the adapter (an array of strings) backing the spinner. - </li> - </ul> - </li> -</ul> -<p> - Add this code to the definition of <code>SpinnerActivityTest</code>, after the constructor definition: -</p> -<pre> - @Override - protected void setUp() throws Exception { - super.setUp(); - - setActivityInitialTouchMode(false); - - mActivity = getActivity(); - - mSpinner = - (Spinner) mActivity.findViewById( - com.android.example.spinner.R.id.Spinner01 - ); - - mPlanetData = mSpinner.getAdapter(); - - } // end of setUp() method definition -</pre> -<p> - Add these members to the test case class: -</p> -<pre> - private SpinnerActivity mActivity; - private Spinner mSpinner; - private SpinnerAdapter mPlanetData; -</pre> -<p> - Add these imports: -</p> -<pre> -import android.widget.Spinner; -import android.widget.SpinnerAdapter; -</pre> -<p> - You now have the complete <code>setUp()</code> method. -</p> -<h3 id="AddPreConditionsTest">Adding an initial conditions test</h3> -<p> - The initial conditions test verifies that the application under test is initialized correctly. It is an illustration of the types of tests you can run, so it is not comprehensive. - It verifies the following: -</p> -<ul> - <li> - The item select listener is initialized. This listener is called when a selection is made from the spinner. - </li> - <li> - The adapter that provides values to the spinner is initialized. - </li> - <li> - The adapter contains the right number of entries. - </li> -</ul> -<p> - The actual initialization of the application under test is done in <code>setUp()</code>, which the test runner calls automatically before every test. The verifications are - done with JUnit {@link junit.framework.Assert} calls. As a useful convention, the method name is <code>testPreConditions()</code>: -</p> -<pre> - public void testPreConditions() { - assertTrue(mSpinner.getOnItemSelectedListener() != null); - assertTrue(mPlanetData != null); - assertEquals(mPlanetData.getCount(),ADAPTER_COUNT); - } // end of testPreConditions() method definition -</pre> -<p> - Add this member: -</p> -<pre> - public static final int ADAPTER_COUNT = 9; -</pre> -<h3 id="AddUITest">Adding a UI test</h3> -<p> - Now create a UI test that selects an item from the <code>Spinner</code> widget. The test sends key events to the UI with key events. - The test confirms that the selection matches the result you expect. -</p> -<p> - This test demonstrates the power of using instrumentation in Android testing. Only an instrumentation-based test class allows you to send key events (or touch events) - to the application under test. With instrumentation, you can test your UI without having to take screenshots, record the screen, or do human-controlled testing. -</p> -<p> - To work with the spinner, the test has to request focus for it and then set it to a known position. The test uses {@link android.view.View#requestFocus() requestFocus()} and - {@link android.widget.AbsSpinner#setSelection(int) setSelection()} to do this. Both of these methods interact with a View in the application under test, so you have to call them - in a special way. -</p> -<p> - Code in a test application that interacts with a View of the application under test must run in the main application's thread, also - known as the <em>UI thread</em>. To do this, you use the {@link android.app.Activity#runOnUiThread(java.lang.Runnable) Activity.runOnUiThread()} - method. You pass the code to <code>runOnUiThread()</code>in an anonymous {@link java.lang.Runnable Runnable} object. To set - the statements in the <code>Runnable</code> object, you override the object's {@link java.lang.Runnable#run()} method. -</p> -<p> - To send key events to the UI of the application under test, you use the <a href="{@docRoot}reference/android/test/InstrumentationTestCase.html#sendKeys(int...)">sendKeys</a>() method. - This method does not have to run on the UI thread, since Android uses instrumentation to pass the key events to the application under test. -</p> -<p> - The last part of the test compares the selection made by sending the key events to a pre-determined value. This tests that the spinner is working as intended. -</p> -<p> - The following sections show you how to add the code for this test. -</p> -<ol> - <li> - Get focus and set selection. Create a new method <code>public void testSpinnerUI()</code>. Add - code to to request focus for the spinner and set its position to default or initial position, "Earth". This code is run on the UI thread of - the application under test: -<pre> - public void testSpinnerUI() { - - mActivity.runOnUiThread( - new Runnable() { - public void run() { - mSpinner.requestFocus(); - mSpinner.setSelection(INITIAL_POSITION); - } // end of run() method definition - } // end of anonymous Runnable object instantiation - ); // end of invocation of runOnUiThread -</pre> - <p> - Add the following member to the test case class. - </p> -<pre> - public static final int INITIAL_POSITION = 0; -</pre> - </li> - <li> - Make a selection. Send key events to the spinner to select one of the items. To do this, open the spinner by - "clicking" the center keypad button (sending a DPAD_CENTER key event) and then clicking (sending) the down arrow keypad button five times. Finally, - click the center keypad button again to highlight the desired item. Add the following code: -<pre> - this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER); - for (int i = 1; i <= TEST_POSITION; i++) { - this.sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); - } // end of for loop - - this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER); -</pre> - <p> - Add the following member to the test case class: - </p> -<pre> - public static final int TEST_POSITION = 5; -</pre> - <p> - This sets the final position of the spinner to "Saturn" (the spinner's backing adapter is 0-based). - </p> - </li> - <li> - Check the result. Query the current state of the spinner, and compare its current selection to the expected value. - Call the method {@link android.widget.AdapterView#getSelectedItemPosition() getSelectedItemPosition()} to find out the current selection position, and then - {@link android.widget.AdapterView#getItemAtPosition(int) getItemAtPosition()} to get the object corresponding to that position (casting it to a String). Assert that - this string value matches the expected value of "Saturn": -<pre> - mPos = mSpinner.getSelectedItemPosition(); - mSelection = (String)mSpinner.getItemAtPosition(mPos); - TextView resultView = - (TextView) mActivity.findViewById( - com.android.example.spinner.R.id.SpinnerResult - ); - - String resultText = (String) resultView.getText(); - - assertEquals(resultText,mSelection); - - } // end of testSpinnerUI() method definition -</pre> -<p> - Add the following members to the test case class: -</p> -<pre> - private String mSelection; - private int mPos; -</pre> - <p> - Add the following imports to the test case class: - </p> -<pre> - import android.view.KeyEvent; - import android.widget.TextView; -</pre> - </li> -</ol> -<p> - Pause here to run the tests you have. The procedure for running a test application is different - from running a regular Android application. You run a test application as an Android JUnit - application. To see how to do this, see <a href="#RunTests">Running the Tests and Seeing the Results</a>. -</p> -<p> - Eventually, you will see the <code>SpinnerActivity</code> application start, and the test - application controlling it by sending it key events. You will also see a new - <strong>JUnit</strong> view in the Explorer pane, showing the results of the - test. The JUnit view is documented in a following section, - <a href="#RunTests">Running the Test and Seeing the Results</a>. -</p> -<h3 id="StateManagementTests">Adding state management tests</h3> -<p> - You now write two tests that verify that SpinnerActivity maintains its state when it is paused or terminated. - The state, in this case, is the current selection in the spinner. When users make a selection, - pause or terminate the application, and then resume or restart it, they should see - the same selection. -</p> -<p> - Maintaining state is an important feature of an application. Users may switch from the current - application temporarily to answer the phone, and then switch back. Android may decide to - terminate and restart an activity to change the screen orientation, or terminate an unused - activity to regain storage. In each case, users are best served by having the UI return to its - previous state (except where the logic of the application dictates otherwise). -</p> -<p> - SpinnerActivity manages its state in these ways: -</p> - <ul> - <li> - Activity is hidden. When the spinner screen (the activity) is running but hidden by some other screen, it - stores the spinner's position and value in a form that persists while the application is running. - </li> - <li> - Application is terminated. When the activity is terminated, it stores the spinner's position and value in - a permanent form. The activity can read the position and value when it restarts, and restore the spinner to its previous state. - </li> - <li> - Activity re-appears. When the user returns to the spinner screen, the previous selection is restored. - </li> - <li> - Application is restarted. When the user starts the application again, the previous selection is restored. - </li> - </ul> -<p class="note"> - <strong>Note:</strong> An application can manage its state in other ways as well, but these are - not covered in this tutorial. -</p> -<p> - When an activity is hidden, it is <strong>paused</strong>. When it re-appears, it - <strong>resumes</strong>. Recognizing that these are key points in an activity's life cycle, - the Activity class provides two callback methods {@link android.app.Activity#onPause()} and - {@link android.app.Activity#onResume()} for handling pauses and resumes. - SpinnerActivity uses them for code that saves and restores state. -</p> -<p> - <strong>Note:</strong> If you would like to learn more about the difference between losing - focus/pausing and killing an application, - read about the <a href="{@docRoot}guide/components/activities.html#Lifecycle">activity -lifecycle</a>. -</p> -<p> - The first test verifies that the spinner selection is maintained after the entire application is shut down and then restarted. The test uses instrumentation to - set the spinner's variables outside of the UI. It then terminates the activity by calling {@link android.app.Activity#finish() Activity.finish()}, and restarts it - using the instrumentation method {@link android.test.ActivityInstrumentationTestCase2#getActivity()}. The test then asserts that the current spinner state matches - the test values. -</p> -<p> - The second test verifies that the spinner selection is maintained after the activity is paused and then resumed. The test uses instrumentation to - set the spinner's variables outside of the UI and then force calls to the <code>onPause()</code> and <code>onResume()</code> methods. The test then - asserts that the current spinner state matches the test values. -</p> -<p> - Notice that these tests make limited assumptions about the mechanism by which the activity manages state. The tests use the activity's getters and - setters to control the spinner. The first test also knows that hiding an activity calls <code>onPause()</code>, and bringing it back to the foreground - calls <code>onResume()</code>. Other than this, the tests treat the activity as a "black box". -</p> -<p> - To add the code for testing state management across shutdown and restart, follow these steps: -</p> - <ol> - <li> - Add the test method <code>testStateDestroy()</code>, then - set the spinner selection to a test value: -<pre> - public void testStateDestroy() { - mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION); - mActivity.setSpinnerSelection(TEST_STATE_DESTROY_SELECTION); -</pre> - </li> - <li> - Terminate the activity and restart it: -<pre> - mActivity.finish(); - mActivity = this.getActivity(); -</pre> - </li> - <li> - Get the current spinner settings from the activity: -<pre> - int currentPosition = mActivity.getSpinnerPosition(); - String currentSelection = mActivity.getSpinnerSelection(); -</pre> - </li> - <li> - Test the current settings against the test values: -<pre> - assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition); - assertEquals(TEST_STATE_DESTROY_SELECTION, currentSelection); - } // end of testStateDestroy() method definition -</pre> -<p> - Add the following members to the test case class: -<pre> - public static final int TEST_STATE_DESTROY_POSITION = 2; - public static final String TEST_STATE_DESTROY_SELECTION = "Earth"; -</pre> - </li> - </ol> -<p> - To add the code for testing state management across a pause and resume, follow these steps: -</p> -<ol> - <li> - Add the test method <code>testStatePause()</code>: -<pre> - @UiThreadTest - public void testStatePause() { -</pre> - <p> - The <code>@UiThreadTest</code> annotation tells Android to build this method so that it runs - on the UI thread. This allows the method to change the state of the spinner widget in the - application under test. This use of <code>@UiThreadTest</code> shows that, if necessary, you - can run an entire method on the UI thread. - </p> - </li> - <li> - Set up instrumentation. Get the instrumentation object - that is controlling the application under test. This is used later to - invoke the <code>onPause()</code> and <code>onResume()</code> methods: -<pre> - Instrumentation mInstr = this.getInstrumentation(); -</pre> - </li> - <li> - Set the spinner selection to a test value: -<pre> - mActivity.setSpinnerPosition(TEST_STATE_PAUSE_POSITION); - mActivity.setSpinnerSelection(TEST_STATE_PAUSE_SELECTION); -</pre> - </li> - <li> - Use instrumentation to call the Activity's <code>onPause()</code>: -<pre> - mInstr.callActivityOnPause(mActivity); -</pre> - <p> - Under test, the activity is waiting for input. The invocation of - {@link android.app.Instrumentation#callActivityOnPause(android.app.Activity)} - performs a call directly to the activity's <code>onPause()</code> instead - of manipulating the activity's UI to force it into a paused state. - </p> - </li> - <li> - Force the spinner to a different selection: -<pre> - mActivity.setSpinnerPosition(0); - mActivity.setSpinnerSelection(""); -</pre> - <p> - This ensures that resuming the activity actually restores the - spinner's state rather than simply leaving it as it was. - </p> - </li> - <li> - Use instrumentation to call the Activity's <code>onResume()</code>: -<pre> - mInstr.callActivityOnResume(mActivity); -</pre> - <p> - Invoking {@link android.app.Instrumentation#callActivityOnResume(android.app.Activity)} - affects the activity in a way similar to <code>callActivityOnPause</code>. The - activity's <code>onResume()</code> method is invoked instead of manipulating the - activity's UI to force it to resume. - </p> - </li> - <li> - Get the current state of the spinner: -<pre> - int currentPosition = mActivity.getSpinnerPosition(); - String currentSelection = mActivity.getSpinnerSelection(); -</pre> - </li> - <li> - Test the current spinner state against the test values: -<pre> - assertEquals(TEST_STATE_PAUSE_POSITION,currentPosition); - assertEquals(TEST_STATE_PAUSE_SELECTION,currentSelection); - } // end of testStatePause() method definition -</pre> - <p> - Add the following members to the test case class: - </p> -<pre> - public static final int TEST_STATE_PAUSE_POSITION = 4; - public static final String TEST_STATE_PAUSE_SELECTION = "Jupiter"; -</pre> - </li> - <li> - Add the following imports: -<pre> - import android.app.Instrumentation; - import android.test.UiThreadTest; -</pre> - </li> -</ol> -<h2 id="RunTests">Running the Tests and Seeing the Results</h2> - <p> - The most simple way to run the <code>SpinnerActivityTest</code> test case is to run it directly from the Package Explorer. - </p> - <p> - To run the <code>SpinnerActivityTest</code> test, follow these steps: -</p> - <ol> - <li> - In the Package Explorer, right-click the project SpinnerActivityTest at the top level, and then - select <strong>Run As</strong> > <strong>Android JUnit Test</strong>:<br/> - <a href="{@docRoot}images/testing/spinnertest_runas_menu_callouts.png"> - <img alt="Menu to run a test as an Android JUnit test" src="{@docRoot}images/testing/spinnertest_runas_menu_callouts.png" style="height:230px"> - </a> - </li> - <li> - You will see the emulator start. When the unlock option is displayed (its appearance depends on the API level you specified for the AVD), - unlock the home screen. - </li> - <li> - The test application starts. You see a new tab for the <strong>JUnit</strong> view, next to the Package Explorer tab:<br/> - <a href="{@docRoot}images/testing/spinnertest_junit_panel.png"> - <img alt="The JUnit window" src="{@docRoot}images/testing/spinnertest_junit_panel.png" style="height:230px"> - </a> - </li> -</ol> -<p> - This view contains two sub-panes. The top pane summarizes the tests that were run, and the bottom pane shows failure traces for - highlighted tests. -</p> -<p> - At the conclusion of a successful test run, this is the view's appearance:<br/> - <a href="{@docRoot}images/testing/spinnertest_junit_success.png"> - <img src="{@docRoot}images/testing/spinnertest_junit_success.png" alt="JUnit test run success" style="height:230px"/> - </a> -</p> -<p> - The upper pane summarizes the test: -</p> - <ul> - <li> - Total time elapsed for the test application(labeled <em>Finished after <x> seconds</em>). - </li> - <li> - Number of runs (<em>Runs:</em>) - the number of tests in the entire test class. - </li> - <li> - Number of errors (<em>Errors:</em>) - the number of program errors and exceptions encountered during - the test run. - </li> - <li> - Number of failures (<em>Failures:</em>) - the number of test failures encountered during the test - run. This is the number of assertion failures. A test can fail even if the program does not encounter an error. - </li> - <li> - A progress bar. The progress bar extends from left to right as the tests run. - <p> - If all the tests succeed, the bar remains green. If a test fails, the bar turns from green to red. - </p> - </li> - <li> - A test method summary. Below the bar, you see a line for each class in the test application. To look at the results for the individual - methods in a test, click the arrow at the left to expand the line. You see the name of each test method. To the - right of the name, you see the time taken by the test. You can look at the test's code - by double-clicking its name. - </li> - </ul> -<p> - The lower pane contains the failure trace. If all the tests are successful, this pane is empty. If some tests fail, - then if you highlight a failed test in the upper pane, the lower view contains a stack trace for the test. This is - demonstrated in the next section. -</p> -<p class="note"> - <strong>Note:</strong> If you run the test application and nothing seems to happen, look for - the JUnit view. If you do not see it, you may have run the test application - as a regular Android application. - Remember that you need to run it as an Android <strong>JUnit</strong> - application. -</p> -<h2 id="TestFailure">Forcing Some Tests to Fail</h2> -<p> - A test is as useful when it fails as when it succeeds. This section shows what happens in Eclipse with ADT when a test fails. You - can quickly see that a test class has failed, find the method or methods that failed, and then use a failure trace to find - the exact problem. -</p> -<p> - The example application SpinnerActivity that you downloaded passes all the tests in the test application SpinnerActivityTest. - To force the test to fail, you must modify the example application. You change a line of setup code in the application under test. This - causes the <code>testPreConditions()</code> and <code>testTextView()</code> test methods to fail. -</p> -<p> - To force the tests to fail, follow these steps: -</p> -<ol> - <li> - In Eclipse with ADT, go to the SpinnerActivity project and open the file <code>SpinnerActivity.java</code>. - </li> - <li> - At the top of <code>SpinnerActivity.java</code>, at the end of the <code>onCreate()</code> method, find the following line: -<pre> - // mySpinner.setOnItemSelectedListener(null); -</pre> - <p>Remove the forward slash characters at the beginning of the line to - uncomment the line. This sets the listener callback to null: - </p> -<pre> - mySpinner.setOnItemSelectedListener(null); -</pre> - </li> - <li> - The <code>testPreConditions()</code> method in <code>SpinnerActivityTest</code> contains the following test: - <code>assertTrue(mSpinner.getOnItemSelectedListener() != null);</code>. This test asserts that the listener callback is <em>not</em> null. - Since you have modified the application under test, this assertion now fails. - </li> - <li> - Run the test, as described in the previous section <a href="#RunTests">Running the Tests and Seeing the Results</a>. - </li> -</ol> -<p> - The JUnit view is either created or updated with the results of the test. Now, however, the progress bar is red, - the number of failures is 2, and small "x" icons appear in the list icons next to the testPreConditions and - TestSpinnerUI tests. This indicates that the tests have failed. The display is similar to this:<br/> - <a href="{@docRoot}images/testing/spinnertest_junit_panel_fail_callouts.png"> - <img src="{@docRoot}images/testing/spinnertest_junit_panel_fail_callouts.png" alt="The JUnit Failure window" style="height:230px"/> - </a> -</p> -<p> - You now want to look at the failures to see exactly where they occurred. -</p> -<p> - To examine the failures, follow these steps: -</p> -<ol> - <li> - Click the testPreconditions entry. In the lower pane entitled <strong>Failure Trace</strong>, - you see a stack trace of the calls that led to the failure. This trace is similar to the following screenshot:<br/> - <a href="{@docRoot}images/testing/spinnertest_junit_panel_failtrace_callouts.png"> - <img src="{@docRoot}images/testing/spinnertest_junit_panel_failtrace_callouts.png" alt="The JUnit failure trace" style="height:230px"/> - </a> - </li> - <li> - The first line of the trace tells you the error. In this case, a JUnit assertion failed. To look at the - assertion in the test code, double-click the next line (the first line of the trace). In the center pane - a new tabbed window opens, containing the code for the test application <code>SpinnerActivityTest</code>. The failed assertion - is highlighted in the middle of the window. - </li> -</ol> -<p> - The assertion failed because you modified the main application to set the <code>getOnItemSelectedListener</code> callback to <code>null</code>. -</p> -<p> - You can look at the failure in <code>testTextView</code> if you want. Remember, though, that <code>testPreConditions</code> is meant to verify the - initial setup of the application under test. If testPreConditions() fails, then succeeding tests can't be trusted. The best strategy to follow is to - fix the problem and re-run all the tests. -</p> -<p> - Remember to go back to <code>SpinnerActivity.java</code> and re-comment the line you uncommented in an earlier step. -</p> -<p> - You have now completed the tutorial. -</p> -<h2 id="NextSteps">Next Steps</h2> -<p> - This example test application has shown you how to create a test project and link it to - the application you want to test, how to choose and add a test case class, how to write - UI and state management tests, and how to run the tests against the application under - test. Now that you are familiar with the basics of testing Android applications, here - are some suggested next steps: -</p> -<p> - <strong>Learn more about testing on Android</strong> -</p> -<ul> - <li> - If you haven't done so already, read the - <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a> - document in the <em>Dev Guide</em>. It provides an overview of how testing on Android - works. If you are just getting started with Android testing, reading that document will - help you understand the tools available to you, so that you can develop effective - tests. - </li> -</ul> -<p> - <strong>Review the main Android test case classes</strong> -</p> -<ul> - <li> - {@link android.test.ActivityInstrumentationTestCase2} - </li> - <li> - {@link android.test.ActivityUnitTestCase} - </li> - <li> - {@link android.test.ProviderTestCase2} - </li> - <li> - {@link android.test.ServiceTestCase} - </li> -</ul> -<p> - <strong>Learn more about the assert and utility classes</strong> -</p> -<ul> - <li> - {@link junit.framework.Assert}, the JUnit Assert class. - </li> - <li> - {@link android.test.MoreAsserts}, additional Android assert methods. - </li> - <li> - {@link android.test.ViewAsserts}, useful assertion methods for testing Views. - </li> - <li> - {@link android.test.TouchUtils}, utility methods for simulating touch events in an Activity. - </li> -</ul> -<p> - <strong>Learn about instrumentation and the instrumented test runner</strong> -</p> -<ul> - <li> - {@link android.app.Instrumentation}, the base instrumentation class. - </li> - <li> - {@link android.test.InstrumentationTestCase}, the base instrumentation test case. - </li> - <li> - {@link android.test.InstrumentationTestRunner}, the standard Android test runner. - </li> -</ul> -<h2 id="Appendix">Appendix</h2> -<h3 id="InstallCompletedTestApp">Installing the Completed Test Application File</h3> -<p> - The recommended approach to this tutorial is to follow the instructions step-by-step and - write the test code as you go. However, if you want to do this tutorial quickly, - you can install the entire file for the test application into the test project. -</p> -<p> - To do this, you first create a test project with the necessary structure and files by using - the automated tools in Eclipse. Then you exit Eclipse and copy the test application's file - from the SpinnerTest sample project into your test project. The SpinnerTest sample project is - part of the Samples component of the SDK. -</p> -<p> - The result is a complete test application, ready to run against the Spinner sample application. -</p> -<p> - To install the test application file, follow these steps: -</p> -<ol> - <li> - Set up the projects for the application under test and the test application, as described - in the section section <a href="#SetupProjects">Setting Up the Projects</a>. - </li> - <li> - Set up the emulator, as described in the section <a href="#SetupEmulator">Setting Up the Emulator</a>. - </li> - <li> - Add the test case class, as described in the section <a href="#AddTestCaseClass">Adding the test case class file</a>. - </li> - <li> - Close Eclipse with ADT. - </li> - <li> - Copy the file <code><SDK_path>/samples/android-8/SpinnerTest/src/com/android/example/spinner/test/SpinnerActivityTest.java</code> - to the directory <code>workspace/SpinnerActivityTest/src/com/android/example/spinner/test/</code>. - </li> - <li> - Restart Eclipse with ADT. - </li> - <li> - In Eclipse with ADT, re-build the project <code>SpinnerActivityTest</code> by selecting it in the Package Explorer, right-clicking, - and selecting <em>Project</em> > <em>Clean</em>. - </li> - <li> - The complete, working test application should now be in the <code>SpinnerActivityTest</code> project. - </li> -</ol> -<p> - You can now continue with the tutorial, starting at the section <a href="#AddConstructor">Adding the test case constructor</a> and - following along in the text. -</p> -<h3 id="EditorCommandLine">For Users Not Developing In Eclipse</h3> -<p> - If you are not developing in Eclipse, you can still do this tutorial. Android provides tools for - creating test applications using a code editor and command-line tools. You use the following tools: -</p> -<ul> - <li> - <a href="{@docRoot}tools/help/adb.html">adb</a> - Installs and uninstalls applications and test applications to a device or the emulator. You - also use this tool to run the test application from the command line. - </li> - <li> - <a href="{@docRoot}tools/help/android.html">android</a> - Manages projects and test projects. This tool also manages AVDs and Android platforms. - </li> -</ul> - <p> - You use the <code>emulator</code> tool to run the emulator from the command line. - </p> - <p> - Here are the general steps for doing this tutorial using an editor and the command line: - </p> -<ol> - <li> - As described in the section <a href="#DownloadCode">Installing the Tutorial Sample Code</a>, get the sample code. You will then - have a directory <code><SDK_path>/samples/android-8</code>, containing (among others) the directories <code>Spinner</code> - and <code>SpinnerTest</code>: - <ul> - <li> - <code>Spinner</code> contains the main application, also known as the <strong>application under test</strong>. This tutorial focuses on the - common situation of writing tests for an application that already exists, so the main application is provided to you. - </li> - <li> - <code>SpinnerTest</code> contains all the code for the test application. If you want to run quickly through the tutorial, you can - install the test code and then follow the text. You may get more from the tutorial, however, if you write the code as you go. The instructions - for installing the test code are in the section <a href="#InstallCompletedTestApp">Appendix: Installing the Completed Test Application File</a>. - </li> - </ul> - </li> - <li> - Navigate to the directory <code><SDK_path>/samples/android-8</code>. - </li> - <li> - Create a new Android application project using <code>android create project</code>: -<pre> -$ android create project -t <APItarget> -k com.android.example.spinner -a SpinnerActivity -n SpinnerActivity -p Spinner -</pre> - <p> - The value of <code><APItarget></code> should be "3" (API level 3) or higher. If you are already developing with a particular API level, and it is - higher than 3, then use that API level. - </p> - <p> - This a new Android project <code>SpinnerActivity</code> in the existing <code>Spinner</code> directory. The existing source and - resource files are not touched, but the <code>android</code> tool adds the necessary build files. - </p> - </li> - <li> - Create a new Android test project using <code>android create test-project</code>: -<pre> -$ android create test-project -m ../Spinner -n SpinnerActivityTest -p SpinnerActivityTest -</pre> - <p> - This will create a new Android test project in the <em>new</em> directory <code>SpinnerActivityTest</code>. You do this - so that the solution to the tutorial that is in <code>SpinnerTest</code> is left untouched. If you want to use the solution - code instead of entering it as you read through the tutorial, refer to the section - <a href="#InstallCompletedTestApp">Appendix: Installing the Completed Test Application File</a>. - </p> - <p class="Note"> - <strong>Note:</strong> Running <code>android create test-project</code> will automatically create - the file <code>AndroidManifest.xml</code> with the correct <code><instrumentation></code> element. - </p> - </li> - <li> - Build the sample application. If you are building with Ant, then it is easiest to use the command <code>ant debug</code> to build a debug version, since the SDK comes - with a debug signing key. The result will be the file <code>Spinner/bin/SpinnerActivity-debug.apk</code>. - You can install this to your device or emulator. Attach your device or start the emulator if you haven't already, and run the command: -<pre> -$ adb install Spinner/bin/SpinnerActivity-debug.apk -</pre> - </li> - <li> - To create the test application, create a file <code>SpinnerActivityTest.java</code> in the directory - <code>SpinnerActivityTest/src/com/android/example/spinner/test/</code>. - </li> - <li> - Follow the tutorial, starting with the section <a href="#CreateTestCaseClass">Creating the Test Case Class</a>. When you are prompted to - run the sample application, go to the Launcher screen in your device or emulator and select SpinnerActivity. - When you are prompted to run the test application, return here to continue with the following instructions. - </li> - <li> - Build the test application. If you are building with Ant, then it is easiest to use the command <code>ant debug</code> to build a - debug version, since the SDK comes with a debug signing key. The result will be the Android file - <code>SpinnerActivityTest/bin/SpinnerActivityTest-debug.apk</code>. You can install this to your device or emulator. - Attach your device or start the emulator if you haven't already, and run the command: -<pre> -$ adb install SpinnerActivityTest/bin/SpinnerActivityTest-debug.apk -</pre> - </li> - <li> - In your device or emulator, check that both the main application <code>SpinnerActivity</code> and the test application - <code>SpinnerActivityTest</code> are installed. - </li> - <li> - To run the test application, enter the following at the command line: -<pre> -$ adb shell am instrument -w com.android.example.spinner.test/android.test.InstrumentationTestRunner - </pre> - </li> -</ol> -<p> - The result of a successful test looks like this: -</p> -<pre> -com.android.example.spinner.test.SpinnerActivityTest:.... -Test results for InstrumentationTestRunner=.... -Time: 10.098 -OK (4 tests) -</pre> -<p> - If you force the test to fail, as described in the previous section <a href="#TestFailure">Forcing Some Tests to Fail</a>, then - the output looks like this: -</p> -<pre> -com.android.example.spinner.test.SpinnerActivityTest: -Failure in testPreConditions: -junit.framework.AssertionFailedError - at com.android.example.spinner.test.SpinnerActivityTest.testPreConditions(SpinnerActivityTest.java:104) - at java.lang.reflect.Method.invokeNative(Native Method) - at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205) - at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195) - at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:175) - at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169) - at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154) - at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430) - at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447) -Failure in testSpinnerUI: -junit.framework.ComparisonFailure: expected:<Result> but was:<Saturn> - at com.android.example.spinner.test.SpinnerActivityTest.testSpinnerUI(SpinnerActivityTest.java:153) - at java.lang.reflect.Method.invokeNative(Native Method) - at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205) - at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195) - at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:175) - at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169) - at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154) - at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430) - at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447) -.. -Test results for InstrumentationTestRunner=.F.F.. -Time: 9.377 -FAILURES!!! -Tests run: 4, Failures: 2, Errors: 0 -</pre> diff --git a/docs/html/tools/testing/activity_testing.jd b/docs/html/tools/testing/activity_testing.jd deleted file mode 100755 index 6109c060a801..000000000000 --- a/docs/html/tools/testing/activity_testing.jd +++ /dev/null @@ -1,375 +0,0 @@ -page.title=Activity Testing -parent.title=Testing -parent.link=index.html -@jd:body - -<div id="qv-wrapper"> - <div id="qv"> - <h2>In this document</h2> - <ol> - <li> - <a href="#ActivityTestAPI">The Activity Testing API</a> - <ol> - <li> - <a href="#ActivityInstrumentationTestCase2">ActivityInstrumentationTestCase2</a> - </li> - <li> - <a href="#ActivityUnitTestCase">ActivityUnitTestCase</a> - </li> - <li> - <a href="#SingleLaunchActivityTestCase">SingleLaunchActivityTestCase</a> - </li> - <li> - <a href="#MockObjectNotes">Mock objects and activity testing</a> - </li> - <li> - <a href="#AssertionNotes">Assertions for activity testing</a> - </li> - </ol> - </li> - <li> - <a href="#WhatToTest">What to Test</a> - </li> - <li> - <a href="#NextSteps">Next Steps</a> - </li> - <li> - <a href="#UITesting">Appendix: UI Testing Notes</a> - <ol> - <li> - <a href="#RunOnUIThread">Testing on the UI thread</a> - </li> - <li> - <a href="#NotouchMode">Turning off touch mode</a> - </li> - <li> - <a href="#UnlockDevice">Unlocking the Emulator or Device</a> - </li> - <li> - <a href="#UITestTroubleshooting">Troubleshooting UI tests</a> - </li> - </ol> - </li> - </ol> -<h2>Key Classes</h2> - <ol> - <li>{@link android.test.InstrumentationTestRunner}</li> - <li>{@link android.test.ActivityInstrumentationTestCase2}</li> - <li>{@link android.test.ActivityUnitTestCase}</li> - </ol> -<h2>Related Tutorials</h2> - <ol> - <li> - <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a> - </li> - </ol> -<h2>See Also</h2> - <ol> - <li> - <a href="{@docRoot}training/testing/unit-testing/local-unit-tests.html"> - Building Local Unit Tests</a> - </li> - <li> - <a href="{@docRoot}tools/testing/testing_otheride.html"> - Testing from Other IDEs</a> - </li> - </ol> - </div> -</div> -<p> - Activity testing is particularly dependent on the Android instrumentation framework. - Unlike other components, activities have a complex lifecycle based on callback methods; these - can't be invoked directly except by instrumentation. Also, the only way to send events to the - user interface from a program is through instrumentation. -</p> -<p> - This document describes how to test activities using instrumentation and other test - facilities. The document assumes you have already read - <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>, - the introduction to the Android testing and instrumentation framework. -</p> -<h2 id="ActivityTestAPI">The Activity Testing API</h2> -<p> - The activity testing API base class is {@link android.test.InstrumentationTestCase}, - which provides instrumentation to the test case subclasses you use for Activities. -</p> -<p> - For activity testing, this base class provides these functions: -</p> -<ul> - <li> - Lifecycle control: With instrumentation, you can start the activity under test, pause it, - and destroy it, using methods provided by the test case classes. - </li> - <li> - Dependency injection: Instrumentation allows you to create mock system objects such as - Contexts or Applications and use them to run the activity under test. This - helps you control the test environment and isolate it from production systems. You can - also set up customized Intents and start an activity with them. - </li> - <li> - User interface interaction: You use instrumentation to send keystrokes or touch events - directly to the UI of the activity under test. - </li> -</ul> -<p> - The activity testing classes also provide the JUnit framework by extending - {@link junit.framework.TestCase} and {@link junit.framework.Assert}. -</p> -<p> - The two main testing subclasses are {@link android.test.ActivityInstrumentationTestCase2} and - {@link android.test.ActivityUnitTestCase}. To test an Activity that is launched in a mode - other than <code>standard</code>, you use {@link android.test.SingleLaunchActivityTestCase}. -</p> -<h3 id="ActivityInstrumentationTestCase2">ActivityInstrumentationTestCase2</h3> -<p> - The {@link android.test.ActivityInstrumentationTestCase2} test case class is designed to do - functional testing of one or more Activities in an application, using a normal system - infrastructure. It runs the Activities in a normal instance of the application under test, - using a standard system Context. It allows you to send mock Intents to the activity under - test, so you can use it to test an activity that responds to multiple types of intents, or - an activity that expects a certain type of data in the intent, or both. Notice, though, that it - does not allow mock Contexts or Applications, so you can not isolate the test from the rest of - a production system. -</p> -<h3 id="ActivityUnitTestCase">ActivityUnitTestCase</h3> -<p> - The {@link android.test.ActivityUnitTestCase} test case class tests a single activity in - isolation. Before you start the activity, you can inject a mock Context or Application, or both. - You use it to run activity tests in isolation, and to do unit testing of methods - that do not interact with Android. You can not send mock Intents to the activity under test, - although you can call - {@link android.app.Activity#startActivity(Intent) Activity.startActivity(Intent)} and then - look at arguments that were received. -</p> -<h3 id="SingleLaunchActivityTestCase">SingleLaunchActivityTestCase</h3> -<p> - The {@link android.test.SingleLaunchActivityTestCase} class is a convenience class for - testing a single activity in an environment that doesn't change from test to test. - It invokes {@link junit.framework.TestCase#setUp() setUp()} and - {@link junit.framework.TestCase#tearDown() tearDown()} only once, instead of once per - method call. It does not allow you to inject any mock objects. -</p> -<p> - This test case is useful for testing an activity that runs in a mode other than - <code>standard</code>. It ensures that the test fixture is not reset between tests. You - can then test that the activity handles multiple calls correctly. -</p> -<h3 id="MockObjectNotes">Mock objects and activity testing</h3> -<p> - This section contains notes about the use of the mock objects defined in - {@link android.test.mock} with activity tests. -</p> -<p> - The mock object {@link android.test.mock.MockApplication} is only available for activity - testing if you use the {@link android.test.ActivityUnitTestCase} test case class. - By default, <code>ActivityUnitTestCase</code>, creates a hidden <code>MockApplication</code> - object that is used as the application under test. You can inject your own object using - {@link android.test.ActivityUnitTestCase#setApplication(Application) setApplication()}. -</p> -<h3 id="AssertionNotes">Assertions for activity testing</h3> -<p> - {@link android.test.ViewAsserts} defines assertions for Views. You use it to verify the - alignment and position of View objects, and to look at the state of ViewGroup objects. -</p> -<h2 id="WhatToTest">What To Test</h2> -<ul> - <li> - Input validation: Test that an activity responds correctly to input values in an - EditText View. Set up a keystroke sequence, send it to the activity, and then - use {@link android.view.View#findViewById(int)} to examine the state of the View. You can - verify that a valid keystroke sequence enables an OK button, while an invalid one leaves the - button disabled. You can also verify that the Activity responds to invalid input by - setting error messages in the View. - </li> - <li> - Lifecycle events: Test that each of your application's activities handles lifecycle events - correctly. In general, lifecycle events are actions, either from the system or from the - user, that trigger a callback method such as <code>onCreate()</code> or - <code>onClick()</code>. For example, an activity should respond to pause or destroy events - by saving its state. Remember that even a change in screen orientation causes the current - activity to be destroyed, so you should test that accidental device movements don't - accidentally lose the application state. - </li> - <li> - Intents: Test that each activity correctly handles the intents listed in the intent - filter specified in its manifest. You can use - {@link android.test.ActivityInstrumentationTestCase2} to send mock Intents to the - activity under test. - </li> - <li> - Runtime configuration changes: Test that each activity responds correctly to the - possible changes in the device's configuration while your application is running. These - include a change to the device's orientation, a change to the current language, and so - forth. Handling these changes is described in detail in the topic - <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime - Changes</a>. - </li> - <li> - Screen sizes and resolutions: Before you publish your application, make sure to test it on - all of the screen sizes and densities on which you want it to run. You can test the - application on multiple sizes and densities using AVDs, or you can test your application - directly on the devices that you are targeting. For more information, see the topic - <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>. - </li> -</ul> -<h2 id="NextSteps">Next Steps</h2> -<p> - To learn how to set up and run tests in Android Studio, please refer to -<a href="{@docRoot}training/testing/unit-testing/local-unit-tests.html">Building Local Unit Tests</a>. - If you're not working in Android Studio, refer to -<a href="{@docRoot}tools/testing/testing_otheride.html">Testing from Other IDEs</a>. -</p> -<p> - If you want a step-by-step introduction to testing activities, try the - <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>, which - guides you through a testing scenario that you develop against an activity-oriented application. -</p> -<h2 id="UITesting">Appendix: UI Testing Notes</h2> -<p> - The following sections have tips for testing the UI of your Android application, specifically - to help you handle actions that run in the UI thread, touch screen and keyboard events, and home - screen unlock during testing. -</p> -<h3 id="RunOnUIThread">Testing on the UI thread</h3> -<p> - An application's activities run on the application's <strong>UI thread</strong>. Once the - UI is instantiated, for example in the activity's <code>onCreate()</code> method, then all - interactions with the UI must run in the UI thread. When you run the application normally, it - has access to the thread and does not have to do anything special. -</p> -<p> - This changes when you run tests against the application. With instrumentation-based classes, - you can invoke methods against the UI of the application under test. The other test classes - don't allow this. To run an entire test method on the UI thread, you can annotate the thread - with <code>@UiThreadTest</code>. Notice that this will run <em>all</em> of the method statements - on the UI thread. Methods that do not interact with the UI are not allowed; for example, you - can't invoke <code>Instrumentation.waitForIdleSync()</code>. -</p> -<p> - To run a subset of a test method on the UI thread, create an anonymous class of type - <code>Runnable</code>, put the statements you want in the <code>run()</code> method, and - instantiate a new instance of the class as a parameter to the method - <code><em>appActivity</em>.runOnUiThread()</code>, where <code><em>appActivity</em></code> is - the instance of the application you are testing. -</p> -<p> - For example, this code instantiates an activity to test, requests focus (a UI action) for the - Spinner displayed by the activity, and then sends a key to it. Notice that the calls to - <code>waitForIdleSync</code> and <code>sendKeys</code> aren't allowed to run on the UI thread: -</p> -<pre> - private MyActivity mActivity; // MyActivity is the class name of the app under test - private Spinner mSpinner; - - ... - - protected void setUp() throws Exception { - super.setUp(); - mInstrumentation = getInstrumentation(); - - mActivity = getActivity(); // get a references to the app under test - - /* - * Get a reference to the main widget of the app under test, a Spinner - */ - mSpinner = (Spinner) mActivity.findViewById(com.android.demo.myactivity.R.id.Spinner01); - - ... - - public void aTest() { - /* - * request focus for the Spinner, so that the test can send key events to it - * This request must be run on the UI thread. To do this, use the runOnUiThread method - * and pass it a Runnable that contains a call to requestFocus on the Spinner. - */ - mActivity.runOnUiThread(new Runnable() { - public void run() { - mSpinner.requestFocus(); - } - }); - - mInstrumentation.waitForIdleSync(); - - this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER); -</pre> - -<h3 id="NotouchMode">Turning off touch mode</h3> -<p> - To control the emulator or a device with key events you send from your tests, you must turn off - touch mode. If you do not do this, the key events are ignored. -</p> -<p> - To turn off touch mode, you invoke - <code>ActivityInstrumentationTestCase2.setActivityTouchMode(false)</code> - <em>before</em> you call <code>getActivity()</code> to start the activity. You must invoke the - method in a test method that is <em>not</em> running on the UI thread. For this reason, you - can't invoke the touch mode method from a test method that is annotated with - <code>@UIThread</code>. Instead, invoke the touch mode method from <code>setUp()</code>. -</p> -<h3 id="UnlockDevice">Unlocking the emulator or device</h3> -<p> - You may find that UI tests don't work if the emulator's or device's home screen is disabled with - the keyguard pattern. This is because the application under test can't receive key events sent - by <code>sendKeys()</code>. The best way to avoid this is to start your emulator or device - first and then disable the keyguard for the home screen. -</p> -<p> - You can also explicitly disable the keyguard. To do this, - you need to add a permission in the manifest file (<code>AndroidManifest.xml</code>) and - then disable the keyguard in your application under test. Note, though, that you either have to - remove this before you publish your application, or you have to disable it with code in - the published application. -</p> -<p> - To add the permission, add the element - <code><uses-permission android:name="android.permission.DISABLE_KEYGUARD"/></code> - as a child of the <code><manifest></code> element. To disable the KeyGuard, add the - following code to the <code>onCreate()</code> method of activities you intend to test: -</p> -<pre> - mKeyGuardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE); - mLock = mKeyGuardManager.newKeyguardLock("<em>activity_classname</em>"); - mLock.disableKeyguard(); -</pre> -<p>where <code><em>activity_classname</em></code> is the class name of the activity.</p> -<h3 id="UITestTroubleshooting">Troubleshooting UI tests</h3> -<p> - This section lists some of the common test failures you may encounter in UI testing, and their - causes: -</p> -<dl> - <dt><code>WrongThreadException</code></dt> - <dd> - <p><strong>Problem:</strong></p> - For a failed test, the Failure Trace contains the following error message: - <code> - android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created - a view hierarchy can touch its views. - </code> - <p><strong>Probable Cause:</strong></p> - This error is common if you tried to send UI events to the UI thread from outside the UI - thread. This commonly happens if you send UI events from the test application, but you don't - use the <code>@UIThread</code> annotation or the <code>runOnUiThread()</code> method. The - test method tried to interact with the UI outside the UI thread. - <p><strong>Suggested Resolution:</strong></p> - Run the interaction on the UI thread. Use a test class that provides instrumentation. See - the previous section <a href="#RunOnUIThread">Testing on the UI Thread</a> - for more details. - </dd> - <dt><code>java.lang.RuntimeException</code></dt> - <dd> - <p><strong>Problem:</strong></p> - For a failed test, the Failure Trace contains the following error message: - <code> - java.lang.RuntimeException: This method can not be called from the main application thread - </code> - <p><strong>Probable Cause:</strong></p> - This error is common if your test method is annotated with <code>@UiThreadTest</code> but - then tries to do something outside the UI thread or tries to invoke - <code>runOnUiThread()</code>. - <p><strong>Suggested Resolution:</strong></p> - Remove the <code>@UiThreadTest</code> annotation, remove the <code>runOnUiThread()</code> - call, or re-factor your tests. - </dd> -</dl> diff --git a/docs/html/tools/testing/contentprovider_testing.jd b/docs/html/tools/testing/contentprovider_testing.jd deleted file mode 100755 index 28aef919ad8b..000000000000 --- a/docs/html/tools/testing/contentprovider_testing.jd +++ /dev/null @@ -1,208 +0,0 @@ -page.title=Content Provider Testing -parent.title=Testing -parent.link=index.html -@jd:body - -<div id="qv-wrapper"> - <div id="qv"> - <h2>In this document</h2> - <ol> - <li> - <a href="#DesignAndTest">Content Provider Design and Testing</a> - </li> - <li> - <a href="#ContentProviderTestAPI">The Content Provider Testing API</a> - <ol> - <li> - <a href="#ProviderTestCase2">ProviderTestCase2 </a> - </li> - <li> - <a href="#MockObjects">Mock object classes</a> - </li> - </ol> - </li> - <li> - <a href="#WhatToTest">What To Test</a> - </li> - <li> - <a href="#NextSteps">Next Steps</a> - </li> - </ol> - <h2>Key Classes</h2> - <ol> - <li>{@link android.test.InstrumentationTestRunner}</li> - <li>{@link android.test.ProviderTestCase2}</li> - <li>{@link android.test.IsolatedContext}</li> - <li>{@link android.test.mock.MockContentResolver}</li> - </ol> - <h2>Related Tutorials</h2> - <ol> - <li> - <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a> - </li> - </ol> - <h2>See Also</h2> - <ol> - <li> - <a - href="{@docRoot}tools/testing/testing_android.html"> - Testing Fundamentals</a> - </li> - <li> - <a href="{@docRoot}tools/testing/testing_otheride.html"> - Testing From Other IDEs</a> - </li> - </ol> - </div> -</div> -<p> - Content providers, which store and retrieve data and make it accessible across applications, - are a key part of the Android API. As an application developer you're allowed to provide your - own public providers for use by other applications. If you do, then you should test them - using the API you publish. -</p> -<p> - This document describes how to test public content providers, although the information is - also applicable to providers that you keep private to your own application. If you aren't - familiar with content providers or the Android testing framework, please read - <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>, - the guide to developing content providers, and - <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>, - the introduction to the Android testing and instrumentation framework. -</p> -<h2 id="DesignAndTest">Content Provider Design and Testing</h2> -<p> - In Android, content providers are viewed externally as data APIs that provide - tables of data, with their internals hidden from view. A content provider may have many - public constants, but it usually has few if any public methods and no public variables. - This suggests that you should write your tests based only on the provider's public members. - A content provider that is designed like this is offering a contract between itself and its - users. -</p> -<p> - The base test case class for content providers, - {@link android.test.ProviderTestCase2}, allows you to test your content provider in an - isolated environment. Android mock objects such as {@link android.test.IsolatedContext} and - {@link android.test.mock.MockContentResolver} also help provide an isolated test environment. -</p> -<p> - As with other Android tests, provider test packages are run under the control of the test - runner {@link android.test.InstrumentationTestRunner}. The section - <a href="{@docRoot}tools/testing/testing_android.html#InstrumentationTestRunner"> - Running Tests With InstrumentationTestRunner</a> describes the test runner in - more detail. The topic <a href="{@docRoot}tools/testing/testing_otheride.html"> - Testing From Other IDEs</a> shows you how to run a test package from the command line. -</p> -<h2 id="ContentProviderTestAPI">Content Provider Testing API</h2> -<p> - The main focus of the provider testing API is to provide an isolated testing environment. This - ensures that tests always run against data dependencies set explicitly in the test case. It - also prevents tests from modifying actual user data. For example, you want to avoid writing - a test that fails because there was data left over from a previous test, and you want to - avoid adding or deleting contact information in a actual provider. -</p> -<p> - The test case class and mock object classes for provider testing set up this isolated testing - environment for you. -</p> -<h3 id="ProviderTestCase2">ProviderTestCase2</h3> -<p> - You test a provider with a subclass of {@link android.test.ProviderTestCase2}. This base class - extends {@link android.test.AndroidTestCase}, so it provides the JUnit testing framework as well - as Android-specific methods for testing application permissions. The most important - feature of this class is its initialization, which creates the isolated test environment. -</p> -<p> - The initialization is done in the constructor for {@link android.test.ProviderTestCase2}, which - subclasses call in their own constructors. The {@link android.test.ProviderTestCase2} - constructor creates an {@link android.test.IsolatedContext} object that allows file and - database operations but stubs out other interactions with the Android system. - The file and database operations themselves take place in a directory that is local to the - device or emulator and has a special prefix. -</p> -<p> - The constructor then creates a {@link android.test.mock.MockContentResolver} to use as the - resolver for the test. The {@link android.test.mock.MockContentResolver} class is described in - detail in the section - <a href="{@docRoot}tools/testing/testing_android.html#MockObjectClasses">Mock object -classes</a>. -</p> -<p> - Lastly, the constructor creates an instance of the provider under test. This is a normal - {@link android.content.ContentProvider} object, but it takes all of its environment information - from the {@link android.test.IsolatedContext}, so it is restricted to - working in the isolated test environment. All of the tests done in the test case class run - against this isolated object. -</p> -<h3 id="MockObjects">Mock object classes</h3> -<p> - {@link android.test.ProviderTestCase2} uses {@link android.test.IsolatedContext} and - {@link android.test.mock.MockContentResolver}, which are standard mock object classes. To - learn more about them, please read - <a href="{@docRoot}tools/testing/testing_android.html#MockObjectClasses"> - Testing Fundamentals</a>. -</p> -<h2 id="WhatToTest">What To Test</h2> -<p> - The topic <a href="{@docRoot}tools/testing/what_to_test.html">What To Test</a> - lists general considerations for testing Android components. - Here are some specific guidelines for testing content providers. -</p> -<ul> - <li> - Test with resolver methods: Even though you can instantiate a provider object in - {@link android.test.ProviderTestCase2}, you should always test with a resolver object - using the appropriate URI. This ensures that you are testing the provider using the same - interaction that a regular application would use. - </li> - <li> - Test a public provider as a contract: If you intent your provider to be public and - available to other applications, you should test it as a contract. This includes - the following ideas: - <ul> - <li> - Test with constants that your provider publicly exposes. For - example, look for constants that refer to column names in one of the provider's - data tables. These should always be constants publicly defined by the provider. - </li> - <li> - Test all the URIs offered by your provider. Your provider may offer several URIs, - each one referring to a different aspect of the data. The - <a href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a> sample, - for example, features a provider that offers one URI for retrieving a list of notes, - another for retrieving an individual note by it's database ID, and a third for - displaying notes in a live folder. - </li> - <li> - Test invalid URIs: Your unit tests should deliberately call the provider with an - invalid URI, and look for errors. Good provider design is to throw an - IllegalArgumentException for invalid URIs. - - </li> - </ul> - </li> - <li> - Test the standard provider interactions: Most providers offer six access methods: - query, insert, delete, update, getType, and onCreate(). Your tests should verify that all - of these methods work. These are described in more detail in the topic - <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>. - </li> - <li> - Test business logic: Don't forget to test the business logic that your provider should - enforce. Business logic includes handling of invalid values, financial or arithmetic - calculations, elimination or combining of duplicates, and so forth. A content provider - does not have to have business logic, because it may be implemented by activities that - modify the data. If the provider does implement business logic, you should test it. - </li> -</ul> -<h2 id="NextSteps">Next Steps</h2> -<p> - To learn how to set up and run tests from other IDEs, please refer to -<a href="{@docRoot}tools/testing/testing_otheride.html">Testing From Other IDEs</a>. -</p> -<p> - If you want a step-by-step introduction to testing activities, try the - <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>, which - guides you through a testing scenario that you develop against an activity-oriented application. -</p> - diff --git a/docs/html/tools/testing/index.jd b/docs/html/tools/testing/index.jd index 185727c27ecf..a4548912f4ff 100755..100644 --- a/docs/html/tools/testing/index.jd +++ b/docs/html/tools/testing/index.jd @@ -1,40 +1,19 @@ page.title=Testing @jd:body -<p> The Android framework includes an integrated testing framework that helps you test all aspects -of your application and the SDK tools include tools for setting up and running test applications. -Whether you are working in Android Studio or working from the command line, the SDK tools help you -set up and run your tests within an emulator or the device you are targeting. </p> - -<p>If you aren't yet familiar with the Android testing framework, start by reading <a -href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>. For a step-by-step -introduction to Android testing, try the <a -href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>. </p> - - - -<div class="landing-docs"> - - <div class="col-13" style="margin-left:0"> - <h3>Blog Articles</h3> - - <a href="http://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html"> - <h4>New Gingerbread API: StrictMode</h4> - <p>StrictMode is a new API in Gingerbread which primarily lets you set a policy on a thread -declaring what you’re not allowed to do on that thread, and what the penalty is if you violate the -policy. Implementation-wise, this policy is simply a thread-local integer bitmask.</p> - </a> - - <a href="http://android-developers.blogspot.com/2010/10/traceview-war-story.html"> - <h4>Traceview War Story</h4> - <p>I recently took my first serious look at Traceview, and it occurred to me, first, that -there are probably a few other Android developers who haven’t used it and, second, that this is an -opportunity to lecture sternly on one of my favorite subjects: performance improvement and -profiling.</p> - </a> - </div> - - -</div> - - +<p>Android provides an integrated testing framework that helps you test all aspects +of your app. The Android <a href="{@docRoot}sdk/installing/index.html">SDK</a> and +<a href="{@docRoot}tools/testing-support-library/index.html">Testing Support Library</a> include +tools and APIs for setting up and running test apps within an emulator or on the device you are +targeting. You can build and execute tests whether you are working in Android Studio or working +from the command line.</p> + +<p>To familiarize yourself with mobile app testing in Android, start by reading these resources:</p> +<ul> + <li><a href="{@docRoot}tools/testing/testing_android.html">Testing Concepts</a>: Learn key + concepts related to Android app testing and get an overview of the testing tools and APIs + that Google provides.</li> + <li><a href="{@docRoot}training/testing/start/index.html">Getting Started with Testing</a>: Learn + how to build and run your tests, step-by-step, using the testing APIs and tools that + Google provides.</li> +</ul> diff --git a/docs/html/tools/testing/service_testing.jd b/docs/html/tools/testing/service_testing.jd deleted file mode 100755 index e0bb351b30a7..000000000000 --- a/docs/html/tools/testing/service_testing.jd +++ /dev/null @@ -1,172 +0,0 @@ -page.title=Service Testing -parent.title=Testing -parent.link=index.html -@jd:body - -<div id="qv-wrapper"> - <div id="qv"> - <h2>In this document</h2> - <ol> - <li> - <a href="#DesignAndTest">Service Design and Testing</a> - </li> - <li> - <a href="#ServiceTestCase">ServiceTestCase</a> - </li> - <li> - <a href="#MockObjects">Mock object classes</a> - </li> - <li> - <a href="#TestAreas">What to Test</a> - </li> - </ol> - <h2>Key Classes</h2> - <ol> - <li>{@link android.test.InstrumentationTestRunner}</li> - <li>{@link android.test.ServiceTestCase}</li> - <li>{@link android.test.mock.MockApplication}</li> - <li>{@link android.test.RenamingDelegatingContext}</li> - </ol> - <h2>Related Tutorials</h2> - <ol> - <li> - <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a> - </li> - </ol> - <h2>See Also</h2> - <ol> - <li> - <a href="{@docRoot}tools/testing/testing_otheride.html"> - Testing From Other IDEs</a> - </li> - </ol> - </div> -</div> -<p> - Android provides a testing framework for Service objects that can run them in - isolation and provides mock objects. The test case class for Service objects is - {@link android.test.ServiceTestCase}. Since the Service class assumes that it is separate - from its clients, you can test a Service object without using instrumentation. -</p> -<p> - This document describes techniques for testing Service objects. If you aren't familiar with the - Service class, please read the <a href="{@docRoot}guide/components/services.html"> - Services</a> document. If you aren't familiar with Android testing, please read - <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>, - the introduction to the Android testing and instrumentation framework. -</p> -<h2 id="DesignAndTest">Service Design and Testing</h2> -<p> - When you design a Service, you should consider how your tests can examine the various states - of the Service lifecycle. If the lifecycle methods that start up your Service, such as - {@link android.app.Service#onCreate() onCreate()} or - {@link android.app.Service#onStartCommand(Intent, int, int) onStartCommand()} do not normally - set a global variable to indicate that they were successful, you may want to provide such a - variable for testing purposes. -</p> -<p> - Most other testing is facilitated by the methods in the {@link android.test.ServiceTestCase} - test case class. For example, the {@link android.test.ServiceTestCase#getService()} method - returns a handle to the Service under test, which you can test to confirm that the Service is - running even at the end of your tests. -</p> -<h2 id="ServiceTestCase">ServiceTestCase</h2> -<p> - {@link android.test.ServiceTestCase} extends the JUnit {@link junit.framework.TestCase} class - with methods for testing application permissions and for controlling the application and - Service under test. It also provides mock application and Context objects that isolate your - test from the rest of the system. -</p> -<p> - {@link android.test.ServiceTestCase} defers initialization of the test environment until you - call {@link android.test.ServiceTestCase#startService(Intent) ServiceTestCase.startService()} or - {@link android.test.ServiceTestCase#bindService(Intent) ServiceTestCase.bindService()}. This - allows you to set up your test environment, particularly your mock objects, before the Service - is started. -</p> -<p> - Notice that the parameters to <code>ServiceTestCase.bindService()</code>are different from - those for <code>Service.bindService()</code>. For the <code>ServiceTestCase</code> version, - you only provide an Intent. Instead of returning a boolean, - <code>ServiceTestCase.bindService()</code> returns an object that subclasses - {@link android.os.IBinder}. -</p> -<p> - The {@link android.test.ServiceTestCase#setUp()} method for {@link android.test.ServiceTestCase} - is called before each test. It sets up the test fixture by making a copy of the current system - Context before any test methods touch it. You can retrieve this Context by calling - {@link android.test.ServiceTestCase#getSystemContext()}. If you override this method, you must - call <code>super.setUp()</code> as the first statement in the override. -</p> -<p> - The methods {@link android.test.ServiceTestCase#setApplication(Application) setApplication()} - and {@link android.test.AndroidTestCase#setContext(Context)} setContext()} allow you to set - a mock Context or mock Application (or both) for the Service, before you start it. These mock - objects are described in <a href="#MockObjects">Mock object classes</a>. -</p> -<p> - By default, {@link android.test.ServiceTestCase} runs the test method - {@link android.test.AndroidTestCase#testAndroidTestCaseSetupProperly()}, which asserts that - the base test case class successfully set up a Context before running. -</p> -<h2 id="MockObjects">Mock object classes</h2> -<p> - <code>ServiceTestCase</code> assumes that you will use a mock Context or mock Application - (or both) for the test environment. These objects isolate the test environment from the - rest of the system. If you don't provide your own instances of these objects before you - start the Service, then {@link android.test.ServiceTestCase} will create its own internal - instances and inject them into the Service. You can override this behavior by creating and - injecting your own instances before starting the Service -</p> -<p> - To inject a mock Application object into the Service under test, first create a subclass of - {@link android.test.mock.MockApplication}. <code>MockApplication</code> is a subclass of - {@link android.app.Application} in which all the methods throw an Exception, so to use it - effectively you subclass it and override the methods you need. You then inject it into the - Service with the - {@link android.test.ServiceTestCase#setApplication(Application) setApplication()} method. - This mock object allows you to control the application values that the Service sees, and - isolates it from the real system. In addition, any hidden dependencies your Service has on - its application reveal themselves as exceptions when you run the test. -</p> -<p> - You inject a mock Context into the Service under test with the - {@link android.test.AndroidTestCase#setContext(Context) setContext()} method. The mock - Context classes you can use are described in more detail in - <a href="{@docRoot}tools/testing/testing_android.html#MockObjectClasses"> - Testing Fundamentals</a>. -</p> -<h2 id="TestAreas">What to Test</h2> -<p> - The topic <a href="{@docRoot}tools/testing/what_to_test.html">What To Test</a> - lists general considerations for testing Android components. - Here are some specific guidelines for testing a Service: -</p> -<ul> - <li> - Ensure that the {@link android.app.Service#onCreate()} is called in response to - {@link android.content.Context#startService(Intent) Context.startService()} or - {@link android.content.Context#bindService(Intent,ServiceConnection,int) Context.bindService()}. - Similarly, you should ensure that {@link android.app.Service#onDestroy()} is called in - response to {@link android.content.Context#stopService(Intent) Context.stopService()}, - {@link android.content.Context#unbindService(ServiceConnection) Context.unbindService()}, - {@link android.app.Service#stopSelf()}, or - {@link android.app.Service#stopSelfResult(int) stopSelfResult()}. - </li> - <li> - Test that your Service correctly handles multiple calls from - <code>Context.startService()</code>. Only the first call triggers - <code>Service.onCreate()</code>, but all calls trigger a call to - <code>Service.onStartCommand()</code>. - <p> - In addition, remember that <code>startService()</code> calls don't - nest, so a single call to <code>Context.stopService()</code> or - <code>Service.stopSelf()</code> (but not <code>stopSelf(int)</code>) - will stop the Service. You should test that your Service stops at the correct point. - </p> - </li> - <li> - Test any business logic that your Service implements. Business logic includes checking for - invalid values, financial and arithmetic calculations, and so forth. - </li> -</ul> diff --git a/docs/html/tools/testing/testing-tools.jd b/docs/html/tools/testing/testing-tools.jd index 5e0a5bcd26fa..c60199f78d1d 100644 --- a/docs/html/tools/testing/testing-tools.jd +++ b/docs/html/tools/testing/testing-tools.jd @@ -5,7 +5,7 @@ page.title=Android Testing Tools <div id="qv"> <h2>See also</h2> <ol> - <li><a href="{@docRoot}training/testing.html">Best Practices for Testing</a></li> + <li><a href="{@docRoot}training/testing/index.html">Best Practices for Testing</a></li> </ol> </div> </div> diff --git a/docs/html/tools/testing/testing_android.jd b/docs/html/tools/testing/testing_android.jd index 5b2b549d377a..5adb7e96230f 100755 --- a/docs/html/tools/testing/testing_android.jd +++ b/docs/html/tools/testing/testing_android.jd @@ -1,4 +1,4 @@ -page.title=Testing Fundamentals +page.title=Testing Concepts parent.title=Testing parent.link=index.html @jd:body @@ -7,14 +7,8 @@ parent.link=index.html <div id="qv"> <h2>In this document</h2> <ol> - <li> - <a href="#TestStructure">Test Structure</a> - </li> - <li> - <a href="#TestProjects">Test Projects</a> - </li> - <li> - <a href="#TestAPI">The Testing API</a> + <li><a href="#TestStructure">Test Structure</a></li> + <li><a href="#TestAPI">Testing APIs</a> <ol> <li> <a href="#JUnit">JUnit</a> @@ -23,521 +17,256 @@ parent.link=index.html <a href="#Instrumentation">Instrumentation</a> </li> <li> - <a href="#TestCaseClasses">Test case classes</a> + <a href="#TestingSupportLibraryClasses">Android Testing Support Library APIs</a> </li> <li> <a href="#AssertionClasses">Assertion classes</a> </li> - <li> - <a href="#MockObjectClasses">Mock object classes</a> - </li> </ol> </li> <li> - <a href="#InstrumentationTestRunner">Running Tests</a> - </li> - <li> - <a href="#TestResults">Seeing Test Results</a> - </li> - <li> - <a href="#Monkeys">monkey and monkeyrunner</a> - </li> - <li> - <a href="#PackageNames">Working With Package Names</a> - </li> - <li> - <a href="#WhatToTest">What To Test</a> - </li> - <li> - <a href="#NextSteps">Next Steps</a> + <a href="#Monkeys">Monkey and Monkeyrunner</a> </li> </ol> - <h2>Key classes</h2> - <ol> - <li>{@link android.test.InstrumentationTestRunner}</li> - <li>{@link android.test}</li> - <li>{@link android.test.mock}</li> - <li>{@link junit.framework}</li> - </ol> - <h2>Related tutorials</h2> - <ol> - <li> - <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a> - </li> - </ol> <h2>See also</h2> - <ol> - <li> - <a href="{@docRoot}tools/testing/testing_otheride.html"> - Testing from Other IDEs</a> - </li> - <li> - <a href="{@docRoot}tools/help/monkeyrunner_concepts.html"> - monkeyrunner</a> - </li> - <li> - <a href="{@docRoot}tools/help/monkey.html">UI/Application Exerciser Monkey</a> - </li> - </ol> + <ol> + <li><a href="{@docRoot}training/testing/start/index.html">Getting Started with Testing</a></li> + </ol> </div> </div> + <p> - The Android testing framework, an integral part of the development environment, - provides an architecture and powerful tools that help you test every aspect of your application - at every level from unit to framework. -</p> -<p> - The testing framework has these key features: -</p> +This document describes key concepts related to Android app testing. It assumes you have a basic +knowledge of the <a href="http://junit.org/" class="external-link">JUnit</a> testing framework.</p> + +<h2 id="TestStructure">Test Structure</h2> +<p>Android testing is based on JUnit. In general, a JUnit test is a method whose statements test a +part of the application. You organize test methods into classes called +<em>test cases</em>. You can further organize these classes into <em>test suites</em>.</p> +<p>In JUnit, you build one or more test classes and use a test runner to +execute them. In Android, you use <a href="{@docRoot}tools/studio/index.html"> +Android Studio </a>(or the <a href="{@docRoot}tools/building/plugin-for-gradle.html"> +Android Plugin for Gradle</a>) to build one or more test source files into an +<em>Android test app</em>.</p> + +<p>From your testing environment, you can run your test in one of the following ways:</p> <ul> - <li> - Android test suites are based on JUnit. You can use plain JUnit to test a class that doesn't - call the Android API, or Android's JUnit extensions to test Android components. If you're - new to Android testing, you can start with general-purpose test case classes such as {@link - android.test.AndroidTestCase} and then go on to use more sophisticated classes. - </li> - <li> - The Android JUnit extensions provide component-specific test case classes. These classes - provide helper methods for creating mock objects and methods that help you control the - lifecycle of a component. - </li> - <li> - Test suites are contained in test packages that are similar to main application packages, so - you don't need to learn a new set of tools or techniques for designing and building tests. - </li> - <li> - The SDK tools for building and tests are available in Android Studio, and also in - command-line form for use with other IDEs. These tools get information from the project of - the application under test and use this information to automatically create the build files, - manifest file, and directory structure for the test package. - </li> - <li> - The SDK also provides - <a href="{@docRoot}tools/help/monkeyrunner_concepts.html">monkeyrunner</a>, an API - for testing devices with Python programs, and <a - href="{@docRoot}tools/help/monkey.html">UI/Application Exerciser Monkey</a>, - a command-line tool for stress-testing UIs by sending pseudo-random events to a device. - </li> + <li><strong>On your local machine:</strong> Compile the test classes and + execute them locally on the Java Virtual Machine (JVM) using the JUnit test runner.</li> + <li><strong>On a device or emulator</strong>: Install the test app and the app +under test to a physical device or emulator, and then execute your tests using an Android-specific +test runner (such as <a href="{@docRoot}tools/testing-support-library/index.html#AndroidJUnitRunner"> +{@code AndroidJUnitRunner}</a>).</li> </ul> -<p> - This document describes the fundamentals of the Android testing framework, including the - structure of tests, the APIs that you use to develop tests, and the tools that you use to run - tests and view results. The document assumes you have a basic knowledge of Android application - programming and JUnit testing methodology. -</p> -<p> - The following diagram summarizes the testing framework: -</p> -<div style="width: 70%; margin-left:auto; margin-right:auto;"> -<a href="{@docRoot}images/testing/test_framework.png"> - <img src="{@docRoot}images/testing/test_framework.png" - alt="The Android testing framework"/> -</a> -</div> -<h2 id="TestStructure">Test Structure</h2> -<p> - Android's build and test tools assume that test projects are organized into a standard - structure of tests, test case classes, test packages, and test projects. -</p> -<p> - Android testing is based on JUnit. In general, a JUnit test is a method whose - statements test a part of the application under test. You organize test methods into classes - called test cases (or test suites). Each test is an isolated test of an individual module in - the application under test. Each class is a container for related test methods, although it - often provides helper methods as well. -</p> -<p> - In JUnit, you build one or more test source files into a class file. Similarly, in Android you - use the SDK's build tools to build one or more test source files into class files in an - Android test package. In JUnit, you use a test runner to execute test classes. In Android, you - use test tools to load the test package and the application under test, and the tools then - execute an Android-specific test runner. -</p> -<h2 id="TestProjects">Test Projects</h2> -<p> - Tests, like Android applications, are organized into projects. -</p> -<p> - A test project is a directory in which you create the source code, manifest - file, and other files for a test package. The Android SDK contains tools for Android Studio - and for the command line that create and update test projects for you. The tools create the - directories you use for source code and resources and the manifest file for the test package. -</p> -<p> - You should always use Android tools to create a test project. Among other benefits, - the tools: -</p> - <ul> - <li> - Automatically set up your test package to use - {@link android.test.InstrumentationTestRunner} as the test case runner. You must use - <code>InstrumentationTestRunner</code> (or a subclass) to run JUnit tests. - </li> - <li> - Create an appropriate name for the test package. If the application - under test has a package name of <code>com.mydomain.myapp</code>, then the - Android tools set the test package name to <code>com.mydomain.myapp.test</code>. This - helps you identify their relationship, while preventing conflicts within the system. - </li> - <li> - Automatically create the proper build files, manifest file, and directory - structure for the test project. This helps you to build the test package without - having to modify build files and sets up the linkage between your test package and - the application under test. - The - </li> - </ul> -<p> - You can create a test project anywhere in your file system, but the best approach is to - add the test project so that its root directory <code>tests/</code> is at the same level - as the <code>src/</code> directory of the main application's project. This helps you find the - tests associated with an application. For example, if your application project's root directory - is <code>MyProject</code>, then you should use the following directory structure: -</p> -<pre class="classic no-pretty-print"> - MyProject/ - AndroidManifest.xml - res/ - ... (resources for main application) - src/ - ... (source code for main application) ... - tests/ - AndroidManifest.xml - res/ - ... (resources for tests) - src/ - ... (source code for tests) -</pre> -<h2 id="TestAPI">The Testing API</h2> -<p> - The Android testing API is based on the JUnit API and extended with a instrumentation - framework and Android-specific testing classes. -</p> + +<p>The structure of your test code and the way you build and run the tests in Android Studio depend +on the type of testing you are performing. The following table summarizes the common testing types +for Android:</p> + +<table> +<tr><th>Type</th> + <th>Subtype</th> + <th>Description</th></tr> + +<tr><td rowspan="3">Unit tests</td> + <tr><td>Local Unit Tests</td> + <td>Unit tests that run on your local machine only. These tests are compiled to run locally +on the JVM to minimize execution time. Use this approach to run unit tests +that have no dependencies on the Android framework or have dependencies that mock objects can +satisfy.</td></tr> + <tr><td>Instrumented unit tests</td> + <td>Unit tests that run on an Android device or emulator. These tests have access to +{@link android.app.Instrumentation} information, such as the {@link android.content.Context} of the +app under test. Use this approach to run unit tests that have Android dependencies which mock +objects cannot easily satisfy.</td></tr> + +<tr><td rowspan="3">Integration Tests</td> + <tr><td>Components within your app only</td> + <td>This type of test verifies that the target app behaves as expected when a user performs +a specific action or enters a specific input in its activities. For example, it allows you to check +that the target app returns the correct UI output in response to user interactions in the app’s +activities. UI testing frameworks like +<a href="{@docRoot}tools/testing-support-library/index.html#Espresso">Espresso</a> allow you to +programmatically simulate user actions and test complex intra-app user interactions.</td></tr> + <tr><td>Cross-app Components</td> + <td>This type of test verifies the correct behavior of interactions between different user +apps or between user apps and system apps. For example, you might want to test that your app behaves +correctly when the user performs an action in the Android Settings menu. UI testing frameworks +that support cross-app interactions, such as UI Automator, allow you to create tests for such +scenarios.</td></tr> +</table> + +<p>Based on the type of test you want to create, you need to configure the test code source +location and the project dependencies in Android Studio as described in +<a href="{@docRoot}training/testing/start/index.html">Getting Started with Testing</a>.</p> + +<h2 id="TestAPI">Testing APIs</h2> +<p>The following list summarizes the common APIs related to app testing for Android.</p> + <h3 id="JUnit">JUnit</h3> -<p> - You can use the JUnit {@link junit.framework.TestCase TestCase} class to do unit testing on - a class that doesn't call Android APIs. <code>TestCase</code> is also the base class for - {@link android.test.AndroidTestCase}, which you can use to test Android-dependent objects. - Besides providing the JUnit framework, AndroidTestCase offers Android-specific setup, - teardown, and helper methods. -</p> -<p> - You use the JUnit {@link junit.framework.Assert} class to display test results. - The assert methods compare values you expect from a test to the actual results and - throw an exception if the comparison fails. Android also provides a class of assertions that - extend the possible types of comparisons, and another class of assertions for testing the UI. - These are described in more detail in the section <a href="#AssertionClasses"> - Assertion classes</a> -</p> -<p> - To learn more about JUnit, you can read the documentation on the - <a href="http://www.junit.org">junit.org</a> home page. - Note that the Android testing API supports JUnit 3 code style, but not JUnit 4. Also, you must - use Android's instrumented test runner {@link android.test.InstrumentationTestRunner} to run - your test case classes. This test runner is described in the - section <a href="#InstrumentationTestRunner">Running Tests</a>. -</p> -<h3 id="Instrumentation">Instrumentation</h3> -<p> - Android instrumentation is a set of control methods or "hooks" in the Android system. These hooks - control an Android component independently of its normal lifecycle. They also control how - Android loads applications. -</p> -<p> - Normally, an Android component runs in a lifecycle determined by the system. For example, an - Activity object's lifecycle starts when the Activity is activated by an Intent. The object's - <code>onCreate()</code> method is called, followed by <code>onResume()</code>. When the user - starts another application, the <code>onPause()</code> method is called. If the Activity - code calls the <code>finish()</code> method, the <code>onDestroy()</code> method is called. - The Android framework API does not provide a way for your code to invoke these callback - methods directly, but you can do so using instrumentation. -</p> -<p> - Also, the system runs all the components of an application into the same - process. You can allow some components, such as content providers, to run in a separate process, - but you can't force an application to run in the same process as another application that is - already running. -</p> -<p> - With Android instrumentation, though, you can invoke callback methods in your test code. - This allows you to run through the lifecycle of a component step by step, as if you were - debugging the component. The following test code snippet demonstrates how to use this to - test that an Activity saves and restores its state: -</p> -<a name="ActivitySnippet"></a> -<pre> - // Start the main activity of the application under test - mActivity = getActivity(); - // Get a handle to the Activity object's main UI widget, a Spinner - mSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01); +<p>You should write your unit or integration test class as a JUnit 4 test class. +<a href="http://junit.org/" class="external-link">JUnit</a> is the most popular +and widely-used unit testing framework for Java. The framework offers a convenient way to perform +common setup, teardown, and assertion operations in your test.</p> - // Set the Spinner to a known position - mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION); +<p>JUnit 4 allows you to write tests in a cleaner and more +flexible way than its predecessor versions. Unlike the previous approach to Android unit testing +based on JUnit 3, with JUnit 4, you do not need to extend the {@code junit.framework.TestCase} +class. You also do not need to prepend the {@code test} keyword to your test method name, or +use any classes in the {@code junit.framework} or {@code junit.extensions} package.</p> - // Stop the activity - The onDestroy() method should save the state of the Spinner - mActivity.finish(); +<p>A basic JUnit 4 test class is a Java class that contains one or more test methods. +A test method begins with the {@code @Test} annotation and contains the code to exercise +and verify a single functionality (that is, a logical <em>unit</em>) in the component that you want +to test.</p> +<p>The following snippet shows an example JUnit 4 integration test that uses the Espresso +APIs to perform a click action on a UI element, then checks to see if an expected string is +displayed.</p> +<pre> +@RunWith(AndroidJUnit4.class) +@LargeTest +public class MainActivityInstrumentationTest { - // Re-start the Activity - the onResume() method should restore the state of the Spinner - mActivity = getActivity(); + @Rule + public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>( + MainActivity.class); - // Get the Spinner's current position - int currentPosition = mActivity.getSpinnerPosition(); + @Test + public void sayHello(){ + onView(withText("Say hello!")).perform(click()); - // Assert that the current position is the same as the starting position - assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition); + onView(withId(R.id.textView)).check(matches(withText("Hello, World!"))); + } +} </pre> -<p> - The key method used here is - {@link android.test.ActivityInstrumentationTestCase2#getActivity()}, which is a - part of the instrumentation API. The Activity under test is not started until you call this - method. You can set up the test fixture in advance, and then call this method to start the - Activity. -</p> -<p> - Also, instrumentation can load both a test package and the application under test into the - same process. Since the application components and their tests are in the same process, the - tests can invoke methods in the components, and modify and examine fields in the components. -</p> -<h3 id="TestCaseClasses">Test case classes</h3> -<p> - Android provides several test case classes that extend {@link junit.framework.TestCase} and - {@link junit.framework.Assert} with Android-specific setup, teardown, and helper methods. -</p> -<h4 id="AndroidTestCase">AndroidTestCase</h4> -<p> - A useful general test case class, especially if you are - just starting out with Android testing, is {@link android.test.AndroidTestCase}. It extends - both {@link junit.framework.TestCase} and {@link junit.framework.Assert}. It provides the - JUnit-standard <code>setUp()</code> and <code>tearDown()</code> methods, as well as - all of JUnit's Assert methods. In addition, it provides methods for testing permissions, and a - method that guards against memory leaks by clearing out certain class references. -</p> -<h4 id="ComponentTestCase">Component-specific test cases</h4> -<p> - A key feature of the Android testing framework is its component-specific test case classes. - These address specific component testing needs with methods for fixture setup and - teardown and component lifecycle control. They also provide methods for setting up mock objects. - These classes are described in the component-specific testing topics: -</p> +<p>In your JUnit 4 test class, you can call out sections in your test code for +special processing by using the following annotations:</p> <ul> - <li> - <a href="{@docRoot}tools/testing/activity_testing.html">Activity Testing</a> - </li> - <li> - <a href="{@docRoot}tools/testing/contentprovider_testing.html"> - Content Provider Testing</a> - </li> - <li> - <a href="{@docRoot}tools/testing/service_testing.html">Service Testing</a> - </li> +<li> +{@code @Before}: Use this annotation to specify a block of code that contains test setup +operations. The test class invokes this code block before each test. You can have multiple +{@code @Before} methods but the order in which the test class calls these methods +is not guaranteed. +</li> +<li> +{@code @After}: This annotation specifies a block of code that contains test +tear-down operations. The test class calls this code block after every test method. You can define +multiple {@code @After} operations in your test code. Use this annotation to release any +resources from memory. +</li> +<li> +{@code @Test}: Use this annotation to mark a test method. A single test class can contain +multiple test methods, each prefixed with this annotation. +</li> +<li> +{@code @Rule}: Rules allow you to flexibly add or redefine the behavior of each test +method in a reusable way. In Android testing, use this annotation together with +one of the test rule classes that the Android Testing Support Library provides, such as +<a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html"> +{@code ActivityTestRule}</a> or +<a href="{@docRoot}reference/android/support/test/rule/ServiceTestRule.html"> +{@code ServiceTestRule}</a>. +</li> +<li> +{@code @BeforeClass}: Use this annotation to specify static methods for each test class to +invoke only once. This testing step is useful for expensive operations such as connecting to a +database. +</li> +<li> +{@code @AfterClass}: Use this annotation to specify static methods for the test class to invoke +only after all tests in the class have run. This testing step is useful for releasing any +resources allocated in the {@code @BeforeClass} block. +</li> +<li> +{@code @Test(timeout=<milliseconds>)}: Some annotations support the ability to pass in +elements for which you can set values. For example, you can specify a timeout period for the test. +If the test starts but does not complete within the given timeout period, it automatically fails. +You must specify the timeout period in milliseconds, for example: {@code @Test(timeout=5000)}. +</li> </ul> +<p>For more annotations, see the documentation for +<a href="//junit.sourceforge.net/javadoc/org/junit/package-summary.html" class="external-link"> +JUnit annotations</a> and the +<a href="{@docRoot}android/support/test/annotation/package-summary.html"> +Android-specific annotations</a>. <p> - Android does not provide a separate test case class for BroadcastReceiver. Instead, test a - BroadcastReceiver by testing the component that sends it Intent objects, to verify that the - BroadcastReceiver responds correctly. -</p> -<h4 id="ApplicationTestCase">ApplicationTestCase</h4> -<p> - You use the {@link android.test.ApplicationTestCase} test case class to test the setup and - teardown of {@link android.app.Application} objects. These objects maintain the global state of - information that applies to all the components in an application package. The test case can - be useful in verifying that the <application> element in the manifest file is correctly - set up. Note, however, that this test case does not allow you to control testing of the - components within your application package. -</p> -<h4 id="InstrumentationTestCase">InstrumentationTestCase</h4> -<p> - If you want to use instrumentation methods in a test case class, you must use - {@link android.test.InstrumentationTestCase} or one of its subclasses. The - {@link android.app.Activity} test cases extend this base class with other functionality that - assists in Activity testing. + You use the JUnit {@link junit.framework.Assert} class to verify the correctness of an object's + state. The assert methods compare values you expect from a test to the actual results and + throw an exception if the comparison fails. <a href="#AssertionClasses"> + Assertion classes</a> describes these methods in more detail. </p> -<h3 id="AssertionClasses">Assertion classes</h3> -<p> - Because Android test case classes extend JUnit, you can use assertion methods to display the - results of tests. An assertion method compares an actual value returned by a test to an - expected value, and throws an AssertionException if the comparison test fails. Using assertions - is more convenient than doing logging, and provides better test performance. -</p> -<p> - Besides the JUnit {@link junit.framework.Assert} class methods, the testing API also provides - the {@link android.test.MoreAsserts} and {@link android.test.ViewAsserts} classes: -</p> -<ul> - <li> - {@link android.test.MoreAsserts} contains more powerful assertions such as - {@link android.test.MoreAsserts#assertContainsRegex}, which does regular expression - matching. - </li> - <li> - {@link android.test.ViewAsserts} contains useful assertions about Views. For example - it contains {@link android.test.ViewAsserts#assertHasScreenCoordinates} that tests if a View - has a particular X and Y position on the visible screen. These asserts simplify testing of - geometry and alignment in the UI. - </li> -</ul> -<h3 id="MockObjectClasses">Mock object classes</h3> -<p> - To facilitate dependency injection in testing, Android provides classes that create mock system - objects such as {@link android.content.Context} objects, - {@link android.content.ContentProvider} objects, {@link android.content.ContentResolver} - objects, and {@link android.app.Service} objects. Some test cases also provide mock - {@link android.content.Intent} objects. You use these mocks both to isolate tests - from the rest of the system and to facilitate dependency injection for testing. These classes - are found in the packages {@link android.test} and {@link android.test.mock}. -</p> -<p> - Mock objects isolate tests from a running system by stubbing out or overriding - normal operations. For example, a {@link android.test.mock.MockContentResolver} - replaces the normal resolver framework with its own local framework, which is isolated - from the rest of the system. MockContentResolver also stubs out the - {@link android.content.ContentResolver#notifyChange(Uri, ContentObserver, boolean)} method - so that observer objects outside the test environment are not accidentally triggered. </p> +<h3 id="Instrumentation">Instrumentation</h3> <p> - Mock object classes also facilitate dependency injection by providing a subclass of the - normal object that is non-functional except for overrides you define. For example, the - {@link android.test.mock.MockResources} object provides a subclass of - {@link android.content.res.Resources} in which all the methods throw Exceptions when called. - To use it, you override only those methods that must provide information. + Android instrumentation is a set of control methods or hooks in the Android system. These + hooks control an Android component independently of its normal lifecycle. They also control how + Android loads applications. </p> <p> - These are the mock object classes available in Android: + The following diagram summarizes the testing framework: </p> -<h4 id="SimpleMocks">Simple mock object classes</h4> +<div style="width: 70%; margin-left:auto; margin-right:auto;"> +<a href="{@docRoot}images/testing/test_framework.png"> + <img src="{@docRoot}images/testing/test_framework.png" + alt="The Android testing framework"/> +</a> +</div> <p> - {@link android.test.mock.MockApplication}, {@link android.test.mock.MockContext}, - {@link android.test.mock.MockContentProvider}, {@link android.test.mock.MockCursor}, - {@link android.test.mock.MockDialogInterface}, {@link android.test.mock.MockPackageManager}, and - {@link android.test.mock.MockResources} provide a simple and useful mock strategy. They are - stubbed-out versions of the corresponding system object class, and all of their methods throw an - {@link java.lang.UnsupportedOperationException} exception if called. To use them, you override - the methods you need in order to provide mock dependencies. +Normally, an Android component runs in a lifecycle that the system determines. For example, an +{@link android.app.Activity} object's lifecycle starts when an {@link android.content.Intent} +activates the {@link android.app.Activity}. The system calls the object's <code>onCreate()</code> +method, on then the <code>onResume()</code> method. When the user starts another application, the +system calls the <code>onPause()</code> method. If the {@link android.app.Activity} code calls +the <code>finish()</code> method, the system calls the <code>onDestroy()</code> method. The Android +framework API does not provide a way for your code to invoke these callback methods directly, but +you can do so using instrumentation. </p> -<p class="Note"><strong>Note:</strong> - {@link android.test.mock.MockContentProvider} - and {@link android.test.mock.MockCursor} are new as of API level 8. -</p> -<h4 id="ResolverMocks">Resolver mock objects</h4> <p> - {@link android.test.mock.MockContentResolver} provides isolated testing of content providers by - masking out the normal system resolver framework. Instead of looking in the system to find a - content provider given an authority string, MockContentResolver uses its own internal table. You - must explicitly add providers to this table using - {@link android.test.mock.MockContentResolver#addProvider(String,ContentProvider)}. +The system runs all the components of an application in the same process. You can allow some +components, such as content providers, to run in a separate process, +but you can't force an application to run in the same process as another application that is +already running. </p> <p> - With this feature, you can associate a mock content provider with an authority. You can create - an instance of a real provider but use test data in it. You can even set the provider for an - authority to <code>null</code>. In effect, a MockContentResolver object isolates your test - from providers that contain real data. You can control the - function of the provider, and you can prevent your test from affecting real data. +Instrumentation can load both a test package and the app under test into the +same process. Since the application components and their tests are in the same process, your +tests can invoke methods in the components, and modify and examine fields in the components. </p> -<h3 id="ContextMocks">Contexts for testing</h3> +<h3 id="TestingSupportLibraryClasses">Android Testing Support Library APIs</h3> <p> - Android provides two Context classes that are useful for testing: -</p> +The <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a> +provides a set of APIs that allow you to quickly build and run test code for your apps, including +JUnit 4 and functional user interface (UI) tests. The library includes the following +instrumentation-based APIs that are useful when you want to automate your tests:</p> <ul> - <li> - {@link android.test.IsolatedContext} provides an isolated {@link android.content.Context}, - File, directory, and database operations that use this Context take place in a test area. - Though its functionality is limited, this Context has enough stub code to respond to - system calls. - <p> - This class allows you to test an application's data operations without affecting real - data that may be present on the device. - </p> + <li><a href="{@docRoot}tools/testing-support-library/index.html#AndroidJUnitRunner"> + {@code AndroidJUnitRunner}</a>: + JUnit 4-compatible test runner for Android </li> - <li> - {@link android.test.RenamingDelegatingContext} provides a Context in which - most functions are handled by an existing {@link android.content.Context}, but - file and database operations are handled by a {@link android.test.IsolatedContext}. - The isolated part uses a test directory and creates special file and directory names. - You can control the naming yourself, or let the constructor determine it automatically. - <p> - This object provides a quick way to set up an isolated area for data operations, - while keeping normal functionality for all other Context operations. - </p> + + <li><a href="{@docRoot}tools/testing-support-library/index.html#Espresso">Espresso</a>: + UI testing framework; suitable for functional UI testing within an app </li> -</ul> -<h2 id="InstrumentationTestRunner">Running Tests</h2> -<p> - Test cases are run by a test runner class that loads the test case class, set ups, - runs, and tears down each test. An Android test runner must also be instrumented, so that - the system utility for starting applications can control how the test package - loads test cases and the application under test. You tell the Android platform - which instrumented test runner to use by setting a value in the test package's manifest file. -</p> -<p> - {@link android.test.InstrumentationTestRunner} is the primary Android test runner class. It - extends the JUnit test runner framework and is also instrumented. It can run any of the test - case classes provided by Android and supports all possible types of testing. -</p> -<p> - You specify <code>InstrumentationTestRunner</code> or a subclass in your test package's - manifest file, in the -<code><a href="{@docRoot}guide/topics/manifest/instrumentation-element.html"><instrumentation></a></code> - element. Also, <code>InstrumentationTestRunner</code> code resides - in the shared library <code>android.test.runner</code>, which is not normally linked to - Android code. To include it, you must specify it in a -<code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html"><uses-library></a></code> - element. You do not have to set up these elements yourself. Both Android Studio and the - <code>android</code> command-line tool construct them automatically and add them to your - test package's manifest file. -</p> -<p class="Note"> - <strong>Note:</strong> If you use a test runner other than - <code>InstrumentationTestRunner</code>, you must change the <instrumentation> - element to point to the class you want to use. -</p> -<p> - To run {@link android.test.InstrumentationTestRunner}, you use internal system classes called by - Android tools. When you run a test in Android Studio the classes are called automatically. - When you run a test from the command line, you run these classes with - <a href="{@docRoot}tools/help/adb.html">Android Debug Bridge (adb)</a>. -</p> -<p> - The system classes load and start the test package, kill any processes that - are running an instance of the application under test, and then load a new instance of the - application under test. They then pass control to - {@link android.test.InstrumentationTestRunner}, which runs - each test case class in the test package. You can also control which test cases and - methods are run using settings in Android Studio or using flags with the command-line tools. -</p> -<p> - Neither the system classes nor {@link android.test.InstrumentationTestRunner} run - the application under test. Instead, the test case does this directly. It either calls methods - in the application under test, or it calls its own methods that trigger lifecycle events in - the application under test. The application is under the complete control of the test case, - which allows it to set up the test environment (the test fixture) before running a test. This - is demonstrated in the previous <a href="#ActivitySnippet">code snippet</a> that tests an - Activity that displays a Spinner widget. -</p> -<p> - To learn more about running tests, please read - <a href="{@docRoot}tools/testing/testing_otheride.html"> - Testing from Other IDEs</a>. -</p> -<h2 id="TestResults">Seeing Test Results</h2> -<p> - The Android testing framework returns test results back to the tool that started the test. - If you run a test in Android Studio, the results are displayed in a new JUnit view pane. If - you run a test from the command line, the results are displayed in <code>STDOUT</code>. In - both cases, you see a test summary that displays the name of each test case and method that - was run. You also see all the assertion failures that occurred. These include pointers to the - line in the test code where the failure occurred. Assertion failures also list the expected - value and actual value. -</p> -<p> - The test results have a format that is specific to the IDE that you are using. The test -results format for tests run from the - command line is described in - <a href="{@docRoot}tools/testing/testing_otheride.html#RunTestsCommand"> - Testing from Other IDEs</a>. -</p> -<h2 id="Monkeys">monkey and monkeyrunner</h2> + + <li><a href="{@docRoot}tools/testing-support-library/index.html#UIAutomator">UI Automator</a>: + UI testing framework; suitable for cross-app functional UI testing across system and installed + apps</li> + </ul> + +<h3 id="AssertionClasses">Assertion classes</h3> +<p>Because Android Testing Support Library APIs extend JUnit, you can use assertion methods to +display the results of tests. An assertion method compares an actual value returned by a test to an +expected value, and throws an AssertionException if the comparison test fails. Using assertions +is more convenient than logging, and provides better test performance. +</p> +<p>To simplify your test development, we recommend that you use the +<a href="https://github.com/hamcrest" +class="external-link">Hamcrest</a> library, which lets you create more flexible tests using the +Hamcrest matcher APIs.</p> + +<h2 id="Monkeys">Monkey and Monkeyrunner</h2> <p> The SDK provides two tools for functional-level application testing: </p> @@ -560,67 +289,4 @@ The <a href="{@docRoot}tools/help/monkey.html">UI/Application Exerciser Monkey</ tests. You run programs that use the API with the <code>monkeyrunner</code> command-line tool. </li> - </ul> -<h2 id="PackageNames">Working With Package names</h2> -<p> - In the test environment, you work with both Android application package names and - Java package identifiers. Both use the same naming format, but they represent substantially - different entities. You need to know the difference to set up your tests correctly. -</p> -<p> - An Android package name is a unique system name for a <code>.apk</code> file, set by the - "android:package" attribute of the <manifest> element in the package's - manifest. The Android package name of your test package must be different from the - Android package name of the application under test. By default, Android tools create the - test package name by appending ".test" to the package name of the application under test. -</p> -<p> - The test package also uses an Android package name to target the application package it - tests. This is set in the "android:targetPackage" attribute of the - <instrumentation> element in the test package's manifest. -</p> -<p> - A Java package identifier applies to a source file. This package name reflects the directory - path of the source file. It also affects the visibility of classes and members to each other. -</p> -<p> - Android tools that create test projects set up an Android test package name for you. - From your input, the tools set up the test package name and the target package name for the - application under test. For these tools to work, the application project must already exist. -</p> -<p> - By default, these tools set the Java package identifier for the test class to be the same - as the Android package identifier. You may want to change this if you want to expose - members in the application under test by giving them package visibility. If you do this, - change only the Java package identifier, not the Android package names, and change only the - test case source files. Do not change the Java package name of the generated - <code>R.java</code> class in your test package, because it will then conflict with the - <code>R.java</code> class in the application under test. Do not change the Android package name - of your test package to be the same as the application it tests, because then their names - will no longer be unique in the system. -</p> -<h2 id="WhatToTest">What to Test</h2> -<p> - The topic <a href="{@docRoot}tools/testing/what_to_test.html">What To Test</a> - describes the key functionality you should test in an Android application, and the key - situations that might affect that functionality. -</p> -<p> - Most unit testing is specific to the Android component you are testing. - The topics <a href="{@docRoot}tools/testing/activity_testing.html">Activity Testing</a>, - <a href="{@docRoot}tools/testing/contentprovider_testing.html"> - Content Provider Testing</a>, and <a href="{@docRoot}tools/testing/service_testing.html"> - Service Testing</a> each have a section entitled "What To Test" that lists possible testing - areas. -</p> -<p> - When possible, you should run these tests on an actual device. If this is not possible, you can - use the <a href="{@docRoot}tools/devices/emulator.html">Android Emulator</a> with - Android Virtual Devices configured for the hardware, screens, and versions you want to test. -</p> -<h2 id="NextSteps">Next Steps</h2> - -<p> - If you want a step-by-step introduction to Android testing, try the - <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>. -</p> + </ul>
\ No newline at end of file diff --git a/docs/html/tools/testing/testing_otheride.jd b/docs/html/tools/testing/testing_otheride.jd index 8a3eb05defd9..4b2a6b14680b 100755 --- a/docs/html/tools/testing/testing_otheride.jd +++ b/docs/html/tools/testing/testing_otheride.jd @@ -1,6 +1,5 @@ -page.title=Testing from Other IDEs -parent.title=Testing -parent.link=index.html +page.title=Testing from the Command-Line + @jd:body <div id="qv-wrapper"> @@ -8,27 +7,13 @@ parent.link=index.html <h2>In this document</h2> <ol> <li> - <a href="#CreateTestProjectCommand">Working with Test Projects</a> - <ol> - <li> - <a href="#CreateTestProject">Creating a test project</a> - </li> - <li> - <a href="#UpdateTestProject">Updating a test project</a> - </li> - </ol> - </li> - <li> - <a href="#CreateTestApp">Creating a Test Package</a> - </li> - <li> <a href="#RunTestsCommand">Running Tests</a> <ol> <li> - <a href="#RunTestsAnt">Quick build and run with Gradle</a> + <a href="#RunTestsGradle">Running unit tests with Gradle</a> </li> <li> - <a href="#RunTestsDevice">Running tests on a device or emulator</a> + <a href="#RunTestsDevice">Running tests with adb</a> </li> </ol> </li> @@ -47,288 +32,84 @@ parent.link=index.html <h2>See Also</h2> <ol> <li> - <a href="{@docRoot}tools/testing/testing_android.html"> - Testing Fundamentals</a> - </li> - <li> <a href="{@docRoot}tools/help/adb.html">Android Debug Bridge</a> </li> </ol> </div> </div> <p> - This document describes how to create and run tests directly from the command line. - You can use the techniques described here if you are developing in an IDE other than Android Studio - or if you prefer to work from the command line. This document assumes that you already know how - to create a Android application in your programming environment. Before you start this - document, you should read the topic - <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>, - which provides an overview of Android testing. -</p> -<p> - If you are developing in Android Studio, you can set up and run your tests - directly in Android Studio. + This document describes how to create and run tests directly from the command line. This + document assumes that you already know how to create a Android application in your programming + environment. </p> -<h2 id="CreateTestProjectCommand">Working with Test Projects</h2> -<p> - You use the <code>android</code> tool to create test projects. - You also use <code>android</code> to convert existing test code into an Android test project, - or to add the <code>test</code> Gradle target to an existing Android test project. - These operations are described in more detail in the section <a href="#UpdateTestProject"> - Updating a test project</a>. The <code>test</code> target is described in - <a href="#RunTestsAnt">Quick build and run with Gradle</a>. -</p> -<h3 id="CreateTestProject">Creating a test project</h3> -<p> - To create a test project with the <code>android</code> tool, enter: -</p> -<pre> -android create test-project -m <main_path> -n <project_name> -p <test_path> -</pre> + +<h2 id="RunTestsCommand">Running Tests</h2> <p> - You must supply all the flags. The following table explains them in detail: + You can run tests from the command-line, either with Gradle or with an + <a href="{@docRoot}tools/help/adb.html"> + Android Debug Bridge (adb)</a> shell. </p> +<h3 id="RunTestsGradle">Running unit tests with Gradle</h3> + +<p>The <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plugin for Gradle</a> +lets you run unit tests from your Gradle project via the command-line. For more information on +how to build unit tests for your app, see +<a href="{@docRoot}training/testing/unit-testing/index.html">Building Effective Unit Tests</a>.</p> + +<p>The table below summarizes how to run your unit tests with Gradle:</p> <table> <tr> - <th>Flag</th> - <th>Value</th> - <th>Description</th> - </tr> - <tr> - <td><code>-m, --main</code></td> - <td> - Path to the project of the application under test, relative to the test package - directory. - </td> - <td> - For example, if the application under test is in <code>source/HelloAndroid</code>, and - you want to create the test project in <code>source/HelloAndroidTest</code>, then the - value of <code>--main</code> should be <code>../HelloAndroid</code>. - <p> - To learn more about choosing the location of test projects, please read - <a href="{@docRoot}tools/testing/testing_android.html#TestProjects"> - Testing Fundamentals</a>. - </p> - </td> + <th>Unit Test Type</th> + <th>Command To Run</th> + <th>Test Result Location</th> </tr> <tr> - <td><code>-n, --name</code></td> - <td>Name that you want to give the test project.</td> - <td> </td> + <td>Local unit test</td> + <td>Call the {@code test} task: +<pre> +./gradlew test +</pre></td> + <td> +HTML test result files: +{@code <path_to_your_project>/app/build/reports/tests/} directory. +<p>XML test result files: +{@code <path_to_your_project>/app/build/test-results/} directory. +</p></td> </tr> <tr> - <td><code>-p, --path</code></td> - <td>Directory in which you want to create the new test project.</td> - <td> - The <code>android</code> tool creates the test project files and directory structure - in this directory. If the directory does not exist, <code>android</code> creates it. - </td> - </tr> -</table> -<p> - If the operation is successful, <code>android</code> lists to STDOUT the names of the files - and directories it has created. -</p> -<p> - This creates a new test project with the appropriate directories and build files. The directory - structure and build file contents are identical to those in a regular Android application - project. They are described in detail in the topic - <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>. -</p> -<p> - The operation also creates an <code>AndroidManifest.xml</code> file with instrumentation - information. When you run the test, Android uses this information to load the application you - are testing and control it with instrumentation. -</p> -<p> - For example, suppose you create a project in the directory <code>~/source/HelloAndroid</code>, -with the package name <code>com.example.helloandroid</code>, - and the activity name <code>HelloAndroid</code>. You can to create the test for this in - <code>~/source/HelloAndroidTest</code>. To do so, you enter: -</p> + <td>Instrumented unit test</td> + <td>Call the {@code connectedAndroidTest} (or {@code cAT}) task: <pre> -$ cd ~/source -$ android create test-project -m ../HelloAndroid -n HelloAndroidTest -p HelloAndroidTest +./gradlew cAT </pre> -<p> - This creates a directory called <code>~/src/HelloAndroidTest</code>. In the new directory you - see the file <code>AndroidManifest.xml</code>. This file contains the following - instrumentation-related elements and attributes: -</p> -<ul> - <li> - <code><application></code>: to contain the - <code><uses-library></code> element. - </li> - <li> - <code><uses-library android:name="android.test.runner"</code>: - specifies this testing application uses the <code>android.test.runner</code> library. - </li> - <li> - <code><instrumentation></code>: contains attributes that control Android - instrumentation. The attributes are: - <ul> - <li> - <code>android:name="android.test.InstrumentationTestRunner"</code>: - {@link android.test.InstrumentationTestRunner} runs test cases. It extends both - JUnit test case runner classes and Android instrumentation classes. - </li> - <li> - <code>android:targetPackage="com.example.helloandroid"</code>: specifies - that the tests in HelloAndroidTest should be run against the application with the - <em>Android</em> package name <code>com.example.helloandroid</code>. - </li> - <li> - <code>android:label="Tests for .HelloAndroid"</code>: specifies a - user-readable label for the instrumentation class. By default, - the <code>android</code> tool gives it the value "Tests for " plus - the name of the main Activity of the application under test. - </li> - </ul> - </li> -</ul> -<h3 id="UpdateTestProject">Updating a test project</h3> -<p> - You use the <code>android</code> tool when you need to change the path to the - project of the application under test. If you are changing an existing test project created in - Android Studio so that you can also build and run it from the command line, you must use the - "create" operation. See the section <a href="#CreateTestProject">Creating a test project</a>. -</p> -<p class="note"> - <strong>Note:</strong> If you change the Android package name of the application under test, - you must <em>manually</em> change the value of the <code><android:targetPackage></code> - attribute within the <code>AndroidManifest.xml</code> file of the test package. - Running <code>android update test-project</code> does not do this. -</p> -<p> - To update a test project with the <code>android</code> tool, enter: -</p> -<pre>android update test-project -m <main_path> -p <test_path></pre> - -<table> - <tr> - <th>Flag</th> - <th>Value</th> - <th>Description</th> - </tr> - <tr> - <td><code>-m, --main</code></td> - <td>The path to the project of the application under test, relative to the test project</td> - <td> - For example, if the application under test is in <code>source/HelloAndroid</code>, and - the test project is in <code>source/HelloAndroidTest</code>, then the value for - <code>--main</code> is <code>../HelloAndroid</code>. </td> - </tr> - <tr> - <td><code>-p, --path</code></td> - <td>The of the test project.</td> <td> - For example, if the test project is in <code>source/HelloAndroidTest</code>, then the - value for <code>--path</code> is <code>HelloAndroidTest</code>. - </td> +HTML test result files: +{@code <path_to_your_project>/app/build/outputs/reports/androidTests/connected/} directory. +<p>XML test result files: +{@code <path_to_your_project>/app/build/outputs/androidTest-results/connected/} directory. +</p></td> </tr> </table> -<p> - If the operation is successful, <code>android</code> lists to STDOUT the names of the files - and directories it has created. -</p> -<h2 id="CreateTestApp">Creating a Test Package</h2> -<p> - Once you have created a test project, you populate it with a test package. - The application does not require an {@link android.app.Activity Activity}, - although you can define one if you wish. Although your test package can - combine Activities, Android test class extensions, JUnit extensions, or - ordinary classes, you should extend one of the Android test classes or JUnit classes, - because these provide the best testing features. -</p> -<p> - If you run your tests with {@link android.test.InstrumentationTestRunner} - (or a related test runner), then it will run all the methods in each class. You can modify - this behavior by using the {@link junit.framework.TestSuite TestSuite} class. -</p> +<h3 id="RunTestsDevice">Running tests with ADB</h3> <p> - To create a test package, start with one of Android's test classes in the Java package - {@link android.test android.test}. These extend the JUnit - {@link junit.framework.TestCase TestCase} class. With a few exceptions, the Android test - classes also provide instrumentation for testing. -</p> -<p> - For test classes that extend {@link junit.framework.TestCase TestCase}, you probably want to - override the <code>setUp()</code> and <code>tearDown()</code> methods: -</p> -<ul> - <li> - <code>setUp()</code>: This method is invoked before any of the test methods in the class. - Use it to set up the environment for the test. You can use <code>setUp()</code> - to instantiate a new <code>Intent</code> object with the action <code>ACTION_MAIN</code>. - You can then use this intent to start the Activity under test. - <p class="note"> - <strong>Note:</strong> If you override this method, call - <code>super.setUp()</code> as the first statement in your code. - </p> - </li> - <li> - <code>tearDown()</code>: This method is invoked after all the test methods in the class. Use - it to do garbage collection and re-setting before moving on to the next set of tests. - <p class="note"><strong>Note:</strong> If you override this method, you must call - <code>super.tearDown()</code> as the <em>last</em> statement in your code.</p> - </li> -</ul> -<p> - Another useful convention is to add the method <code>testPreConditions()</code> to your test - class. Use this method to test that the application under test is initialized correctly. If this - test fails, you know that the initial conditions were in error. When this happens, further - test results are suspect, regardless of whether or not the tests succeeded. -</p> -<p> - To learn more about creating test packages, see the topic <a - href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>, - which provides an overview of Android testing. If you prefer to follow a tutorial, - try the <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing</a> - tutorial, which leads you through the creation of tests for an actual Android application. -</p> -<h2 id="RunTestsCommand">Running Tests</h2> -<p> - You run tests from the command line, either with Gradle or with an - <a href="{@docRoot}tools/help/adb.html"> - Android Debug Bridge (adb)</a> shell. -</p> -<h3 id="RunTestsAnt">Quick build and run with Gradle</h3> -<p> - You can use Gradle to run all the tests in your test project, using the target - <code>test</code>, which is created automatically when you create a test project with - the <code>android</code> tool. -</p> -<p> - This target re-builds your main project and test project if necessary, installs the test - application to the current AVD or device, and then runs all the test classes in the test - application. The results are directed to <code>STDOUT</code>. -</p> -<p> - You can update an existing test project to use this feature. To do this, use the - <code>android</code> tool with the <code>update test-project</code> option. This is described - in the section <a href="#UpdateTestProject">Updating a test project</a>. -</p> -<h3 id="RunTestsDevice">Running tests on a device or emulator</h3> -<p> - When you run tests from the command line with + When you run tests from the command-line with <a href="{@docRoot}tools/help/adb.html"> Android Debug Bridge (adb)</a>, you get more options for choosing the tests to run than with any other method. You can select individual test methods, filter tests according to their annotation, or specify testing options. Since the test run is controlled - entirely from a command line, you can customize your testing with shell scripts in various ways. + entirely from a command-line, you can customize your testing with shell scripts in various ways. </p> <p> - To run a test from the command line, you run <code>adb shell</code> to start a command-line + To run a test from the command-line, you run <code>adb shell</code> to start a command-line shell on your device or emulator, and then in the shell run the <code>am instrument</code> command. You control <code>am</code> and your tests with command-line flags. </p> <p> As a shortcut, you can start an <code>adb</code> shell, call <code>am instrument</code>, and specify command-line flags all on one input line. The shell opens on the device or emulator, - runs your tests, produces output, and then returns to the command line on your computer. + runs your tests, produces output, and then returns to the command-line on your computer. </p> <p> To run a test with <code>am instrument</code>: @@ -341,7 +122,7 @@ $ android create test-project -m ../HelloAndroid -n HelloAndroidTest -p HelloAnd Install your test package and main application Android package files (<code>.apk</code> files) to your current Android device or emulator</li> <li> - At the command line, enter: + At the command-line, enter: <pre> $ adb shell am instrument -w <test_package_name>/<runner_class> </pre> @@ -351,7 +132,9 @@ $ adb shell am instrument -w <test_package_name>/<runner_class> runner class you are using. The Android package name is the value of the <code>package</code> attribute of the <code>manifest</code> element in the manifest file (<code>AndroidManifest.xml</code>) of your test package. The Android test runner - class is usually {@link android.test.InstrumentationTestRunner}. + class is usually +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> +{@code AndroidJUnitRunner}</a>. </p> <p> Your test results appear in <code>STDOUT</code>. @@ -369,7 +152,7 @@ $ adb shell am instrument -w <test_package_name>/<runner_class> The general syntax of the <code>am instrument</code> command is: </p> <pre> - am instrument [flags] <test_package>/<runner_class> +am instrument [flags] <test_package>/<runner_class> </pre> <p> The main input parameters to <code>am instrument</code> are described in the following table: @@ -406,10 +189,13 @@ $ adb shell am instrument -w <test_package_name>/<runner_class> The class name of the instrumented test runner you are using. </td> <td> - This is usually {@link android.test.InstrumentationTestRunner}. + This is usually +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> +{@code AndroidJUnitRunner}</a>. </td> </tr> </table> + <p> The flags for <code>am instrument</code> are described in the following table: </p> @@ -465,12 +251,11 @@ $ adb shell am instrument -w <test_package_name>/<runner_class> <code>am instrument</code> tool passes these to the specified instrumentation class via its <code>onCreate()</code> method. You can specify multiple occurrences of <code>-e <test_options></code>. The keys and values are described in the - section <a href="#AMOptionsSyntax">am instrument options</a>. - <p> - The only instrumentation class that uses these key-value pairs is - {@link android.test.InstrumentationTestRunner} (or a subclass). Using them with - any other class has no effect. - </p> + section <a href="#AMOptionsSyntax">am instrument options</a>. You can only use these + key-value pairs with +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> +{@code AndroidJUnitRunner}</a> or with {@link android.test.InstrumentationTestRunner} and its +subclasses. Using them with any other class has no effect. </td> </tr> </table> @@ -478,25 +263,24 @@ $ adb shell am instrument -w <test_package_name>/<runner_class> <h3 id="AMOptionsSyntax">am instrument options</h3> <p> The <code>am instrument</code> tool passes testing options to - <code>InstrumentationTestRunner</code> or a subclass in the form of key-value pairs, - using the <code>-e</code> flag, with this syntax: +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> +{@code AndroidJUnitRunner}</a> or {@link android.test.InstrumentationTestRunner} in the form of +key-value pairs, using the <code>-e</code> flag, with this syntax: </p> <pre> - -e <key> <value> +-e <key> <value> </pre> <p> Some keys accept multiple values. You specify multiple values in a comma-separated list. - For example, this invocation of <code>InstrumentationTestRunner</code> provides multiple - values for the <code>package</code> key: + For example, this invocation of +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> +{@code AndroidJUnitRunner}</a> provides multiple values for the <code>package</code> key: </p> <pre> $ adb shell am instrument -w -e package com.android.test.package1,com.android.test.package2 \ -> com.android.test/android.test.InstrumentationTestRunner +> com.android.test/android.support.test.runner.AndroidJUnitRunner </pre> -<p> - The following table describes the key-value pairs and their result. Please review the - <strong>Usage Notes</strong> following the table. -</p> +<p>The following table lists the key-value pairs you can use with your test runner.</p> <table> <tr> <th>Key</th> @@ -554,8 +338,8 @@ $ adb shell am instrument -w -e package com.android.test.package1,com.android.te [<code>small</code> | <code>medium</code> | <code>large</code>] </td> <td> - Runs a test method annotated by size. The annotations are <code>@SmallTest</code>, - <code>@MediumTest</code>, and <code>@LargeTest</code>. + Runs a test method annotated by size. The annotations are <code>@SmallTest</code>, + <code>@MediumTest</code>, and <code>@LargeTest</code>. </td> </tr> <tr> @@ -589,8 +373,9 @@ $ adb shell am instrument -w -e package com.android.test.package1,com.android.te <td><code>true</code></td> <td> Runs an EMMA code coverage analysis and writes the output to - <code>/data//coverage.ec</code> on the device. To override the file location, use the - <code>coverageFile</code> key that is described in the following entry. + <code>/data/<app_package>/coverage.ec</code> on the device. To override the + file location, use the <code>coverageFile</code> key that is described in the + following entry. <p class="note"> <strong>Note:</strong> This option requires an EMMA-instrumented build of the test application, which you can generate with the <code>coverage</code> target. @@ -632,24 +417,16 @@ They are based on the following structure:</p> The test package has the Android package name <code>com.android.demo.app.tests</code> </li> <li> - There are three test classes: + Two instrumented test classes: <ul> - <li> - <code>UnitTests</code>, which contains the methods - <code>testPermissions</code> and <code>testSaveState</code>. - </li> - <li> - <code>FunctionTests</code>, which contains the methods - <code>testCamera</code>, <code>testXVGA</code>, and <code>testHardKeyboard</code>. - </li> - <li> - <code>IntegrationTests</code>, - which contains the method <code>testActivityProvider</code>. - </li> + <li>{@code Foo1} which contains the test method {@code bar1}, and</li> + <li>{@code Foo2} which contains test methods {@code bar2} and {@code bar3}</li> </ul> </li> <li> - The test runner is {@link android.test.InstrumentationTestRunner}. + The test runner is +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> +{@code AndroidJUnitRunner}</a>. </li> </ul> <h4>Running the entire test package</h4> @@ -657,7 +434,7 @@ They are based on the following structure:</p> To run all of the test classes in the test package, enter: </p> <pre> -$ adb shell am instrument -w com.android.demo.app.tests/android.test.InstrumentationTestRunner +$ adb shell am instrument -w com.android.demo.app.tests/android.support.test.runner.AndroidJUnitRunner </pre> <h4>Running all tests in a test case class</h4> <p> @@ -665,8 +442,8 @@ $ adb shell am instrument -w com.android.demo.app.tests/android.test.Instrumenta </p> <pre> $ adb shell am instrument -w \ -> -e class com.android.demo.app.tests.UnitTests \ -> com.android.demo.app.tests/android.test.InstrumentationTestRunner +> -e class com.android.demo.app.tests.Foo \ +> com.android.demo.app.tests/android.support.test.runner.AndroidJUnitRunner </pre> <p> <code>am instrument</code> gets the value of the <code>-e</code> flag, detects the @@ -674,15 +451,11 @@ $ adb shell am instrument -w \ </p> <h4>Selecting a subset of tests</h4> <p> - To run all of the tests in <code>UnitTests</code>, and the <code>testCamera</code> method in - <code>FunctionTests</code>, enter: + To run all of the tests in <code>Foo1</code>, and the <code>bar3</code> method in + <code>Foo2</code>, enter: </p> <pre> $ adb shell am instrument -w \ -> -e class com.android.demo.app.tests.UnitTests,com.android.demo.app.tests.FunctionTests#testCamera \ -> com.android.demo.app.tests/android.test.InstrumentationTestRunner +> -e class com.android.demo.app.tests.Foo1,com.android.demo.app.tests.Foo2#bar3 \ +> com.android.demo.app.tests/android.support.test.runner.AndroidJUnitRunner </pre> -<p> - You can find more examples of the command in the documentation for - {@link android.test.InstrumentationTestRunner}. -</p> diff --git a/docs/html/tools/testing/testing_ui.jd b/docs/html/tools/testing/testing_ui.jd deleted file mode 100644 index 4318a2165ab1..000000000000 --- a/docs/html/tools/testing/testing_ui.jd +++ /dev/null @@ -1,356 +0,0 @@ -page.title=UI Testing -parent.title=Testing -parent.link=index.html -@jd:body - -<div id="qv-wrapper"> - <div id="qv"> - <h2>In this document</h2> - <ol> - <li><a href="#overview">Overview</a></li> - <ul> - <li><a href="#workflow">Workflow</a></li> - </ul> - <li><a href="#uianalysis">Analyzing Your UI</a></li> - <li><a href="#prepare">Preparing to Test</a> - <ul> - <LI><a href="#loading">Load the App</a></LI> - <LI><a href="#identifyUI">Identify UI Components</a></LI> - <LI><a href="#accessibility">Ensure Accessibility</a></LI> - <LI><a href="#configure">Configure Development Environment</a></LI> - </ul> - </li> - <li><a href="#creating">Creating Tests</a> - <ul> - <LI><a href="#classes">uiautomator API</a></LI> - <li><a href="#sample">Sample Test Case</a> - </ul> - </li> - <li><a href="#builddeploy">Building and Deploying Tests</a></li> - <li><a href="#running">Running Tests</a></li> - <li><a href="#bestpractices">Best Practices</a></li> - </ol> - <h2>Key classes</h2> - <ol> - <li><a href="{@docRoot}tools/help/uiautomator/IAutomationSupport.html">IAutomationSupport</a></li> - <li><a href="{@docRoot}tools/help/uiautomator/UiAutomatorTestCase.html">UiAutomatorTestCase</a></li> - <li><a href="{@docRoot}tools/help/uiautomator/UiCollection.html">UiCollection</a></li> - <li><a href="{@docRoot}tools/help/uiautomator/UiDevice.html">UiDevice</a></li> - <li><a href="{@docRoot}tools/help/uiautomator/UiObject.html">UiObject</a></li> - <li><a href="{@docRoot}tools/help/uiautomator/UiScrollable.html">UiScrollable</a></li> - <li><a href="{@docRoot}tools/help/uiautomator/UiSelector.html">UiSelector</a></li> - </ol> - <h2>See Also</h2> - <ol> - <li> - <a href="{@docRoot}tools/help/uiautomator/index.html">uiautomator (reference)</a> - </li> - </ol> - </div> -</div> - -<p> -In addition to unit testing the individual components that make up your Android application (such as activities, services, and content providers), it is also important that you test the behavior of your application’s user interface (UI) when it is running on a device. UI testing ensures that your application returns the correct UI output in response to a sequence of user actions on a device, such as entering keyboard input or pressing toolbars, menus, dialogs, images, and other UI controls. -</p> -<p> -Functional or black-box UI testing does not require testers to know the internal implementation details of the app, only its expected output when a user performs a specific action or enters a specific input. This approach allows for better separation of development and testing roles in your organization. -</p> -<p>One common approach to UI testing is to run tests manually and verify that the app is behaving as expected. However, this approach can be time-consuming, tedious, and error-prone. A more efficient and reliable approach is to automate the UI testing with a software testing framework. Automated testing involves creating programs to perform testing tasks (test cases) to cover specific usage scenarios, and then using the testing framework to run the test cases automatically and in a repeatable manner.</p> - -<h2 id="overview">Overview</h2> -<p>The Android SDK provides the following tools to support automated, functional UI testing on your application: -<ul> -<LI>{@code uiautomatorviewer} - A GUI tool to scan and analyze the UI components of an Android application.</LI> -<LI>{@code uiautomator} - A Java library containing APIs to create customized functional UI tests, and an execution engine to automate and run the tests.</LI> -</ul></p> - -<p>To use these tools, you must have the following versions of the Android development tools installed: -<ul> -<LI>Android SDK Tools, Revision 21 or higher</LI> -<LI>Android SDK Platform, API 16 or higher</LI> -</ul> -</p> - -<h3 id="workflow">Workflow for the the uiautomator testing framework</h3> -<p>Here's a short overview of the steps required to automate UI testing: -<ol> -<LI>Prepare to test by installing the app on a test device, analyzing the app’s UI components, and ensuring that your application is accessible by the test automation framework.</LI> -<li>Create automated tests to simulate specific user interactions on your application.</li> -<li>Compile your test cases into a JAR file and install it on your test device along with your app.</li> -<li>Run the tests and view the test results.</li> -<li>Correct any bugs or defects discovered in testing.</li> -</ol> -</p> - -<h2 id="uianalysis">Analyzing Your Application's UI</h2> -<p>Before you start writing your test cases, it's helpful to familiarize yourself with the UI components (including the views and controls) of the targeted application. You can use the {@code uiautomatorviewer} tool to take a snapshot of the foreground UI screen on any Android device that is connected to your development machine. The {@code uiautomatorviewer} tool provides a convenient visual interface to inspect the layout hierarchy and view the properties of the individual UI components that are displayed on the test device. Using this information, you can later create {@code uiautomator} tests with selector objects that target specific UI components to test.</p> - -<a href="{@docRoot}images/testing/UIAutomatorViewer.png"> - <img src="{@docRoot}images/testing/UIAutomatorViewer.png" - alt="User interface of uiautomatorviewer tool" height="327px" id="figure1"/> -</a> -<p class="img-caption"> - <strong>Figure 1.</strong> The {@code uiautomatorviewer} showing the captured interface of a test device. -</p> - -<p>To analyze the UI components of the application that you want to test:</p> -<ol> -<li>Connect your Android device to your development machine.</li> -<li>Open a terminal window and navigate to {@code <android-sdk>/tools/}.</li> -<LI>Run the tool with this command:<pre>$ uiautomatorviewer</pre></LI> -<li><p>To capture a screen for analysis, click the <strong>Device Screenshot</strong> button in the GUI of the {@code uiautomatorviewer} tool.</p> -<p class="note"><strong>Note: </strong>If you have more than one device connected, specify the device for screen capture by setting the {@code ANDROID_SERIAL} environment variable: - <ol type="a"> - <li>Find the serial numbers for your connected devices by running this command:<pre>$ adb devices</pre> </li> - <li>Set the {@code ANDROID_SERIAL} environment variable to select the device to test: - <ul> - <li>In Windows: <pre>set ANDROID_SERIAL=<device serial number></pre></li> - <li>In UNIX: <pre>export ANDROID_SERIAL=<device serial number></pre></li> - </ul> - </li> - </ol> -If you are connected to only a single device, you do not need to set the ANDROID_SERIAL environment variable.</p> -</li> -<li>View the UI properties for your application: - <ul> - <LI>Hover over the snapshot in the left-hand panel to see the UI components identified by the {@code uiautomatorviewer} tool. You can view the component’s properties listed in the lower right-hand panel, and the layout hierarchy in the upper right-hand panel.</LI> - <li>Optionally, click on the <strong>Toggle NAF Nodes</strong> button to see UI components that are not accessible to the {@code uiautomator} testing framework. Only limited information may be available for these components.</li> - </ul> -</li> -</ol> - -<h2 id="prepare">Preparing to Test</h2> -<p>Before using the {@code uiautomator} testing framework, complete these pre-flight tasks: -</p> -<h3 id="loading">Load the application to a device</h3> -<p>If you are reading this document, chances are that the Android application that you want to test has not been published yet. If you have a copy of the APK file, you can install the APK onto a test device by using the {@code adb} tool. To learn how to install an APK file using the {@code adb} tool, see the <a href="{@docRoot}tools/help/adb.html#move">{@code adb}</a> documentation. </p> - -<h3 id="identifyUI">Identify the application’s UI components</h3> -<p>Before writing your {@code uiautomator} tests, first identify the UI components in the application that you want to test. Typically, good candidates for testing are UI components that are visible and that users can interact with. The UI components should also have visible text labels, <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">{@code android:contentDescription}</a> values, or both. - -<p>You can inspect the visible screen objects in an application conveniently by using the {@code uiautomatorviewer} tool. For more information about how to analyze an application screen with this tool, see the section <a href="#uianalaysis">Analyzing Your Application’s UI</a>. For more information about the common types of UI components provided by Android, see <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a>.</p> - -<h3 id="accessibility">Ensure that the application is accessible</h3> -<p>This step is required because the {@code uiautomator} tool depends on the accessibility features of the Android framework to execute your functional UI tests. You should include these minimum optimizations to support the {@code uiautomator} tool: -<ul> -<LI>Use the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">{@code android:contentDescription}</a> attribute to label the {@link android.widget.ImageButton}, {@link android.widget.ImageView}, {@link android.widget.CheckBox} and other user interface controls.</LI> -<li>Provide an <a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">{@code android:hint}</a> attribute <em>instead</em> of a content description for {@link android.widget.EditText} fields</li> -<li>Associate an <a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">{@code android:hint}</a> attribute with any graphical icons used by controls that provide feedback to the user (for example, status or state information).</li> -<li>Make sure that all the user interface elements are accessible with a directional controller, such as a trackball or D-pad.</li> -<li>Use the {@code uiautomatorviewer} tool to ensure that the UI component is accessible to the testing framework. You can also test the application by turning on accessibility services like TalkBack and Explore by Touch, and try using your application using only directional controls. </li> -</ul> -</p> - -<p>For more information about implementing and testing accessibility, see <a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications Accessible</a>.</p> - -<p class="note"><strong>Note: </strong>To identify the non-accessible components in the UI, click on the <strong>Toggle NAF Nodes</strong> option in the {@code uiautomatorviewer} tool.</p> - -<p>Generally, Android application developers get accessibility support for free, courtesy of the {@link android.view.View} and {@link android.view.ViewGroup} classes. However, some applications use custom view components to provide a richer user experience. Such custom components won't get the accessibility support that is provided by the standard Android UI components. If this applies to your application, ensure that the application developer exposes the custom drawn UI components to Android accessibility services, by implementing the {@link android.view.accessibility.AccessibilityNodeProvider} class. For more information about making custom view components accessible, see <a href="{@docRoot}guide/topics/ui/accessibility/apps.html#custom-views">Making Applications Accessible</a>.</p> - -<h3 id="configure">Configure your development environment</h3> -<p>If you're developing in Eclipse, the Android SDK provides additional tools that help you write test cases using {@code uiautomator} and buiild your JAR file. In order to set up Eclipse to assist you, you need to create a project that includes the {@code uiautomator} client library, along with the Android SDK library. To configure Eclipse:</p> -<ol> -<li>Create a new Java project in Eclipse, and give your project a name that is relevant to the tests you’re about to create (for example, "MyAppNameTests"). In the project, you will create the test cases that are specific to the application that you want to test.</li> -<li>From the <strong>Project Explorer</strong>, right-click on the new project that you created, then select <strong>Properties > Java Build Path</strong>, and do the following: - <ol type="a"> - <LI>Click <strong>Add Library > JUnit</strong> then select <strong>JUnit3</strong> to add JUnit support.</LI> - <li>Click <strong>Add External JARs...</strong> and navigate to the SDK directory. Under the platforms directory, select the latest SDK version and add both the {@code uiautomator.jar} and {@code android.jar} files.</li> - </ol> -</li> -</ol> -<p>If you did not configure Eclipse as your development environment, make sure that the {@code uiautomator.jar} and {@code android.jar} files from the {@code <android-sdk>/platforms/<sdk>} directory are in your Java class path.</p> -<p>Once you have completed these prerequisite tasks, you're almost ready to start creating your {@code uiautomator} tests. </li> - -<h2 id="creating">Creating uiautomator Tests</h2> -<p>To build a test that runs in the {@code uiautomator} framework, create a test case that extends the <a href="{@docRoot}tools/help/uiautomator/UiAutomatorTestCase.html">{@code UiAutomatorTestCase}</a> class. In Eclipse, the test case file goes under the {@code src} directory in your project. Later, you will build the test case as a JAR file, then copy this file to the test device. The test JAR file is not an APK file and resides separately from the application that you want to test on the device.</p> - -<p>Because the <a href="{@docRoot}tools/help/uiautomator/UiAutomatorTestCase.html">{@code UiAutomatorTestCase}</a> class extends {@code junit.framework.TestCase}, you can use the JUnit {@code Assert} class to test that UI components in the app return the expected results. To learn more about JUnit, you can read the documentation on the <a href="http://www.junit.org/">junit.org</a> home page.</p> - -<p>The first thing your test case should do is access the device that contains the target app. It’s also good practice to start the test from the Home screen of the device. From the Home screen (or some other starting location you’ve chosen in the target app), you can use the classes provided by the {@code uiautomator} API to simulate user actions and to test specific UI components. For an example of how to put together a {@code uiautomator} test case, see the <a href="#sample">sample test case</a>.</p> - -<h3 id="classes">uiautomator API</h3> -<p>The {@code uiautomator} API is bundled in the {@code uiautomator.jar} file under the {@code <android-sdk>/platforms/} directory. The API includes these key classes that allow you to capture and manipulate UI components on the target app:</p> -<dl> -<DT><a href="{@docRoot}tools/help/uiautomator/UiDevice.html">{@code UiDevice}</a></DT> -<dd><p>Represents the device state. In your tests, you can call methods on the <a href="{@docRoot}tools/help/uiautomator/UiDevice.html">{@code UiDevice}</a> instance to check for the state of various properties, such as current orientation or display size. Your tests also can use the <a href="{@docRoot}tools/help/uiautomator/UiDevice.html">{@code UiDevice}</a> instance to perform device level actions, such as forcing the device into a specific rotation, pressing the d-pad hardware button, or pressing the Home and Menu buttons.</p> -<p>To get an instance of <a href="{@docRoot}tools/help/uiautomator/UiDevice.html">{@code UiDevice}</a> and simulate a Home button press: -<pre> -getUiDevice().pressHome(); -</pre></p></dd> - -<dt><a href="{@docRoot}tools/help/uiautomator/UiSelector.html">{@code UiSelector}</a></dt> -<dd>Represents a search criteria to query and get a handle on specific elements in the currently displayed UI. -If more than one matching element is found, the first matching element in the layout hierarchy is returned as the target {@code UiObject}. When constructing a <a href="{@docRoot}tools/help/uiautomator/UiSelector.html">{@code UiSelector}</a>, you can chain together multiple properties to refine your search. If no matching UI element is found, a <a href="{@docRoot}tools/help/uiautomator/UiAutomatorObjectNotFoundException.html">{@code UiAutomatorObjectNotFoundException}</a> is thrown. You can use the <a href="{@docRoot}tools/help/uiautomator/UiSelector.html#childSelector(com.android.uiautomator.core.UiSelector)">{@code childSelector()}</a> method to nest multiple <a href="{@docRoot}tools/help/uiautomator/UiSelector.html">{@code UiSelector}</a> instances. For example, the following code example shows how to specify a search to find the first {@link android.widget.ListView} in the currently displayed UI, then search within that {@link android.widget.ListView} to find a UI element with the text property {@code Apps}. -<pre> -UiObject appItem = new UiObject(new UiSelector() - .className("android.widget.ListView").instance(1) - .childSelector(new UiSelector().text("Apps"))); -</pre> -</dd> - -<dt><a href="{@docRoot}tools/help/uiautomator/UiObject.html">{@code UiObject}</a></dt> -<dd>Represents a UI element. To create a <a href="{@docRoot}tools/help/uiautomator/UiObject.html">{@code UiObject}</a> instance, use a {@code UiSelector} that describes how to search for, or select, the UI element. -<p>The following code example shows how to construct <a href="{@docRoot}tools/help/uiautomator/UiObject.html">{@code UiObject}</a> instances that represent a <strong>Cancel</strong> button and a <strong>OK</strong> button in your application.</p> -<pre> -UiObject cancelButton = new UiObject(new UiSelector().text("Cancel")); -UiObject okButton = new UiObject(new UiSelector().text("OK")); -</pre> -<p>You can reuse the <a href="{@docRoot}tools/help/uiautomator/UiObject.html">{@code UiObject}</a> instances that you have created in other parts of your app testing, as needed. Note that the {@code uiautomator} test framework searches the current display for a match every time your test uses a <a href="{@docRoot}tools/help/uiautomator/UiObject.html">{@code UiObject}</a> instance to click on a UI element or query a property.</p> -<p>In the following code example, the {@code uiautomator} test framework searches for a UI element with the text property {@code OK}. If a match is found and if the element is enabled, the framework simulates a user click action on the element.</p> -<pre> -if(okButton.exists() && okButton.isEnabled()) -{ - okButton.click(); -} -</pre> -<p>You can also restrict the search to find only elements of a specific class. For example, to find matches of the {@link android.widget.Button} class:</p> -<pre> -UiObject cancelButton = new UiObject(new UiSelector().text("Cancel") - .className("android.widget.Button")); -UiObject okButton = new UiObject(new UiSelector().text("OK") - .className("android.widget.Button")); -</pre> -</dd> - -<dt><a href="{@docRoot}tools/help/uiautomator/UiCollection.html">{@code UiCollection}</a></dt> -<dd>Represents a collection of items, for example songs in a music album or a list of emails in an inbox. Similar to a <a href="{@docRoot}tools/help/uiautomator/UiObject.html">{@code UiObject}</a>, you construct a <a href="{@docRoot}tools/help/uiautomator/UiCollection.html">{@code UiCollection}</a> instance by specifying a <a href="{@docRoot}tools/help/uiautomator/UiSelector.html">{@code UiSelector}</a>. The <a href="{@docRoot}tools/help/uiautomator/UiSelector.html">{@code UiSelector}</a> for a <a href="{@docRoot}tools/help/uiautomator/UiCollection.html">{@code UiCollection}</a> should search for a UI element that is a container or wrapper of other child UI elements (such as a layout view that contains child UI elements). For example, the following code snippet shows how to construct a <a href="{@docRoot}tools/help/uiautomator/UiCollection.html">{@code UiCollection}</a> to represent a video album that is displayed within a {@link android.widget.FrameLayout}: -<pre> -UiCollection videos = new UiCollection(new UiSelector() - .className("android.widget.FrameLayout")); -</pre> -<p>If the videos are listed within a {@link android.widget.LinearLayout} view, and you want to to retrieve the number of videos in this collection:</p> -<pre> -int count = videos.getChildCount(new UiSelector() - .className("android.widget.LinearLayout")); -</pre> -<p>If you want to find a specific video that is labeled with the text element {@code Cute Baby Laughing} from the collection and simulate a user-click on the video:</p> -<pre> -UiObject video = videos.getChildByText(new UiSelector() - .className("android.widget.LinearLayout"), "Cute Baby Laughing"); -video.click(); -</pre> -<p>Similarly, you can simulate other user actions on the UI object. For example, if you want -to simulate selecting a checkbox that is associated with the video:</p> -<pre> -UiObject checkBox = video.getChild(new UiSelector() - .className("android.widget.Checkbox")); -if(!checkBox.isSelected()) checkbox.click(); -</pre> -</dd> - -<dt><a href="{@docRoot}tools/help/uiautomator/UiScrollable.html">{@code UiScrollable}</a></dt> -<dd>Represents a scrollable collection of UI elements. You can use the <a href="{@docRoot}tools/help/uiautomator/UiScrollable.html">{@code UiScrollable}</a> class to simulate vertical or horizontal scrolling across a display. This technique is helpful when a UI element is positioned off-screen and you need to scroll to bring it into view. -<p>For example, the following code shows how to simulate scrolling down the Settings menu and clicking on an <strong>About tablet</strong> option:</p> -<pre> -UiScrollable settingsItem = new UiScrollable(new UiSelector() - .className("android.widget.ListView")); -UiObject about = settingsItem.getChildByText(new UiSelector() - .className("android.widget.LinearLayout"), "About tablet"); -about.click() -</pre> -</dd> -</dl> -<p>For more information about these APIs, see the <a href="{@docRoot}tools/help/uiautomator/index.html">{@code uiautomator}</a> reference.</p> - -<h3 id="sample">A sample uiautomator test case</h3> -<p>The following code example shows a simple test case which simulates a user bringing up the Settings app in a stock Android device. The test case mimics all the steps that a user would typically take to perform this task, including opening the Home screen, launching the <strong>All Apps</strong> screen, scrolling to the <strong>Settings</strong> app icon, and clicking on the icon to enter the Settings app.</p> -<pre> -package com.uia.example.my; - -// Import the uiautomator libraries -import com.android.uiautomator.core.UiObject; -import com.android.uiautomator.core.UiObjectNotFoundException; -import com.android.uiautomator.core.UiScrollable; -import com.android.uiautomator.core.UiSelector; -import com.android.uiautomator.testrunner.UiAutomatorTestCase; - -public class LaunchSettings extends UiAutomatorTestCase { - - public void testDemo() throws UiObjectNotFoundException { - - // Simulate a short press on the HOME button. - getUiDevice().pressHome(); - - // We’re now in the home screen. Next, we want to simulate - // a user bringing up the All Apps screen. - // If you use the uiautomatorviewer tool to capture a snapshot - // of the Home screen, notice that the All Apps button’s - // content-description property has the value “Apps”. We can - // use this property to create a UiSelector to find the button. - UiObject allAppsButton = new UiObject(new UiSelector() - .description("Apps")); - - // Simulate a click to bring up the All Apps screen. - allAppsButton.clickAndWaitForNewWindow(); - - // In the All Apps screen, the Settings app is located in - // the Apps tab. To simulate the user bringing up the Apps tab, - // we create a UiSelector to find a tab with the text - // label “Apps”. - UiObject appsTab = new UiObject(new UiSelector() - .text("Apps")); - - // Simulate a click to enter the Apps tab. - appsTab.click(); - - // Next, in the apps tabs, we can simulate a user swiping until - // they come to the Settings app icon. Since the container view - // is scrollable, we can use a UiScrollable object. - UiScrollable appViews = new UiScrollable(new UiSelector() - .scrollable(true)); - - // Set the swiping mode to horizontal (the default is vertical) - appViews.setAsHorizontalList(); - - // Create a UiSelector to find the Settings app and simulate - // a user click to launch the app. - UiObject settingsApp = appViews.getChildByText(new UiSelector() - .className(android.widget.TextView.class.getName()), - "Settings"); - settingsApp.clickAndWaitForNewWindow(); - - // Validate that the package name is the expected one - UiObject settingsValidation = new UiObject(new UiSelector() - .packageName("com.android.settings")); - assertTrue("Unable to detect Settings", - settingsValidation.exists()); - } -} -</pre> - -<h2 id="builddeploy">Building and Deploying Your uiautomator Tests</h2> -<p>Once you have coded your test, follow these steps to build and deploy your test JAR to your target Android test device:</p> -<ol> -<li>Create the required build configuration files to build the output JAR. To generate the build configuration files, open a terminal and run the following command: -<pre><android-sdk>/tools/android create uitest-project -n <name> -t 1 -p <path></pre> -The {@code <name>} is the name of the project that contains your {@code uiautomator} test source files, and the {@code <path>} is the path to the corresponding project directory. -</li> -<LI>From the command line, set the {@code ANDROID_HOME} variable: -<ul> -<li>In Windows: -<pre>set ANDROID_HOME=<path_to_your_sdk></pre> -</li> -<li>In UNIX: -<pre>export ANDROID_HOME=<path_to_your_sdk></pre> -</li> -</ul> -</LI> -<li>Go to the project directory where your {@code build.xml} file is located and build your test JAR. <pre>ant build</pre></li> -<li>Deploy your generated test JAR file to the test device by using the {@code adb push} command: <pre>adb push <path_to_output_jar> /data/local/tmp/</pre> -<p>Here’s an example: <pre>adb push ~/dev/workspace/LaunchSettings/bin/LaunchSettings.jar /data/local/tmp/</pre></p> -</li> -</ol> - -<h2 id="running">Running uiautomator Tests</h2> -<p>Here’s an example of how to run a test that is implemented in the {@code LaunchSettings.jar} file. The tests are bundled in the {@code com.uia.example.my} package:</p> -<pre>adb shell uiautomator runtest LaunchSettings.jar -c com.uia.example.my.LaunchSettings</pre> -<p>To learn more about the syntax, subcommands, and options for {@code uiautomator}, see the <a href="{@docRoot}tools/help/uiautomator/index.html">{@code uiautomator}</a> reference.</p> - - -<h2 id="bestpractices">Best Practices</h2> -<p>Here are some best practices for functional UI testing with the {@code uiautomator} framework: </p> -<ul> -<LI>Ensure that you validate the same UI functions on your application across the various types of devices that your application might run on (for example, devices with different screen densities).</LI> -<li>You should also test your UI against common scenarios such as in-coming phone calls, network interruptions, and user-initiated switching to other applications on the device.</li> -</ul> - diff --git a/docs/html/tools/testing/what_to_test.jd b/docs/html/tools/testing/what_to_test.jd deleted file mode 100644 index 77ae2114f3e2..000000000000 --- a/docs/html/tools/testing/what_to_test.jd +++ /dev/null @@ -1,86 +0,0 @@ -page.title=What To Test -parent.title=Testing -parent.link=index.html -@jd:body -<p> - As you develop Android applications, knowing what to test is as important as knowing how to - test. This document lists some most common Android-related situations that you should consider - when you test, even at the unit test level. This is not an exhaustive list, and you consult the - documentation for the features that you use for more ideas. The - <a href="http://groups.google.com/group/android-developers">android-developers</a> Google Groups - site is another resource for information about testing. -</p> -<h2 id="Tests">Ideas for Testing</h2> -<p> - The following sections are organized by behaviors or situations that you should test. Each - section contains a scenario that further illustrates the situation and the test or tests you - should do. -</p> -<h4>Change in orientation</h4> -<p> - For devices that support multiple orientations, Android detects a change in orientation when - the user turns the device so that the display is "landscape" (long edge is horizontal) instead - of "portrait" (long edge is vertical). -</p> -<p> - When Android detects a change in orientation, its default behavior is to destroy and then - re-start the foreground Activity. You should consider testing the following: -</p> -<ul> - <li> - Is the screen re-drawn correctly? Any custom UI code you have should handle changes in the - orientation. - </li> - <li> - Does the application maintain its state? The Activity should not lose anything that the - user has already entered into the UI. The application should not "forget" its place in the - current transaction. - </li> -</ul> -<h4>Change in configuration</h4> -<p> - A situation that is more general than a change in orientation is a change in the device's - configuration, such as a change in the availability of a keyboard or a change in system - language. -</p> -<p> - A change in configuration also triggers the default behavior of destroying and then restarting - the foreground Activity. Besides testing that the application maintains the UI and its - transaction state, you should also test that the application updates itself to respond - correctly to the new configuration. -</p> -<h4>Battery life</h4> -<p> - Mobile devices primarily run on battery power. A device has finite "battery budget", and when it - is gone, the device is useless until it is recharged. You need to write your application to - minimize battery usage, you need to test its battery performance, and you need to test the - methods that manage battery usage. -</p> -<p> - Techniques for minimizing battery usage were presented at the 2010 Google I/O conference in the - presentation - <a href="http://code.google.com/events/io/2009/sessions/CodingLifeBatteryLife.html"> - Coding for Life -- Battery Life, That Is</a>. This presentation describes the impact on battery - life of various operations, and the ways you can design your application to minimize these - impacts. When you code your application to reduce battery usage, you also write the - appropriate unit tests. -</p> -<h4>Dependence on external resources</h4> -<p> - If your application depends on network access, SMS, Bluetooth, or GPS, then you should - test what happens when the resource or resources are not available. -</p> -<p> - For example, if your application uses the network,it can notify the user if access is - unavailable, or disable network-related features, or do both. For GPS, it can switch to - IP-based location awareness. It can also wait for WiFi access before doing large data transfers, - since WiFi transfers maximize battery usage compared to transfers over 3G or EDGE. -</p> -<p> - You can use the emulator to test network access and bandwidth. To learn more, please see - <a href="{@docRoot}tools/help/emulator.html#netspeed">Network Speed Emulation</a>. - To test GPS, you can use the emulator console and {@link android.location.LocationManager}. To - learn more about the emulator console, please see - <a href="{@docRoot}tools/help/emulator.html#console"> - Using the Emulator Console</a>. -</p> diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs index f41184e024c6..04ed7057ede3 100644 --- a/docs/html/tools/tools_toc.cs +++ b/docs/html/tools/tools_toc.cs @@ -83,56 +83,11 @@ <li><a href="<?cs var:toroot ?>tools/building/building-studio.html"> <span class="en">From Android Studio</span></a></li> <li><a href="<?cs var:toroot ?>tools/building/building-cmdline.html"> - <span class="en">From the Command Line</span></a></li> + <span class="en">From the Command-Line</span></a></li> </ul> </li> - - <li class="nav-section"> - <div class="nav-section-header"><a href="<?cs var:toroot?>tools/testing/index.html"> - <span class="en">Testing</span> - </a></div> - <ul> - <li> - <a href="<?cs var:toroot?>tools/testing/testing_android.html"> - <span class="en">Fundamentals</span></a> - </li> - <li><a href="<?cs var:toroot ?>tools/testing/testing_eclipse.html"> - <span class="en">From Eclipse</span></a> - </li> - <li><a href="<?cs var:toroot ?>tools/testing/testing_otheride.html"> - <span class="en">From Other IDEs</span></a> - </li> - <li> - <a href="<?cs var:toroot?>tools/testing/activity_testing.html"> - <span class="en">Activity Testing</span></a> - </li> - <li> - <a href="<?cs var:toroot?>tools/testing/service_testing.html"> - <span class="en">Service Testing</span></a> - </li> - <li> - <a href="<?cs var:toroot?>tools/testing/contentprovider_testing.html"> - <span class="en">Content Provider Testing</span></a> - </li> - <li> - <a href="<?cs var:toroot?>tools/testing/testing_accessibility.html"> - <span class="en">Accessibility Testing</span></a> - </li> - <li> - <a href="<?cs var:toroot?>tools/testing/testing_ui.html"> - <span class="en">UI Testing</span></a> - </li> - <li> - <a href="<?cs var:toroot ?>tools/testing/what_to_test.html"> - <span class="en">What To Test</span></a> - </li> - <li> - <a href="<?cs var:toroot ?>tools/testing/activity_test.html"> - <span class="en">Activity Testing Tutorial</span></a> - </li> - </ul> - </li><!-- end of testing --> + <li><a href="<?cs var:toroot?>tools/testing/index.html"><span class="en">Testing</span></a></li> <li class="nav-section"> <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/debugging/index.html"><span class="en">Debugging</span></a></div> @@ -307,15 +262,23 @@ class="en">Tools Help</span></a></div> <!-- Testing Tools menu--> <li class="nav-section"> - <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/testing/testing-tools.html"><span class="en">Testing Tools</span></a></div> + <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/testing/testing-tools.html"> + <span class="en">Testing Tools</span></a></div> <ul> + <li><a href="<?cs var:toroot ?>tools/testing/testing_android.html">Testing Concepts</a></li> <li class="nav-section"> - <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/testing-support-library/index.html"><span + <div class="nav-section-header"> + <a href="<?cs var:toroot ?>tools/testing-support-library/index.html"><span class="en">Testing Support Library</span></a></div> <ul> - <li><a href="<?cs var:toroot ?>reference/android/support/test/package-summary.html">API Reference</a></li> + <li><a href="<?cs var:toroot ?>reference/android/support/test/package-summary.html"> + API Reference</a></li> </ul> </li> + <li><a href="<?cs var:toroot ?>training/testing/start/index.html"> + Testing with Android Studio</a></li> + <li><a href="<?cs var:toroot ?>tools/testing/testing_otheride.html"> + Testing from the Command-Line</a></li> <li><a href="<?cs var:toroot ?>tools/help/monkey.html">monkey</a></li> <li class="nav-section"> <div class="nav-section-header"><a href="<?cs var:toroot diff --git a/docs/html/training/accessibility/index.jd b/docs/html/training/accessibility/index.jd index ea54dc4406b6..7a5d6d7e6e9a 100644 --- a/docs/html/training/accessibility/index.jd +++ b/docs/html/training/accessibility/index.jd @@ -50,5 +50,7 @@ just your own.</p> and uses that information to communicate with the user. The example will use a text-to-speech engine to speak to the user.</dd> + <dt><b><a href="testing.html">Accessibility Checklist</a></b></dt> + <dd>Learn how to test your app for accessibility.</dd> </dl> diff --git a/docs/html/tools/testing/testing_accessibility.jd b/docs/html/training/accessibility/testing.jd index 20948fa2306f..6563f4eba571 100644 --- a/docs/html/tools/testing/testing_accessibility.jd +++ b/docs/html/training/accessibility/testing.jd @@ -1,11 +1,13 @@ page.title=Accessibility Testing Checklist -parent.title=Testing -parent.link=index.html +page.tags=testing,accessibility + +trainingnavtop=true +startpage=true @jd:body -<div id="qv-wrapper"> - <div id="qv"> - <h2>In this document</h2> +<div id="tb-wrapper"> + <div id="tb"> + <h2>Checklist sections</h2> <ol> <li><a href="#goals">Testing Goals</a></li> <li><a href="#requirements">Testing Requirements</a></li> @@ -20,7 +22,7 @@ parent.link=index.html </li> </ol> - <h2>See Also</h2> + <h2>You should also read</h2> <ol> <li> <a href="{@docRoot}guide/topics/ui/accessibility/checklist.html"> diff --git a/docs/html/training/activity-testing/activity-basic-testing.jd b/docs/html/training/activity-testing/activity-basic-testing.jd deleted file mode 100644 index 016289d94bdd..000000000000 --- a/docs/html/training/activity-testing/activity-basic-testing.jd +++ /dev/null @@ -1,227 +0,0 @@ -page.title=Creating and Running a Test Case -trainingnavtop=true - -@jd:body - -<!-- This is the training bar --> -<div id="tb-wrapper"> -<div id="tb"> - -<h2>This lesson teaches you to</h2> -<ol> - <li><a href="#testcase">Create a Test Case for Activity Testing</a> - <ol> - <li><a href="#fixture">Set Up Your Test Fixture</a></li> - <li><a href="#preconditions">Add Test Preconditions</a></li> - <li><a href="#test_method">Add Test Methods to Verify Your Activity</a></li> - </ol> - </li> - <li><a href="#build_run">Build and Run Your Test</a></li> -</ol> - -<h2>You should also read</h2> -<ul> -<li><a href="{@docRoot}tools/testing/testing_android.html">Testing -Fundamentals</a></li> -</ul> - -</div> -</div> -<p>In order to verify that there are no regressions in the layout design and -functional behavior in your application, it's important to -create a test for each {@link android.app.Activity} in your application. For -each test, you need to create the individual parts of a test case, including -the test fixture, preconditions test method, and {@link android.app.Activity} -test methods. You can then run your test to get a test report. If any test -method fails, this might indicate a potential defect in your code.</p> -<p class="note"><strong>Note:</strong> In the Test-Driven Development (TDD) -approach, instead of writing most or all of your app code up-front and then -running tests later in the development cycle, you would progressively write -just enough production code to satisfy your test dependencies, update your -test cases to reflect new functional requirements, and iterate repeatedly this -way.</p> - -<h2 id="testcase">Create a Test Case</h2> -<p>{@link android.app.Activity} tests are written in a structured way. -Make sure to put your tests in a separate package, distinct from the code under -test.</p> -<p>By convention, your test package name should follow the same name as the -application package, suffixed with <strong>".tests"</strong>. In the test package -you created, add the Java class for your test case. By convention, your test case -name should also follow the same name as the Java or Android class that you -want to test, but suffixed with <strong>“Test”</strong>.</p> -<p>To create a new test case in Eclipse:</p> -<ol type="a"> - <li>In the Package Explorer, right-click on the {@code /src} directory for -your test project and select <strong>New > Package</strong>.</li> - <li>Set the <strong>Name</strong> field to -{@code <your_app_package_name>.tests} (for example, -{@code com.example.android.testingfun.tests}) and click -<strong>Finish</strong>.</li> - <li>Right-click on the test package you created, and select -<strong>New > Class</strong>.</li> - <li>Set the <strong>Name</strong> field to -{@code <your_app_activity_name>Test} (for example, -{@code MyFirstTestActivityTest}) and click <strong>Finish</strong>.</li> -</ol> - -<h3 id="fixture">Set Up Your Test Fixture</h3> -<p>A <em>test fixture</em> consists of objects that must be initialized for -running one or more tests. To set up the test fixture, you can override the -{@link junit.framework.TestCase#setUp()} and -{@link junit.framework.TestCase#tearDown()} methods in your test. The -test runner automatically runs {@link junit.framework.TestCase#setUp()} before -running any other test methods, and {@link junit.framework.TestCase#tearDown()} -at the end of each test method execution. You can use these methods to keep -the code for test initialization and clean up separate from the tests methods. -</p> -<p>To set up your test fixture in Eclipse:</p> -<ol> -<li>In the Package Explorer, double-click on the test case that you created -earlier to bring up the Eclipse Java editor, then modify your test case class -to extend one of the sub-classes of {@link android.test.ActivityTestCase}. -<p>For example:</p> -<pre> -public class MyFirstTestActivityTest - extends ActivityInstrumentationTestCase2<MyFirstTestActivity> { -</pre> -</li> -<li>Next, add the constructor and {@link junit.framework.TestCase#setUp()} -methods to your test case, and add variable declarations for the -{@link android.app.Activity} that you want to test.</p> -<p>For example:</p> -<pre> -public class MyFirstTestActivityTest - extends ActivityInstrumentationTestCase2<MyFirstTestActivity> { - - private MyFirstTestActivity mFirstTestActivity; - private TextView mFirstTestText; - - public MyFirstTestActivityTest() { - super(MyFirstTestActivity.class); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - mFirstTestActivity = getActivity(); - mFirstTestText = - (TextView) mFirstTestActivity - .findViewById(R.id.my_first_test_text_view); - } -} -</pre> -<p>The constructor is invoked by the test runner to instantiate the test -class, while the {@link junit.framework.TestCase#setUp()} method is invoked by -the test runner before it runs any tests in the test class.</p> -</li> -</ol> - -<p>Typically, in the {@link junit.framework.TestCase#setUp()} method, you -should:</p> -<ul> -<li>Invoke the superclass constructor for -{@link junit.framework.TestCase#setUp()}, which is required by JUnit.</li> -<li>Initialize your test fixture state by: - <ul> - <li>Defining the instance variables that store the state of the fixture.</li> - <li>Creating and storing a reference to an instance of the -{@link android.app.Activity} under test.</li> - <li>Obtaining a reference to any UI components in the -{@link android.app.Activity} that you want to test.</li> - </ul> -</ul> - -<p>You can use the -{@link android.test.ActivityInstrumentationTestCase2#getActivity()} method to -get a reference to the {@link android.app.Activity} under test.</p> - -<h3 id="preconditions">Add Test Preconditions</h3> -<p>As a sanity check, it is good practice to verify that the test fixture has -been set up correctly, and the objects that you want to test have been correctly -instantiated or initialized. That way, you won’t have to see -tests failing because something was wrong with the setup of your test fixture. -By convention, the method for verifying your test fixture is called -{@code testPreconditions()}.</p> - -<p>For example, you might want to add a {@code testPreconditons()} method like -this to your test case:</p> - -<pre> -public void testPreconditions() { - assertNotNull(“mFirstTestActivity is null”, mFirstTestActivity); - assertNotNull(“mFirstTestText is null”, mFirstTestText); -} -</pre> - -<p>The assertion methods are from the JUnit {@link junit.framework.Assert} -class. Generally, you can use assertions to -verify if a specific condition that you want to test is true. -<ul> -<li>If the condition is false, the assertion method throws an -{@link android.test.AssertionFailedError} exception, which is then typically -reported by the test runner. You can provide a string in the first argument of -your assertion method to give some contextual details if the assertion fails.</li> -<li>If the condition is true, the test passes.</li> -</ul> -<p>In both cases, the test runner proceeds to run the other test methods in the -test case.</p> - -<h3 id="test_method">Add Test Methods to Verify Your Activity</h3> -<p>Next, add one or more test methods to verify the layout and functional -behavior of your {@link android.app.Activity}.</p> -<p>For example, if your {@link android.app.Activity} includes a -{@link android.widget.TextView}, you can add a test method like this to check -that it has the correct label text:</p> -<pre> -public void testMyFirstTestTextView_labelText() { - final String expected = - mFirstTestActivity.getString(R.string.my_first_test); - final String actual = mFirstTestText.getText().toString(); - assertEquals(expected, actual); -} -</pre> - -<p>The {@code testMyFirstTestTextView_labelText()} method simply checks that the -default text of the {@link android.widget.TextView} that is set by the layout -is the same as the expected text defined in the {@code strings.xml} resource.</p> -<p class="note"><strong>Note:</strong> When naming test methods, you can use -an underscore to separate what is being tested from the specific case being -tested. This style makes it easier to see exactly what cases are being tested.</p> -<p>When doing this type of string value comparison, it’s good practice to read -the expected string from your resources, instead of hardcoding the string in -your comparison code. This prevents your test from easily breaking whenever the -string definitions are modified in the resource file.</p> -<p>To perform the comparison, pass both the expected and actual strings as -arguments to the -{@link junit.framework.Assert#assertEquals(java.lang.String, java.lang.String) assertEquals()} -method. If the values are not the same, the assertion will throw an -{@link junit.framework.AssertionFailedError} exception.</p> -<p>If you added a {@code testPreconditions()} method, put your test methods -after the {@code testPreconditions()} definition in your Java class.</p> -<p>For a complete test case example, take a look at -{@code MyFirstTestActivityTest.java} in the sample app.</p> - -<h2 id="build_run">Build and Run Your Test</h2> -<p>You can build and run your test easily from the Package Explorer in -Eclipse.</p> -<p>To build and run your test:</p> -<ol> -<li>Connect an Android device to your machine. On the device or emulator, open -the <strong>Settings</strong> menu, select <strong>Developer options</strong> -and make sure that USB debugging is enabled.</li> -<li>In the Project Explorer, right-click on the test class that you created -earlier and select <strong>Run As > Android Junit Test</strong>.</li> -<li>In the Android Device Chooser dialog, select the device that you just -connected, then click <strong>OK</strong>.</li> -<li>In the JUnit view, verify that the test passes with no errors or failures.</li> -</ol> -<p>For example, if the test case passes with no errors, the result should look -like this:</p> -<img src="{@docRoot}images/training/activity-testing_lesson2_MyFirstTestActivityTest_result.png" alt="" /> -<p class="img-caption"> - <strong>Figure 1.</strong> Result of a test with no errors. -</p> - - - diff --git a/docs/html/training/activity-testing/activity-functional-testing.jd b/docs/html/training/activity-testing/activity-functional-testing.jd deleted file mode 100644 index 7c8ff1d7bdd7..000000000000 --- a/docs/html/training/activity-testing/activity-functional-testing.jd +++ /dev/null @@ -1,166 +0,0 @@ -page.title=Creating Functional Tests -trainingnavtop=true -@jd:body - -<!-- This is the training bar --> -<div id="tb-wrapper"> -<div id="tb"> - -<h2>This lesson teaches you to</h2> -<ol> - <li><a href="#test_methods">Add Test Method to Validate Functional Behavior</a> - <ol> - <li><a href="#activitymonitor">Set Up an ActivityMonitor</a></li> - <li><a href="#keyinput">Send Keyboard Input Using Instrumentation</a></li> - </ol> - </li> -</ol> - -<h2>Try it out</h2> -<div class="download-box"> - <a href="http://developer.android.com/shareables/training/AndroidTestingFun.zip" -class="button">Download the demo</a> - <p class="filename">AndroidTestingFun.zip</p> -</div> - -</div> -</div> -<p>Functional testing involves verifying that individual application -components work together as expected by the user. For example, you can create a -functional test to verify that an {@link android.app.Activity} correctly -launches a target {@link android.app.Activity} when the user performs a UI -interaction.</p> - -<p>To create a functional test for your {@link android.app.Activity}, your test -class should extend {@link android.test.ActivityInstrumentationTestCase2}. -Unlike {@link android.test.ActivityUnitTestCase}, -tests in {@link android.test.ActivityInstrumentationTestCase2} can -communicate with the Android system and send keyboard input and click events to -the UI.</p> - -<p>For a complete test case example, take a look at -{@code SenderActivityTest.java} in the sample app.</p> - -<h2 id="test_methods">Add Test Method to Validate Functional Behavior</h2> -<p id="test_goals">Your functional testing goals might include:</p> -<ul> -<li>Verifying that a target {@link android.app.Activity} is started when a -UI control is pushed in the sender {@link android.app.Activity}.</li> -<li>Verifying that the target {@link android.app.Activity} displays the -correct data based on the user's input in the sender -{@link android.app.Activity}.</li> -</ul> -<p>You might implement your test method like this:</p> - -<pre> -@MediumTest -public void testSendMessageToReceiverActivity() { - final Button sendToReceiverButton = (Button) - mSenderActivity.findViewById(R.id.send_message_button); - - final EditText senderMessageEditText = (EditText) - mSenderActivity.findViewById(R.id.message_input_edit_text); - - // Set up an ActivityMonitor - ... - - // Send string input value - ... - - // Validate that ReceiverActivity is started - ... - - // Validate that ReceiverActivity has the correct data - ... - - // Remove the ActivityMonitor - ... -} -</pre> -<p>The test waits for an {@link android.app.Activity} that matches this monitor, -otherwise returns null after a timeout elapses. If {@code ReceiverActivity} was -started, the {@link android.app.Instrumentation.ActivityMonitor ActivityMonitor} -that you set -up earlier receives a hit. You can use the assertion methods to verify that -the {@code ReceiverActivity} is indeed started, and that the hit count on the -{@link android.app.Instrumentation.ActivityMonitor ActivityMonitor} incremented -as expected.</p> - -<h2 id="activitymonitor">Set up an ActivityMonitor</h2> -<p>To monitor a single {@link android.app.Activity} in your application, you -can register an {@link android.app.Instrumentation.ActivityMonitor ActivityMonitor}. -The {@link android.app.Instrumentation.ActivityMonitor ActivityMonitor} is -notified by the system whenever an {@link android.app.Activity} that matches your criteria is started. -If a match is found, the monitor’s hit count is updated.</p> -<p>Generally, to use an -{@link android.app.Instrumentation.ActivityMonitor ActivityMonitor}, you should:</p> -<ol> -<li>Retrieve the {@link android.app.Instrumentation} instance for your test -case by using the -{@link android.test.InstrumentationTestCase#getInstrumentation()} method.</li> -<li>Add an instance of {@link android.app.Instrumentation.ActivityMonitor} to -the current instrumentation using one of the {@link android.app.Instrumentation} -{@code addMonitor()} methods. The match criteria can be specified as an -{@link android.content.IntentFilter} or a class name string.</li> -<li>Wait for the {@link android.app.Activity} to start.</li> -<li>Verify that the monitor hits were incremented.</li> -<li>Remove the monitor.</li> -</ol> -<p>For example:</p> -<pre> -// Set up an ActivityMonitor -ActivityMonitor receiverActivityMonitor = - getInstrumentation().addMonitor(ReceiverActivity.class.getName(), - null, false); - -// Validate that ReceiverActivity is started -TouchUtils.clickView(this, sendToReceiverButton); -ReceiverActivity receiverActivity = (ReceiverActivity) - receiverActivityMonitor.waitForActivityWithTimeout(TIMEOUT_IN_MS); -assertNotNull("ReceiverActivity is null", receiverActivity); -assertEquals("Monitor for ReceiverActivity has not been called", - 1, receiverActivityMonitor.getHits()); -assertEquals("Activity is of wrong type", - ReceiverActivity.class, receiverActivity.getClass()); - -// Remove the ActivityMonitor -getInstrumentation().removeMonitor(receiverActivityMonitor); -</pre> - -<h2 id="keyinput">Send Keyboard Input Using Instrumentation</h2> -<p>If your {@link android.app.Activity} has an {@link android.widget.EditText} -field, you might want to test that users can enter values into the -{@link android.widget.EditText} object.</p> -<p>Generally, to send a string input value to an {@link android.widget.EditText} -object in {@link android.test.ActivityInstrumentationTestCase2}, you should:</p> -<ol> -<li>Use the {@link android.app.Instrumentation#runOnMainSync(java.lang.Runnable) runOnMainSync()} -method to run the {@link android.view.View#requestFocus()} call synchronously -in a loop. This way, the UI thread is blocked until focus is received.</li> -<li>Call {@link android.app.Instrumentation#waitForIdleSync()} method to wait -for the main thread to become idle (that is, have no more events to process).</li> -<li>Send a text string to the {@link android.widget.EditText} by calling -{@link android.app.Instrumentation#sendStringSync(java.lang.String) -sendStringSync()} and pass your input string as the parameter.</p> -</ol> -<p>For example:</p> -<pre> -// Send string input value -getInstrumentation().runOnMainSync(new Runnable() { - @Override - public void run() { - senderMessageEditText.requestFocus(); - } -}); -getInstrumentation().waitForIdleSync(); -getInstrumentation().sendStringSync("Hello Android!"); -getInstrumentation().waitForIdleSync(); -</pre> - - - - - - - - diff --git a/docs/html/training/activity-testing/activity-ui-testing.jd b/docs/html/training/activity-testing/activity-ui-testing.jd deleted file mode 100644 index 644f3ca51513..000000000000 --- a/docs/html/training/activity-testing/activity-ui-testing.jd +++ /dev/null @@ -1,216 +0,0 @@ -page.title=Testing UI Components -trainingnavtop=true - -@jd:body - -<!-- This is the training bar --> -<div id="tb-wrapper"> -<div id="tb"> - -<h2>This lesson teaches you to</h2> -<ol> - <li><a href="#testcase">Create a Test Case for UI Testing with Instrumentation</a> - <li><a href="#test_method">Add Test Methods to Verify UI Behavior</a> - <ol> - <li><a href="#verify_button_display">Verify Button Layout Parameters</a></li> - <li><a href="#verify_TextView">Verify TextView Layout Parameters</a></li> - <li><a href="#verify_button_behavior">Verify Button Behavior</a></li> - </ol> - </li> - <li><a href="#annotations">Apply Test Annotations</a></li> -</ol> - -<h2>Try it out</h2> -<div class="download-box"> - <a href="http://developer.android.com/shareables/training/AndroidTestingFun.zip" -class="button">Download the demo</a> - <p class="filename">AndroidTestingFun.zip</p> -</div> - -</div> -</div> - -<p>Typically, your {@link android.app.Activity} includes user interface -components (such as buttons, editable text fields, checkboxes, and pickers) to -allow users to interact with your Android application. This lesson shows how -you can test an {@link android.app.Activity} with a simple push-button UI. You -can use the same general steps to test other, more sophisticated types of UI -components.</p> - -<p class="note"><strong>Note:</strong> The type of UI testing in this lesson is -called <em>white-box testing</em> because you have the -source code for the application that you want to test. The Android -<a href="{@docRoot}tools/testing/testing_android.html#Instrumentation">Instrumentation</a> -framework is suitable for creating white-box tests for UI components within an -application. An alternative type of UI testing is <em>black-box testing</em>, -where you may not have access to the application source. This type of testing -is useful when you want to test how your app interacts with other apps or with -the system. Black-box testing is not covered in this training. To learn more -about how to perform black-box testing on your Android apps, see the -<a href="{@docRoot}tools/testing/testing_ui.html">UI Testing guide</a>. -<p>For a complete test case example, take a look at -{@code ClickFunActivityTest.java} in the sample app.</p> - -<h2 id="testcase">Create a Test Case for UI Testing with Instrumentation</h2> -<p>When testing an {@link android.app.Activity} that has a user interface (UI), -the {@link android.app.Activity} under test runs in the UI thread. However, the -test application itself runs in a separate thread in the same process as the -application under test. This means that your test app can reference objects -from the UI thread, but if it attempts to change properties on those objects or -send events to the UI thread, you will usually get a {@code WrongThreadException} -error.</p> -<p>To safely inject {@link android.content.Intent} objects into your -{@link android.app.Activity} or run test methods on the UI thread, you can -extend your test class to use {@link android.test.ActivityInstrumentationTestCase2}. -To learn more about how to run test methods on the UI thread, see -<a href="{@docRoot}tools/testing/activity_testing.html#RunOnUIThread">Testing -on the UI thread</a>.</p> - -<h3 id="fixture">Set Up Your Test Fixture</h3> -<p>When setting up the test fixture for UI testing, you should specify the -<a href="{@docRoot}guide/topics/ui/ui-events.html#TouchMode">touch mode</a> -in your {@link junit.framework.TestCase#setUp()} method. Setting the touch mode -to {@code true} prevents the UI control from taking focus when you click it -programmatically in the test method later (for example, a button UI will just -fire its on-click listener). Make sure that you call -{@link android.test.ActivityInstrumentationTestCase2#setActivityInitialTouchMode(boolean) setActivityInitialTouchMode()} -before calling {@link android.test.ActivityInstrumentationTestCase2#getActivity()}. -</p> -<p>For example:</ap> -<pre> -public class ClickFunActivityTest - extends ActivityInstrumentationTestCase2<ClickFunActivity> { - ... - @Override - protected void setUp() throws Exception { - super.setUp(); - - setActivityInitialTouchMode(true); - - mClickFunActivity = getActivity(); - mClickMeButton = (Button) - mClickFunActivity - .findViewById(R.id.launch_next_activity_button); - mInfoTextView = (TextView) - mClickFunActivity.findViewById(R.id.info_text_view); - } -} -</pre> - -<h2 id="test_methods">Add Test Methods to Validate UI Behavior</h2> -<p id="test_goals">Your UI testing goals might include:</p> -<ul> -<li>Verifying that a button is displayed with the correct layout when the -{@link android.app.Activity} is launched.</li> -<li>Verifying that a {@link android.widget.TextView} is initially hidden.</li> -<li>Verifying that a {@link android.widget.TextView} displays the expected string -when a button is pushed.</li> -</ul> -<p>The following section demonstrates how you can implement test methods -to perform these verifications.</p> - -<h3 id="verify_button_display">Verify Button Layout Parameters</h3> -<p>You might add a test method like this to verify that a button is displayed -correctly in your {@link android.app.Activity}:</p> -<pre> -@MediumTest -public void testClickMeButton_layout() { - final View decorView = mClickFunActivity.getWindow().getDecorView(); - - ViewAsserts.assertOnScreen(decorView, mClickMeButton); - - final ViewGroup.LayoutParams layoutParams = - mClickMeButton.getLayoutParams(); - assertNotNull(layoutParams); - assertEquals(layoutParams.width, WindowManager.LayoutParams.MATCH_PARENT); - assertEquals(layoutParams.height, WindowManager.LayoutParams.WRAP_CONTENT); -} -</pre> - -<p>In the {@link android.test.ViewAsserts#assertOnScreen(android.view.View,android.view.View) assertOnScreen()} -method call, you should pass in the root view and the view that you are -expecting to be present on the screen. If the expected view is not found in the -root view, the assertion method throws an {@link junit.framework.AssertionFailedError} -exception, otherwise the test passes.</p> -<p>You can also verify that the layout of a {@link android.widget.Button} is -correct by getting a reference to its {@link android.view.ViewGroup.LayoutParams} -object, then call assertion methods to verify that the -{@link android.widget.Button} object's width and height attributes match the -expected values.</p> -<p>The {@code @MediumTest} annotation specifies how the test is categorized, -relative to its absolute execution time. To learn more about using test size -annotations, see <a href="#annotations">Apply Test Annotations</a>.</p> - -<h3 id="verify_TextView">Verify TextView Layout Parameters</h3> -<p>You might add a test method like this to verify that a -{@link android.widget.TextView} initially appears hidden in -your {@link android.app.Activity}:</p> -<pre> -@MediumTest -public void testInfoTextView_layout() { - final View decorView = mClickFunActivity.getWindow().getDecorView(); - ViewAsserts.assertOnScreen(decorView, mInfoTextView); - assertTrue(View.GONE == mInfoTextView.getVisibility()); -} -</pre> -<p>You can call {@link android.view.Window#getDecorView()} to get a reference -to the decor view for the {@link android.app.Activity}. The decor view is the -top-level ViewGroup ({@link android.widget.FrameLayout}) view in the layout -hierarchy.</p> - -<h3 id="verify_button_behavior">Verify Button Behavior</h3> -<p>You can use a test method like this to verify that a -{@link android.widget.TextView} becomes visible when a -{@link android.widget.Button} is pushed:</p> - -<pre> -@MediumTest -public void testClickMeButton_clickButtonAndExpectInfoText() { - String expectedInfoText = mClickFunActivity.getString(R.string.info_text); - TouchUtils.clickView(this, mClickMeButton); - assertTrue(View.VISIBLE == mInfoTextView.getVisibility()); - assertEquals(expectedInfoText, mInfoTextView.getText()); -} -</pre> - -<p>To programmatically click a {@link android.widget.Button} in your -test, call {@link android.test.TouchUtils#clickView(android.test.InstrumentationTestCase,android.view.View) clickView()}. -You must pass in a reference to the test case that is being run and a reference -to the {@link android.widget.Button} to manipulate.</p> - -<p class="note"><strong>Note: </strong>The {@link android.test.TouchUtils} -helper class provides convenience methods for simulating touch interactions -with your application. You can use these methods to simulate clicking, tapping, -and dragging of Views or the application screen.</p> -<p class="caution"><strong>Caution: </strong>The {@link android.test.TouchUtils} -methods are designed to send events to the UI thread safely from the test thread. -You should not run {@link android.test.TouchUtils} directly in the UI thread or -any test method annotated with {@code @UIThread}. Doing so might -raise the {@code WrongThreadException}.</p> - -<h2 id="annotations">Apply Test Annotations</h2> -<p>The following annotations can be applied to indicate the size of a test -method:</p> -<dl> -<dt>{@link -android.test.suitebuilder.annotation.SmallTest @SmallTest}</dt> -<dd>Marks a test that should run as part of the small tests.</dd> -<dt>{@link -android.test.suitebuilder.annotation.MediumTest @MediumTest}</dt> -<dd>Marks a test that should run as part of the medium tests.</dd> -<dt>{@link android.test.suitebuilder.annotation.LargeTest @LargeTest}</dt> -<dd>Marks a test that should run as part of the large tests.</dd> -</dl> -<p>Typically, a short running test that take only a few milliseconds should be -marked as a {@code @SmallTest}. Longer running tests (100 milliseconds or -more) are usually marked as {@code @MediumTest}s or {@code @LargeTest}s, -depending on whether the test accesses resources on the local system only or -remote resources over a network. For guidance on using test size annotations, -see this <a href="https://plus.sandbox.google.com/+AndroidDevelopers/posts/TPy1EeSaSg8">Android Tools Protip</a>.</p> -<p>You can mark up your test methods with other test annotations to control -how the tests are organized and run. For more information on other annotations, -see the {@link java.lang.annotation.Annotation} class reference.</p> - - - - diff --git a/docs/html/training/activity-testing/activity-unit-testing.jd b/docs/html/training/activity-testing/activity-unit-testing.jd deleted file mode 100644 index 74dcda90b18d..000000000000 --- a/docs/html/training/activity-testing/activity-unit-testing.jd +++ /dev/null @@ -1,134 +0,0 @@ -page.title=Creating Unit Tests -trainingnavtop=true -@jd:body - -<!-- This is the training bar --> -<div id="tb-wrapper"> -<div id="tb"> - -<h2>This lesson teaches you to</h2> -<ol> - <li><a href="#testcase">Create a Test Case for Activity Unit Testing</a> - <li><a href="#test_method">Validate Launch of Another Activity</a> -</ol> - -<h2>Try it out</h2> -<div class="download-box"> - <a href="http://developer.android.com/shareables/training/AndroidTestingFun.zip" -class="button">Download the demo</a> - <p class="filename">AndroidTestingFun.zip</p> -</div> - -</div> -</div> - -<p>An {@link android.app.Activity} unit test is an excellent way to quickly -verify the state of an {@link android.app.Activity} and its interactions with -other components in isolation (that is, disconnected from the rest of the -system). A unit test generally tests the smallest possible unit of code -(which could be a method, class, or component), without dependencies on system -or network resources. For example, you can write a unit test to check -that an {@link android.app.Activity} has the correct layout or that it -triggers an {@link android.content.Intent} object correctly.</p> -<p>Unit tests are generally not suitable for testing complex UI interaction -events with the system. Instead, you should use -the {@link android.test.ActivityInstrumentationTestCase2} class, as described -in <a href="activity-ui-testing.html">Testing UI Components</a>.</p> -<p>This lesson shows how you can write a unit test to verify that an -{@link android.content.Intent} is triggered to launch another -{@link android.app.Activity}. -Since the test runs in an isolated environment, the -{@link android.content.Intent} -is not actually sent to the Android system, but you can inspect that the -{@link android.content.Intent} object's payload data is accurate.</p> -<p>For a complete test case example, take a look at -{@code LaunchActivityTest.java} in the sample app.</p> - -<p class="note"><strong>Note: </strong>To test against system or external -dependencies, you can use mock objects from a mocking -framework and inject them into your unit tests. To learn more about the mocking -framework provided by Android, see -<a href="{@docRoot}tools/testing/testing_android.html#MockObjectClasses}">Mock -Object Classes</a>.</p> - -<h2 id="testcase">Create a Test Case for Activity Unit Testing</h2> -<p>The {@link android.test.ActivityUnitTestCase} class provides support for -isolated testing of a single {@link android.app.Activity}. To create a unit -test for your {@link android.app.Activity}, your test class should extend -{@link android.test.ActivityUnitTestCase}.</p> - -<p>The {@link android.app.Activity} in an {@link android.test.ActivityUnitTestCase} -is not automatically started by Android Instrumentation. To start the -{@link android.app.Activity} in isolation, you need to explicitly call the -{@link android.test.ActivityUnitTestCase#startActivity(android.content.Intent, android.os.Bundle, java.lang.Object) startActivity()} -method, and pass in the {@link android.content.Intent} to -launch your target {@link android.app.Activity}.</p> - -<p>For example:</p> -<pre> -public class LaunchActivityTest - extends ActivityUnitTestCase<LaunchActivity> { - ... - - @Override - protected void setUp() throws Exception { - super.setUp(); - mLaunchIntent = new Intent(getInstrumentation() - .getTargetContext(), LaunchActivity.class); - startActivity(mLaunchIntent, null, null); - final Button launchNextButton = - (Button) getActivity() - .findViewById(R.id.launch_next_activity_button); - } -} -</pre> - -<h2 id="test_method">Validate Launch of Another Activity</h2> -<p id="test_goals">Your unit testing goals might include:</p> -<ul> -<li>Verifying that {@code LaunchActivity} fires an -{@link android.content.Intent} when a button is pushed clicked.</li> -<li>Verifying that the launched {@link android.content.Intent} contains the -correct payload data.</li> -</ul> - -<p>To verify if an {@link android.content.Intent} was triggered -following the {@link android.widget.Button} click, you can use the -{@link android.test.ActivityUnitTestCase#getStartedActivityIntent()} method. -By using assertion methods, you can verify that the returned -{@link android.content.Intent} is not null, and that it contains the expected -string value to launch the next {@link android.app.Activity}. If both assertions -evaluate to {@code true}, you've successfully verified that the -{@link android.content.Intent} was correctly sent by your -{@link android.app.Activity}.</p> - -<p>You might implement your test method like this:</p> -<pre> -@MediumTest -public void testNextActivityWasLaunchedWithIntent() { - startActivity(mLaunchIntent, null, null); - final Button launchNextButton = - (Button) getActivity() - .findViewById(R.id.launch_next_activity_button); - launchNextButton.performClick(); - - final Intent launchIntent = getStartedActivityIntent(); - assertNotNull("Intent was null", launchIntent); - assertTrue(isFinishCalled()); - - final String payload = - launchIntent.getStringExtra(NextActivity.EXTRAS_PAYLOAD_KEY); - assertEquals("Payload is empty", LaunchActivity.STRING_PAYLOAD, payload); -} -</pre> -<p>Because {@code LaunchActivity} runs in isolation, you cannot use the -{@link android.test.TouchUtils} library to manipulate UI controls. To directly -click a {@link android.widget.Button}, you can call the -{@link android.view.View#performClick()} method instead.</p> - - - - - - - diff --git a/docs/html/training/activity-testing/index.jd b/docs/html/training/activity-testing/index.jd deleted file mode 100644 index efa67a2a1935..000000000000 --- a/docs/html/training/activity-testing/index.jd +++ /dev/null @@ -1,68 +0,0 @@ -page.title=Testing Your Android Activity -page.tags=testing - -trainingnavtop=true -startpage=true - -@jd:body - -<div id="tb-wrapper"> -<div id="tb"> - -<!-- Required platform, tools, add-ons, devices, knowledge, etc. --> -<h2>Dependencies and prerequisites</h2> -<ul> - <li>Android 2.2 (API Level 8) or higher.</li> -</ul> - -<h2>You Should Also Read</h2> -<ul> -<li><a href="{@docRoot}tools/testing/index.html">Testing -(Developer's Guide)</a></li> -</ul> - -</div> -</div> - -<p>You should be writing and running tests as part of your Android application -development cycle. Well-written tests can help you to catch bugs early in -development and give you confidence in your code.</p> - -<p>A <em>test case</em> defines a set of objects and methods to run multiple -tests independently from each other. Test cases can be organized into -<em>test suites</em> and run programmatically, in a repeatable manner, with -a <em>test runner</em> provided by a testing framework.</p> - -<p>The lessons in this class teaches you how to use the Android's custom -testing framework that is based on the popular JUnit framework. You can -write test cases to verify specific behavior in your application, and check for -consistency across different Android devices. Your test cases also serve as a -form of internal code documentation by describing the expected behavior of -app components.</p> - -<h2>Lessons</h2> - -<!-- Create a list of the lessons in this class along with a short description -of each lesson. These should be short and to the point. It should be clear from -reading the summary whether someone will want to jump to a lesson or not.--> - -<dl> - <dt><b><a href="preparing-activity-testing.html">Setting Up Your Test -Environment</a></b></dt> - <dd>Learn how to create your test project.</dd> - <dt><b><a href="activity-basic-testing.html">Creating and Running a Test -Case</a></b></dt> - <dd>Learn how to write test cases to verify the -expected properties of your {@link android.app.Activity}, and run the test -cases with the {@code Instrumentation} test runner provided by the Android -framework.</dd> - <dt><b><a href="activity-ui-testing.html">Testing UI Components</a></b></dt> - <dd>Learn how to test the behavior of specific UI -components in your {@link android.app.Activity}.</dd> - <dt><b><a href="activity-unit-testing.html">Creating Unit Tests</a></b></dt> - <dd>Learn how to perform unit testing to -verify the behavior of an Activity in isolation.</dd> - <dt><b><a href="activity-functional-testing.html">Creating Functional Tests</a></b></dt> - <dd>Learn how to perform functional testing to -verify the interaction of multiple Activities.</dd> - diff --git a/docs/html/training/activity-testing/preparing-activity-testing.jd b/docs/html/training/activity-testing/preparing-activity-testing.jd deleted file mode 100644 index c43c9ed4a304..000000000000 --- a/docs/html/training/activity-testing/preparing-activity-testing.jd +++ /dev/null @@ -1,95 +0,0 @@ -page.title=Setting Up Your Test Environment -trainingnavtop=true - -@jd:body - -<!-- This is the training bar --> -<div id="tb-wrapper"> -<div id="tb"> - -<h2>This lesson teaches you to</h2> -<ol> - <li><a href="#eclipse">Set Up Eclipse for Testing</a></li> - <li><a href="#cmdline">Set Up the Command Line Interface for Testing</a></li> -</ol> - -<h2>You should also read</h2> -<ul> -<li><a href="{@docRoot}sdk/index.html">Getting the SDK Bundle</a></li> -<li><a href="{@docRoot}tools/testing/testing_eclipse.html">Testing from Eclipse -with ADT</a></li> -<li><a href="{@docRoot}tools/testing/testing_otheride.html">Testing from Other -IDEs</a></li> -</ul> - -<h2>Try it out</h2> -<div class="download-box"> - <a href="http://developer.android.com/shareables/training/AndroidTestingFun.zip" -class="button">Download the demo</a> - <p class="filename">AndroidTestingFun.zip</p> -</div> - -</div> -</div> - -<p>Before you start writing and running your tests, you should set up your test -development environment. This lesson teaches you how to set up the Eclipse -IDE to build and run tests, and how to -build and run tests with the Gradle framework by using the command line -interface.</p> - -<p class="note"><strong>Note:</strong> To help you get started, the lessons are -based on Eclipse with the ADT plugin. However, for your own test development, you -are free to use the IDE of your choice or the command-line.</p> - -<h2 id="eclipse">Set Up Eclipse for Testing</h2> -<p>Eclipse with the Android Developer Tools (ADT) plugin provides an integrated -development environment for you to create, build, and run Android application -test cases from a graphical user interface (GUI). A convenient feature that -Eclipse provides is the ability to auto-generate a new test project that -corresponds with your Android application project</a>. - -<p>To set up your test environment in Eclipse:</p> - -<ol> -<li><a href="{@docRoot}sdk/installing/bundle.html">Download and install the -Eclipse ADT plugin</a>, if you haven’t installed it yet.</li> -<li>Import or create the Android application project that you want to test -against.</li> -<li>Generate a test project that corresponds to the application project under -test. To generate a test project for the app project that you imported:</p> - <ol type="a"> - <li>In the Package Explorer, right-click on your app project, then -select <strong>Android Tools</strong> > <strong>New Test Project</strong>.</li> - <li>In the New Android Test Project wizard, set the property -values for your test project then click <strong>Finish</strong>.</li> - </ol> -</li> -</ol> -<p>You should now be able to create, build, and run test -cases from your Eclipse environment. To learn how to perform these tasks in -Eclipse, proceed to <a href="activity-basic-testing.html">Creating and Running -a Test Case</a>.</p> - -<h2 id="cmdline">Set Up the Command Line Interface for Testing</h2> -<p>If you are using Gradle version 1.6 or higher as your build environment, you -can build and run your Android application tests from the command line by using -the Gradle Wrapper. Make sure that in your {@code gradle.build} file, the -<a href={@docRoot}guide/topics/manifest/uses-sdk-element.html#min>minSdkVersion</a> -attribute in the {@code defaultConfig} section is set to 8 or higher. You can -refer to the sample {@code gradle.build} file that is -included in the download bundle for this training class.</p> -<p>To run your tests with the Gradle Wrapper:</p> -<ol> - <li>Connect a physical Android device to your machine or launch the Android -Emulator.</li> - <li>Run the following command from your project directory: - <pre>./gradlew build connectedCheck</pre> - </li> -</ol> -<p>To learn more about using Gradle for Android testing, see the -<a href="//tools.android.com/tech-docs/new-build-system/user-guide#TOC-Testing">Gradle Plugin User Guide</a>.</p> -<p>To learn more about using command line tools other than Gradle for test -development, see -<a href="{@docRoot}tools/testing/testing_otheride.html">Testing from Other IDEs</a>.</p> - diff --git a/docs/html/training/app-indexing/deep-linking.jd b/docs/html/training/app-indexing/deep-linking.jd index 26799370015c..4ee742413ac8 100644 --- a/docs/html/training/app-indexing/deep-linking.jd +++ b/docs/html/training/app-indexing/deep-linking.jd @@ -66,10 +66,10 @@ in your manifest for deep linking. The URIs {@code “example://gizmos”} and android:host="www.example.com" android:pathPrefix="/gizmos" /> <!-- note that the leading "/" is required for pathPrefix--> - <!-- Accepts URIs that begin with "example://gizmos” + <!-- Accepts URIs that begin with "example://gizmos” --> <data android:scheme="example" android:host="gizmos" /> - --> + </intent-filter> </activity> </pre> diff --git a/docs/html/training/articles/keystore.jd b/docs/html/training/articles/keystore.jd index 5323e20f71bf..a1563a7a9493 100644 --- a/docs/html/training/articles/keystore.jd +++ b/docs/html/training/articles/keystore.jd @@ -1,8 +1,8 @@ page.title=Android Keystore System @jd:body -<div id="qv-wrapper"> - <div id="qv"> +<div id="tb-wrapper"> +<div id="tb"> <h2>In this document</h2> <ol> <li><a href="#SecurityFeatures">Security Features</a></li> diff --git a/docs/html/training/articles/user-data-ids.jd b/docs/html/training/articles/user-data-ids.jd new file mode 100644 index 000000000000..5a4648b72829 --- /dev/null +++ b/docs/html/training/articles/user-data-ids.jd @@ -0,0 +1,741 @@ +page.title=Best Practices for Unique Identifiers +page.metaDescription=How to manage unique identifiers the right way for users. +page.tags=ids, user data +meta.tags="ids", "user data" +page.image=images/cards/card-user-ids_2x.png + +page.article=true +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + <h2>In this document</h2> + <ol> + <li><a href="#tenets_of_working_with_android_identifiers">Tenets of Working with + Android Identifiers</a></li> + <li><a href="#version_specific_details_identifiers_in_m">Identifiers in Android 6.0+</a></li> + <li><a href="#working_with_advertising_ids">Working with Advertising IDs</a></li> + <li><a href="#working_with_instance_ids_&_guids">Working with Instance IDs and GUIDs</a></li> + <li><a href="#understand_identifier_characteristics">Understanding Identifier + Characteristics</a> + <ol> + <li><a href="#scope">Scope</a></li> + <li><a href="#resettability_&_persistence">Resettability & persistence</a></li> + <li><a href="#uniqueness">Uniqueness</h3> + <li><a href="#integrity_protection_and_non-repudiability">Integrity protection and + non-repudiability</a></li> + </ol> + </li> + <li><a href="#use_appropriate_identifiers">Common Use Cases and the Identifier to Use</a> + <ol> + <li><a href="#a_track_signed-out_user_preferences">Tracking signed-out user + preferences</a></li> + <li><a href="#b_track_signed-out_user_behavior">Tracking signed-out user behavior</a></li> + <li><a href="#c_generate_signed-out_anonymous_user_analytics">Generating + signed-out/anonymous user analytics</a></li> + <li><a href="#d_track_signed-out_user_conversion">Tracking signed-out user + conversion</a></li> + <li><a href="#e_handle_multiple_installations">Handling multiple installations</a></li> + <li><a href="#f_anti-fraud_enforcing_free_content_limits_detecting_sybil_attacks">Anti-fraud: + Enforcing free content limits / detecting Sybil attacks</a></li> + <li><a href="#g_manage_telephony_&_carrier_functionality">Managing telephony and carrier + functionality</a></li> + <li><a href="#h_abuse_detection_identifying_bots_and_ddos_attacks">Abuse detection: + Identifying bots and DDoS attacks</a></li> + <li><a href="#i_abuse_detection_detecting_high_value_stolen_credentials">Abuse detection: + Detecting high value stolen credentials</a></li> + </ol> + </li> + </ol> + </div> +</div> + +<p> + While there are valid reasons why your application may need to identify a + device rather than an instance of the application or an authenticated user on + the device, for the vast majority of applications, the ultimate goal is to + identify a particular <em>installation</em> of your app (not the actual + physical device). +</p> + +<p> + Fortunately, identifying an installation on Android is straightforward using + an Instance ID or by creating your own GUID at install time. This document + provides guidance for selecting appropriate identifiers for your application, + based on your use-case. +</p> + +<p> + For a general look at Android permissions, please see <a href= + "{@docRoot}training/articles/user-data-overview.html">Permissions + and User Data</a>. For specific best practices for + working with Android permissions, please see <a href= + "{@docRoot}training/articles/user-data-permissions.html">Best Practices for + App Permissions</a>. +</p> + + +<h2 id="tenets_of_working_with_android_identifiers">Tenets of Working with Android Identifiers</h2> + +<p> + We recommend that you follow these tenets when working with Android + identifiers: +</p> + +<p> + <em><strong>#1: Avoid using hardware identifiers.</strong></em> Hardware + identifiers such as SSAID (Android ID) and IMEI can be avoided in most + use-cases without limiting required functionality. +</p> + +<p> + <em><strong>#2: Only use Advertising ID for user profiling or ads + use-cases.</strong></em> When using an <a href= + "https://support.google.com/googleplay/android-developer/answer/6048248?hl=en"> + Advertising ID</a>, always respect the <a href= + "https://play.google.com/about/developer-content-policy.html#ADID">Limit Ad + Tracking</a> flag, ensure the identifier cannot be connected to personally + identifiable information (PII) and avoid bridging Advertising ID resets. +</p> + +<p> + <em><strong>#3: Use an Instance ID or a privately stored GUID whenever + possible for all other use-cases except payment fraud prevention and + telephony.</strong></em> For the vast majority of non-ads use-cases, an + instance ID or GUID should be sufficient. +</p> + +<p> + <em><strong>#4: Use APIs that are appropriate to your use-case to minimize + privacy risk.</strong></em> Use the + <a href="http://source.android.com/devices/drm.html">DRM + API</a> API for high value content + protection and the <a href="{@docRoot}training/safetynet/index.html">SafetyNet + API</a> for abuse prevention. The Safetynet API is + the easiest way to determine whether a device is genuine without incurring + privacy risk. +</p> + +<p> + The remaining sections of this guide elaborate on these rules in the context + of developing Android applications. +</p> + +<h2 id="version_specific_details_identifiers_in_m">Identifiers in Android 6.0+</h2> + +<p> + MAC addresses are globally unique, not user-resettable and survive factory + reset. It is generally not recommended to use MAC address for any form of + user identification. As a result, as of Android M, local device MAC addresses + (for example, Wifi and Bluetooth) <em><strong>are not available via third party + APIs</strong></em>. The {@link android.net.wifi.WifiInfo#getMacAddress WifiInfo.getMacAddress()} + method and the {@link android.bluetooth.BluetoothAdapter#getAddress + BluetoothAdapter.getDefaultAdapter().getAddress()} method will + both return <code>02:00:00:00:00:00</code>.. +</p> + +<p> + Additionally, you must hold the following permissions to access MAC addresses + of nearby external devices available via Bluetooth and Wifi scans: +</p> + +<table> + <tr> + <th><strong>Method/Property</strong></td> + <th><strong>Permissions Required</strong></td> + </tr> + <tr> + <td> + <code><a href="{@docRoot}reference/android/net/wifi/WifiManager.html#getScanResults()">WifiManager.getScanResults()</a></code> + </td> + <td> + <code>ACCESS_FINE_LOCATION</code> or <code>ACCESS_COARSE_LOCATION</code> + </td> + </tr> + <tr> + <td> + <code><a href="{@docRoot}reference/android/bluetooth/BluetoothDevice.html#ACTION_FOUND">BluetoothDevice.ACTION_FOUND</a></code> + </td> + <td> + <code>ACCESS_FINE_LOCATION</code> or <code>ACCESS_COARSE_LOCATION</code> + </td> + </tr> + <tr> + <td> + <code><a href="{@docRoot}reference/android/bluetooth/le/BluetoothLeScanner.html#startScan(android.bluetooth.le.ScanCallback)">BluetoothLeScanner.startScan(ScanCallback)</a></code> + </td> + <td> + <code>ACCESS_FINE_LOCATION</code> or <code>ACCESS_COARSE_LOCATION</code> + </td> + </tr> +</table> + + +<h2 id="working_with_advertising_ids">Working with Advertising IDs</h2> + +<p> + Advertising ID is a user-resettable identifier and is appropriate for Ads + use-cases, but there are some key points to bear in mind when using it: +</p> + +<p> + <em><strong>Always respect the user’s intention in resetting the advertising + ID</strong></em>. Do not bridge user resets by using a more persistent device + identifier or fingerprint to link subsequent Advertising IDs together without + the user’s consent. The <a href= + "https://play.google.com/about/developer-content-policy.html">Google Play + Developer Content Policy</a> states: +</p> + +<div style="padding:.5em 2em;"> +<div style="border-left:4px solid #999;padding:0 1em;font-style:italic;"> +<p>...upon reset, a new advertising + identifier must not be connected to a previous advertising identifier or data + derived from a previous advertising identifier without the explicit consent + of the user</span></p> +</div> +</div> + +<p> + <em><strong>Always respect the associated Interest Based Advertising + flag</strong></em>. Advertising IDs are configurable in that users can limit + the amount of tracking associated with the ID. Always use the <code><a href= + "https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html#isLimitAdTrackingEnabled()"> + AdvertisingIdClient.Info.isLimitAdTrackingEnabled()</a></code> method to + ensure you are not circumventing your users' wishes. The <a href= + "https://play.google.com/about/developer-content-policy.html">Google Play + Developer Content Policy</a> states: +</p> + + +<div style="padding:.5em 2em;"> +<div style="border-left:4px solid #999;padding:0 1em;font-style:italic;"> +<p>...you must abide by a user’s ‘opt out of + interest-based advertising’ setting. If a user has enabled this setting, you + may not use the advertising identifier for creating user profiles for + advertising purposes or for targeting users with interest-based advertising. + Allowed activities include contextual advertising, frequency capping, + conversion tracking, reporting and security and fraud detection.</span></p> +</div> +</div> + +<p> + <em><strong>Be aware of any privacy or security policies associated with SDKs + you use that are related to Advertising ID use.</strong></em> For example, if + you are using the Google Analytics SDK + <code><a href= + "https://developers.google.com/android/reference/com/google/android/gms/analytics/Tracker.html#enableAdvertisingIdCollection(boolean)">mTracker.enableAdvertisingIdCollection(true)</a></code> + method, make sure to review and adhere to all applicable <a href= + "https://developers.google.com/analytics/devguides/collection/android/v4/policy"> + Analytics SDK policies</a>. +</p> + +<p> + Also, be aware that the <a href= + "https://play.google.com/about/developer-content-policy.html">Google Play + Developer Content Policy</a> requires that the Advertising ID “must not be + connected to personally-identifiable information or associated with any + persistent device identifier (for example: SSAID, MAC address, IMEI, etc.,) + without the explicit consent of the user.” +</p> + +<p> + As an example, suppose you want to collect information to populate database + tables with the following columns: +</p> + +<table> + <tr> + <td> + <table> + <tr> + <td class="tab2"> + <code>timestamp</code></td> + <td class="tab2"> + <code>ad_id</code></td> + <td> + <code><strong>account_id</strong></code></td> + <td class="tab2"> + <code>clickid</code></td> + </tr> + </table> + + <p>TABLE-01</p> + </td> + <td> + <table> + <tr> + <td> + <code><strong>account_id</strong></code></td> + <td class="tab2"> + <code>name</code></td> + <td class="tab2"> + <code>dob</code></td> + <td class="tab2"> + <code>country</code></td> + </tr> + </table> + <p>TABLE-02</p> + </td> + </tr> +</table> + + +<p> + In this example, the <code>ad_id</code> column could be joined to PII via the + <code>account_id</code> column in both tables, which would be a violation of + the <a href= + "https://play.google.com/about/developer-content-policy.html">Google Play + Developer Content Policy</a>. +</p> + +<p> + Keep in mind that links between Advertiser ID and PII aren't always this + explicit. It's possible to have “quasi-identifiers” that appear in both PII + and Ad ID keyed tables, which also cause problems. For example, assume we + change TABLE-01 and TABLE-02 as follows: +</p> + +<table> + <tr> + <td><table> + <tr> + <td> + <code><strong>timestamp</strong></code></td> + <td class="tab2"> + <code>ad_id</code></td> + <td> + <code>clickid</code></td> + <td> + <code><strong>dev_model</strong></code></td> + </tr> + </table> + + </pre> + <p>TABLE-01</p> + </td> + <td> + <table> + <tr> + <td> + <code><strong>timestamp</strong></code></td> + <td class="tab2"> + <code>demo</code></td> + <td class="tab2"> + <code>account_id</code></td> + <td> + <code><strong>dev_model</strong></code></td> + <td class="tab2"> + <code>name</code></td> + </tr> + </table> + <p>TABLE-02</p> + </td> + </tr> +</table> + + +<p> + In this case, with sufficiently rare click events, it's still possible to + join between the Advertiser ID TABLE-01 and the PII contained in TABLE-2 + using the timestamp of the event and the device model. +</p> + +<p> + While it is often difficult to guarantee that no such quasi-identifiers exist + in a dataset, the most obvious join risks can be prevented by generalizing + unique data where possible. In the example, this would mean reducing the + accuracy of the timestamp so that multiple devices with the same model appear + for every timestamp. +</p> + +<p> + Other solutions include: +</p> + +<ul> +<li><em><strong>Not designing tables that explicitly link PII with Advertising +IDs</strong></em>. In the first example above this would mean not including the +account_id column in TABLE-01.</li> + +<li><em><strong>Segregating and monitoring access control lists for users or roles +that have access to both the Advertising ID keyed data and PII</strong></em>. If the +ability to access both sources simultaneously (for example, to perform +a join between two tables) is tightly controlled and audited, it reduces the +risk of association between the Advertising ID and PII. Generally speaking, +controlling access means: + +<ol> + <li> Keeping access control lists (ACLs) for Advertiser ID keyed data and PII disjoint to + minimize the number of individuals or roles that are in both ACLs, and</li> + <li> Implementing access logging and auditing to detect and manage any exceptions to + this rule.</li> +</ol> +</li> +</ul> + +<p> + For more information on working responsibly with Advertising IDs, please see + the <a href= + "https://support.google.com/googleplay/android-developer/answer/6048248?hl=en"> + Advertising ID</a> help center article. +</p> + +<h2 id="working_with_instance_ids_&_guids">Working with Instance IDs and GUIDs</h2> + +<p> + The most straightforward solution to identifying an application instance + running on a device is to use an Instance ID, and this is the recommended + solution in the majority of non-ads use-cases. Only the app instance for + which it was provisioned can access this identifier, and it's (relatively) + easily resettable because it only persists as long as the app is installed. +</p> + +<p> + As a result, Instance IDs provide better privacy properties compared to + non-resettable, device-scoped hardware IDs. They also come with a key-pair + for message signing (and similar actions) and are available on Android, iOS + and Chrome. Please see the <a href= + "https://developers.google.com/instance-id/">What is Instance ID?</a> help + center document for more information. +</p> + +<p> + In cases where an Instance ID isn't practical, custom globally unique IDs + (GUIDs) can also be used to uniquely identify an app instance. The simplest + way to do so is by generating your own GUID using the following code. +</p> + +<pre>String uniqueID = UUID.randomUUID().toString();</pre> + +<p> + Because the identifier is globally unique, it can be used to identify a + specific app instance. To avoid concerns related to linking the identifier + across applications, GUIDs should be stored in internal storage rather than + external (shared) storage. Please see <a href= + "{@docRoot}guide/topics/data/data-storage.html">Storage Options</a> guide for + more information. +</p> + + +<h2 id="understand_identifier_characteristics">Understanding Identifier Characteristics</h2> + +<p> + The Android Operating system offers a number of IDs with different behavior + characteristics and which ID you should use depends on how those following + characteristics work with your use-case. But these characteristics also come + with privacy implications so it's important to understand how these + characteristics play together. +</p> + +<h3 id="scope">Scope</h3> + +<p> + Identifier scope explains which systems can access the identifier. Android + identifier scope generally comes in three flavors: +</p> + +<ul> + <li> <em>Single app</em>. the ID is internal to the app and not accessible to other apps. + <li> <em>Group of apps</em> - the ID is accessible to a pre-defined group of related apps. + <li> <em>Device</em> - the ID is accessible to all apps installed on the device. +</ul> + +<p> + The wider the scope granted to an identifier, the greater the risk of it + being used for tracking purposes. Conversely, if an identifier can only be + accessed by a single app instance, it can’t be used to track a device across + transactions in different apps. +</p> +<h3 id="resettability_&_persistence">Resettability and persistence</h3> + +<p> + Resettability and persistence define the lifespan of the identifier and + explain how it can be reset. Common reset triggers are: in-app resets, resets + via System Settings, resets on launch, and resets on installation. Android + Identifiers can have varying lifespans, but the lifespan is usually related + to how the ID is reset: +</p> +<ul> + <li> <em>Session-only</em> - a new ID is used every time the user restarts the app. + <li> <em>Install-reset</em> - a new ID is used every time user uninstalls and reinstalls the app. + <li> <em>FDR-reset</em> - a new ID is used every time the user factory-resets the device. + <li> <em>FDR-persistent</em> - the ID survives factory reset. +</ul> + +<p> + Resettability gives users the ability to create a new ID that is + disassociated from any existing profile information. This is important + because the longer, and more reliably, an identifier persists (e.g. across + factory resets etc.), the greater the risk that the user may be subjected to + long-term tracking. If the identifier is reset upon app reinstall, this + reduces the persistence and provides a means for the ID to be reset, even if + there is no explicit user control to reset it from within the app or the + System Settings. +</p> +<h3 id="uniqueness">Uniqueness</h3> + +<p> + Uniqueness establishes the likelihood that identical identifiers exist within + the associated scope. At the highest level, a globally unique identifier will + never have a collision - even on other devices/apps. Otherwise, the level of + uniqueness depends on the size of the identifier and the source of randomness + used to create it. For example, the chance of a collision is much higher for + random identifiers seeded with the calendar date of installation (e.g., + 2015-01-05) than for identifiers seeded with the Unix timestamp of + installation (e.g., 1445530977). +</p> + +<p> + In general, user account identifiers can be considered unique (i.e., each + device/account combo has a unique ID). On the other hand, the less unique + an identifier is within a population (e.g. of devices), the greater the + privacy protection because it's less useful for tracking an individual user. +</p> + +<h3 id="integrity_protection_and_non-repudiability">Integrity protection and +non-repudiability</h3> + +<p> + An identifier that is difficult to spoof or replay can be used to prove that + the associated device or account has certain properties (e.g. it’s not a + virtual device used by a spammer). Difficult to spoof identifiers also + provide <em>non-repudiability</em>. If the device signs a message with a + secret key, it is difficult to claim someone else’s device sent the message. + Non-repudiability could be something a user wants (e.g. authenticating a + payment) or it could be an undesirable property (e.g. sending a message they + regret). +</p> + + +<h2 id="use_appropriate_identifiers">Common Use Cases and the Identifier to Use</h2> + +<p> + This section provides alternatives to using hardware IDs such as IMEI or + SSAID for the majority of use-cases. Relying on hardware IDs is discouraged + because the user cannot reset them and generally has limited control over + their collection. +</p> + +<h3 id="a_track_signed-out_user_preferences">Tracking signed-out user preferences</h3> + +<p> + <em>In this case, you are saving per-device state on the server side.</em> +</p> + +<p> + <strong>We Recommend</strong>: Instance ID or a GUID. +</p> + +<p> + <strong>Why this Recommendation?</strong> +</p> + +<p> + Persisting information through reinstalls is not recommended because users + may want to reset their preferences by reinstalling the app. +</p> + +<h3 id="b_track_signed-out_user_behavior">Tracking signed-out user behavior</h3> + +<p> + <em>In this case, you have created a profile of a user based on their + behavior across different apps/sessions on the same device.</em> +</p> + +<p> + <strong>We Recommend</strong>: Advertising ID. +</p> + +<p> + <strong>Why this Recommendation?</strong> +</p> + +<p> + Use of the Advertising ID is mandatory for Advertising use-cases per the + <a href="https://play.google.com/about/developer-content-policy.html">Google + Play Developer Content Policy</a> because the user can reset it. +</p> + +<h3 id="c_generate_signed-out_anonymous_user_analytics">Generating signed-out/anonymous user analytics</h3> + +<p> + <em>In this case, you are measuring usage statistics and analytics for + signed-out or anonymous users.</em> +</p> + +<p> + <strong>We Recommend</strong>: Instance ID; if an Instance ID is + insufficient, you can also use a GUID. +</p> + +<p> + <strong>Why this Recommendation?</strong> +</p> + +<p> + An Instance ID or a GUID is scoped to the app that creates it, which prevents + it from being used to track users across apps. It is also easily reset by + clearing app data or reinstalling the app. Creating Instance IDs and GUIDs is + straightforward: +</p> + +<ul> + <li> Creating an Instance ID: <code>String iid = InstanceID.getInstance(context).getId()</code> + <li> Creating a GUID: <code>String uniqueID = UUID.randomUUID().toString</code> +</ul> + +<p> + Be aware that if you have told the user that the data you are collecting is + anonymous, you should <em><strong>ensure you are not connecting the + identifier to PII</strong></em> or other identifiers that may be linked to + PII. +</p> + +<p> + You can also use Google Analytics for Mobile Apps, which offers a solution + for per-app analytics. +</p> + +<h3 id="d_track_signed-out_user_conversion">Tracking signed-out user conversion</h3> + +<p> + <em>In this case, you are tracking conversions to detect if your marketing + strategy was successful.</em> +</p> + +<p> + <strong>We Recommend</strong>: Advertising ID. +</p> + +<p> + <strong>Why this Recommendation?</strong> +</p> + +<p> + This is an ads-related use-case which may require an ID that is available + across different apps so using an Advertising ID is the most appropriate + solution. +</p> + +<h3 id="e_handle_multiple_installations">Handling multiple installations</h3> + +<p> + <em>In this case, you need to identify the correct instance of the app when + it's installed on multiple devices for the same user.</em> +</p> + +<p> + <strong>We Recommend</strong>: Instance ID or GUID. +</p> + +<p> + <strong>Why this Recommendation?</strong> +</p> + +<p> + Instance ID is designed explicitly for this purpose; its scope is limited to + the app so that it cannot be used to track users across different apps and it + is reset upon app reinstall. In the rare cases where an Instance ID is + insufficient, you can also use a GUID. +</p> + +<h3 id="f_anti-fraud_enforcing_free_content_limits_detecting_sybil_attacks">Anti-fraud: Enforcing free content limits / detecting Sybil attacks</h3> + +<p> + <em>In this case, you want to limit the number of free content (e.g. + articles) a user can see on a device.</em> +</p> + +<p> + <strong>We Recommend</strong>: Instance ID or GUID. +</p> + +<p> + <strong>Why this Recommendation?</strong> +</p> + +<p> + Using a GUID or Instance ID forces the user to reinstall the app in order to + overcome the content limits, which is a sufficient burden to deter most + people. If this is not sufficient protection, Android provides a + <a href="http://source.android.com/devices/drm.html">DRM API</a> + which can be used to limit access to content. +</p> + +<h3 id="g_manage_telephony_&_carrier_functionality">Managing telephony and carrier functionality</h3> + +<p> + <em>In this case, your app is interacting with the device's phone and texting + functionality.</em> +</p> + +<p> + <strong>We Recommend</strong>: IMEI, IMSI, and Line1 (requires <code>PHONE</code> + permission group in Android 6.0 (API level 23) and higher). +</p> + +<p> + <strong>Why this Recommendation?</strong> +</p> + +<p> + Leveraging hardware identifiers is acceptable if it is required for + telephony/carrier related functionality; for example, switching between + cellular carriers/SIM slots or delivering SMS messages over IP (for Line1) - + SIM-based user accounts. But it's important to note that in Android 6.0+ + these identifiers can only be used via a runtime permission and that users + may toggle off this permission so your app should handle these exceptions + gracefully. +</p> + +<h3 id="h_abuse_detection_identifying_bots_and_ddos_attacks">Abuse detection: +Identifying bots and DDoS attacks</h3> + +<p> + <em>In this case, you are trying to detect multiple fake devices attacking + your backend services.</em> +</p> + +<p> + <strong>We Recommend:</strong> The Safetynet API. +</p> + +<p> + <strong>Why this Recommendation?</strong> +</p> + +<p> + An identifier in isolation does little to indicate that a device is genuine. + You can verify that a request comes from a genuine Android device (as opposed + to an emulator or other code spoofing another device) using the Safetynet + API's <code>SafetyNet.SafetyNetApi.attest(mGoogleApiClient, nonce)</code> + method to verify the integrity of a device making a request. For more + detailed information, please see <a href= + "{@docRoot}training/safetynet/index.html">Safetynet's API documentation</a>. +</p> + +<h3 id="i_abuse_detection_detecting_high_value_stolen_credentials">Abuse detection: +Detecting high value stolen credentials</h3> + +<p> + <em>In this case, you are trying to detect if a single device is being used + multiple times with high-value, stolen credentials (e.g. to make fraudulent + payments).</em> +</p> + +<p> + <strong>We Recommend</strong>: IMEI/IMSI (requires <code>PHONE</code> + permission group in Android 6.0 (API level 23) and higher.) +</p> + +<p> + <strong>Why this Recommendation?</strong> +</p> + +<p> + With stolen credentials, devices can be used to monetize multiple high value + stolen credentials (such as tokenized credit cards). In these scenarios, + software IDs can be reset to avoid detection, so hardware identifiers may be + used. +</p>
\ No newline at end of file diff --git a/docs/html/training/articles/user-data-overview.jd b/docs/html/training/articles/user-data-overview.jd new file mode 100644 index 000000000000..8715d36cb76c --- /dev/null +++ b/docs/html/training/articles/user-data-overview.jd @@ -0,0 +1,269 @@ +page.title=Permissions and User Data +page.metaDescription=An overview of permissions on Android and how to manage them. +page.tags="user data","permissions","identifiers" +page.image=images/cards/card-user_2x.png + +page.article=true +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + <h2>In this document</h2> + <ol> + <li><a href="#introduction">Introduction</a></li> + <li><a href="#permission_groups">Permission Groups</a></li> + <li><a href="#permission_requests_and_app_downloads">Permission + Requests and App Downloads</a></li> + <li><a href="#permission_requests_trend_downward">Permission Requests + Trend Downward</a></li> + </ol> + <h2>You should also read</h2> + <ol> + <li><a href="{@docRoot}guide/topics/security/permissions.html">System Permissions</a></li> + <li><a href="{@docRoot}training/permissions/index.html">Working with System + Permissions</a></li> + </ol> + </div> +</div> + +<p> + Permissions protect sensitive information available from a device and should + only be used when access to information is necessary for the functioning of + your app. +</p> + +<p> + This document provides a high-level overview on how permissions work in + Android so you can make better, more informed decisions about the permissions + you're requesting. The information in this document is not use-case specific + and avoids complex, low-level discussions of the underlying code. +</p> + +<p> + For specific recommendations on how to manage permissions, please see + <a href="{@docRoot}training/articles/user-data-permissions.html">Best + Practices for App Permissions</a>. For best practices on using unique + identifiers on Android, please see <a href= + "{@docRoot}training/articles/user-data-ids.html">Best Practices for Unique + Identifiers</a>. For details on how to work with permissions in your code, + see <a href="{@docRoot}training/permissions/index.html">Working with System + Permissions</a>. +</p> + + +<h2 id="introduction">Introduction</h2> + +<p> + Every Android application must have a <em>manifest file</em> that presents + essential information about the app to the Android system. The Android system + also requires apps to request permission when they want to access sensitive + device or user information, and these requests must be documented in advance + as a part of your app's manifest. Moreover, accessing sensitive information + can affect user behavior, so it's important to make sure you are only making + permission requests when that information is necessary for the functioning of + your app. +</p> + + +<h2 id="permission_groups">Permission Groups</h2> + +<p> + Permissions in Android are organized into <code><a href= + "{@docRoot}guide/topics/security/permissions.html#perm-groups">permission + groups</a></code> that organize, and group, permissions related to a device's + capabilities or features. Under this system, permission requests are handled + at the group level and a <em><strong>single permission group</strong></em> + corresponds to <em><strong>several permission declarations</strong></em> in + the app manifest; for example, the SMS group includes both the + <code>READ_SMS</code> and the <code>RECEIVE_SMS</code> declarations. +</p> + + +<div class="wrap"> + <img src="{@docRoot}images/training/articles/user-data-overview-permissions-flow01.jpg"> +</div> + +<p> + This arrangement is simpler and more informative for users; once an app is + granted permission to access the group, it can use API calls within that + group and users with auto-update enabled will not be asked for additional + permissions because they have already granted access to the group. Grouping + permissions in this way enables the user to make more meaningful and informed + choices, without being overwhelmed by complex and technical permission + requests. +</p> + +<p> + This also means that when you request access to a particular API call or + query a content provider behind a permission, the user will be presented with + a request to grant permission for the whole group rather than the specific + API call. For example, if you request the <code>WRITE_CALL_LOG</code> + permission, the user will be asked to grant access to the <em>PHONE</em> + group (in API level 23 and higher), which is composed of the + <code>READ_PHONE_STATE</code>, <code>CALL_PHONE</code>, + <code>READ_CALL_LOG</code>, <code>WRITE_CALL_LOG</code>, + <code>ADD_VOICEMAIL</code>, <code>USE_SIP</code>, and + <code>PROCESS_OUTGOING_CALLS</code> permissions, and + all their associated methods. +</p> + +<div class="wrap"> + <img src="{@docRoot}images/training/articles/user-data-overview-permissions-flow02.png"> +</div> + +<p> + One consequence of grouping permissions is that a single API call within your + app can have a multiplying effect in terms of the number of permissions + requested by your app. +</p> + +<ol> +<li>API Call →</li> +<li stydle="margin-left:.5em;">Triggers a specific <em>Permission Group</em> access +request →</li> +<li stydle="margin-left:1em;">Successful request grants access to all permissions in +group (if auto-update +enabled) →</li> +<li stydle="margin-left:1.5em;">Each permission grants access to all APIs under that +permission</li> +</ol> + +<p> + As another example, let's assume your application uses one or more <a href= + "{@docRoot}reference/android/telephony/TelephonyManager.html"><code>TelephonyManager</code></a> + methods, such as: +</p> + +<pre class="prettyprint"> +TelephonyManager.getDeviceId() +TelephonyManager.getSubscriberId() +TelephonyManager.getSimSerialNumber() +TelephonyManager.getLine1Number() +TelephonyManager.getVoiceMailNumber() +</pre> + +<p> + To use these methods, the <code>READ_PHONE_STATE</code> permission must be + declared in the app's manifest, and the associated permission group, + <em>PHONE</em>, will be surfaced to the user. This + is important, because it means the user will be asked to grant permission for + the relevant group and all its associated permissions and API calls, rather + than for the specific API call you're requesting. +</p> + +<p>For a full mapping between permissions and their associated permission groups, +please refer to the appropriate version-specific documentation below:</p> + +<ul> + <!--<li> <a href="">pre-M Android OS versions</a>.</li> --> + <li> <a href="{@docRoot}guide/topics/security/permissions.html#perm-groups">Permission + groups, Android 6.0 Marshmallow (API level 23) and later</a>.</li> +</ul> + + +<h2 id="permission_requests_and_app_downloads">Permission Requests and App Downloads</h2> + +<div style="padding:.5em 2em;"> +<div style="border-left:4px solid #999;padding:0 1em;font-style:italic;"> +<p><em>I'm currently using the READ_PHONE_STATE permission in Android to pause my +media player when there's a call, and to resume playback when the call is over. +The permission seems to scare a lot of people</em>...<span +style="font-size:.8em;color:#777"><sup><em><a +href="#references" style="color:#777;padding-left:.1em;">1</a></em></sup></span></p> +</div> +</div> + +<p> + Research shows that among apps that are otherwise identical (e.g., + functionality, brand recognition), requesting fewer permissions leads to more + downloads. Publicly available sources exist that assign grades to apps based + on their permissions usage and allow users to compare related apps by score; + such grades exist for many of the current Android apps and users pay close + attention to the related rankings. +</p> + +<p> + One study<span style="font-size:.8em;color:#777"><sup><em><a href= + "#references" style= + "color:#777;padding-left:.1em;">2</a></em></sup></span>, in which users + were shown two unbranded apps with similar ratings that had the same + functionality but different sets of permission requests, showed that users + were, on average, 3 times more likely to install the app with fewer + permissions requests. And a similar study <span style= + "font-size:.8em;color:#777"><sup><em><a href="#references" style= + "color:#777;padding-left:.1em;">3</a></em></sup></span> showed that users are 1.7 + times more likely, on average, to select the application with fewer + permission requests. +</p> + +<p> + Finally, permissions usage is not evenly distributed across apps within + a similar category of Play apps. For example, 39.3% of arcade game apps in + the Play store request no permissions that are surfaced to the user while + only 1.5% of arcade games request the Phone permission group (see Figure + 1). +</p> + +<div class="wrap"> + <div class="cols"> + <div class="col-16of16"> + <img src="{@docRoot}images/training/articles/user-data-overview-permissions-groups.png"> + <p class="figure-caption"><strong>Figure 1.</strong> Distribution of + permission groups use across Arcade Games category.</p> + </div> + </div> +</div> + +<p> + Users comparing your app to other similar apps may determine that it is + making unusual permission requests for that category - in this case, Arcade + Games apps accessing the <em>Phone</em> permission group. As a result, they + may install a similar app in that category that avoids those + requests.<span style="font-size:.8em;color:#777"><sup><em><a href= + "#references" style="color:#777;padding-left:.1em;">4</a></em></sup></span> +</p> + + +<h2 id="permission_requests_trend_downward">Permission Requests Trend Downward</h2> + +<p> + A recent analysis of Play store apps over time indicated that many developers + trim permissions after first publishing their apps, suggesting that they may + be employing more caution around which permission groups they declare. +</p> + +<div class="wrap"> + <div class="cols"> + <div class="col-16of16"> + <img src="{@docRoot}images/training/articles/user-data-overview-permissions-usage.jpg"> + <p class="figure-caption"><strong>Figure 2.</strong> Developer usage of popular + permissions has decreased over time.</p> + </div> + </div> +</div> + +<p> + The graph in <em>Figure 2</em> illustrates this trend. There has been a + steady decrease in the average percentage of developers' apps requesting at + least one of the three most popular permissions in the Play store + (<code>READ_PHONE_STATE</code>, <code>ACCESS_FINE_LOCATION</code>, and + <code>ACCESS_COARSE_LOCATION</code>). These results indicate that developers + are reducing the permissions their apps request in response to user behavior. +</p> + +<p> + The bottom line is that providing the same functionality to the user with + minimal access to sensitive information means more downloads for your app. + For specific recommendations on how to achieve this, please see <a href= + "{@docRoot}training/articles/user-data-permissions.html">Best Practices for + Application Permissions</a>. +</p> + + +<h2 id="references">References</h2> + +<p>[1] Developer quote on StackOverflow. <em>(<a + href="http://stackoverflow.com/questions/24374701/alternative-to-read-phone-state-permission-for-getting-notified-of-call">source</a>)</em></p> +<p>[2] <em>Using Personal Examples to Improve Risk Communication for Security and Privacy Decisions</em>, by M. Harbach, M. Hettig, S. Weber, and M. Smith. In Proceedings of ACM CHI 2014.</p> +<p>[3] <em>Modeling Users’ Mobile App Privacy Preferences: Restoring Usability in a Sea of Permission Settings</em>, by J. Lin B. Liu, N. Sadeh and J. Hong. In Proceedings of SOUPS 2014.</p> +<p>[4] <em>Teens and Mobile Apps Privacy. (<a href="http://www.pewinternet.org/files/old-media/Files/Reports/2013/PIP_Teens%20and%20Mobile%20Apps%20Privacy.pdf">source</a>)</em></p> diff --git a/docs/html/training/articles/user-data-permissions.jd b/docs/html/training/articles/user-data-permissions.jd new file mode 100644 index 000000000000..edc755884e53 --- /dev/null +++ b/docs/html/training/articles/user-data-permissions.jd @@ -0,0 +1,381 @@ +page.title=Best Practices for App Permissions +page.metaDescription=How to manage permissions to give users context and control. +page.tags=permissions, user data +meta.tags="permissions", "user data" +page.image=images/cards/card-user-permissions_2x.png + +page.article=true +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + <h2>In this document</h2> + <ol> + <li><a href="#tenets_of_working_with_android_permissions">Tenets</a></li> + <li><a href="#version_specific_details_permissions_in_m">Permissions in Android + 6.0+</h2></a></li> + <li><a href="#avoid_requesting_unnecessary_permissions">Avoid Requesting +Unnecessary Permissions</h2></a> + <ol> + <li><a href="#a_camera_contact_access_with_real-time_user_requests">Camera/Contact + access with realtime user requests</a></li> + <li><a href="#b_running_in_the_background_after_losing_audio_focus">Running in +the background after losing audio focus</a></li> + <li><a href="#c_determine_the_device_your_instance_is_running_on">Determine the +device your instance is running on</a></li> + <li><a href="#d_create_a_unique_identifier_for_advertising_or_user_analytics"> +Create a unique identifier for advertising or user analytics</a></li> + </ol> + </li> + <li><a href="#know_the_libraries_you're_working_with">Know the Libraries You're +Working With</a></li> + <li><a href="#be_transparent">Be Transparent</a></li> + </ol> + <h2>You should also read</h2> + <ol> + <li><a href="{@docRoot}guide/topics/security/permissions.html">System Permissions</a></li> + <li><a href="{@docRoot}training/permissions/index.html">Working with System + Permissions</a></li> + </ol> + </div> +</div> + +<p> + Permission requests protect sensitive information available from a device and + should only be used when access to information is necessary for the + functioning of your app. This document provides tips on ways you might be + able to achieve the same (or better) functionality without requiring access + to such information; it is not an exhaustive discussion of how permissions + work in the Android operating system. +</p> + +<p> + For a more general look at Android permissions, please see <a href= + "{@docRoot}training/articles/user-data-overview.html">Permissions + and User Data</a>. For details on how to work with permissions in your code, + see <a href="{@docRoot}training/permissions/index.html">Working with System Permissions</a>. + For best practices for working with unique identifiers, please see <a href= + "{@docRoot}training/articles/user-data-ids.html">Best Practices for + Unique Identifiers</a>. +</p> + +<h2 id="tenets_of_working_with_android_permissions">Tenets of Working +with Android Permissions</h2> + +<p> + We recommend following these tenets when working with Android permissions: +</p> + +<p> + <em><strong>#1: Only use the permissions necessary for your app to + work</strong></em>. Depending on how you are using the permissions, there may + be another way to do what you need (system intents, identifiers, + backgrounding for phone calls) without relying on access to sensitive + information. +</p> + +<p> + <em><strong>#2: Pay attention to permissions required by + libraries.</strong></em> When you include a library, you also inherit its + permission requirements. You should be aware of what you're including, the + permissions they require, and what those permissions are used for. +</p> + +<p> + <em><strong>#3: Be transparent.</strong></em> When you make a permissions + request, be clear about what you’re accessing, and why, so users can make + informed decisions. Make this information available alongside the permission + request including install, runtime, or update permission dialogues. +</p> + +<p> + <em><strong>#4: Make system accesses explicit.</strong></em> Providing + continuous indications when you access sensitive capabilities (for example, the + camera or microphone) makes it clear to users when you’re collecting data and + avoids the perception that you're collecting data surreptitiously. +</p> + +<p> + The remaining sections of this guide elaborate on these rules in the context + of developing Android applications. +</p> + +<h2 id="version_specific_details_permissions_in_m">Permissions in Android 6.0+</h2> + +<p> + Android 6.0 Marshmallow introduced a <a href= + "{@docRoot}training/permissions/requesting.html">new permissions model</a> that + lets apps request permissions from the user at runtime, rather than prior to + installation. Apps that support the new model request permissions when the app + actually requires the services or data protected by the services. While this + doesn't (necessarily) change overall app behavior, it does create a few + changes relevant to the way sensitive user data is handled: +</p> + +<p> + <em><strong>Increased situational context</strong></em>: Users are + prompted at runtime, in the context of your app, for permission to access the + functionality covered by those permission groups. Users are more sensitive to + the context in which the permission is requested, and if there’s a mismatch + between what you are requesting and the purpose of your app, it's even + more important to provide detailed explanation to the user as to why you’re + requesting the permission; whenever possible, you should provide an + explanation of your request both at the time of the request and in a + follow-up dialog if the user denies the request. +</p> + +<p> + <em><strong>Greater flexibility in granting permissions</strong></em>: Users + can deny access to individual permissions at the time they’re requested + <em>and</em> in settings, but they may still be surprised when functionality is + broken as a result. It’s a good idea to monitor how many users are denying + permissions (e.g. using Google Analytics) so that you can either refactor + your app to avoid depending on that permission or provide a better + explanation of why you need the permission for your app to work properly. You + should also make sure that your app handles exceptions created when users + deny permission requests or toggle off permissions in settings. +</p> + +<p> + <em><strong>Increased transactional burden</strong></em>: Users will be asked + to grant access for permission groups individually and not as a set. This + makes it extremely important to minimize the number of permissions you’re + requesting because it increases the user burden for granting permissions and + increases the probability that at least one of the requests will be denied. +</p> + +<h2 id="avoid_requesting_unnecessary_permissions">Avoid Requesting +Unnecessary Permissions</h2> + +<p> + This section provides alternatives to common use-cases that will help you + limit the number of permission requests you make. Since the number and type + of user-surfaced permissions requested affects downloads compared to other + similar apps requesting fewer permissions, it’s best to avoid requesting + permissions for unnecessary functionality. +</p> + +<h3 id="a_camera_contact_access_with_real-time_user_requests">Camera/contact +access with realtime user requests</h3> + +<p> + <em>In this case, you need occasional access to the device's camera or + contact information and don’t mind the user being asked every time you need + access.</em> +</p> + +<p> + If your requirement for access to user data is infrequent — in other + words, it's not unacceptably disruptive for the user to be presented with a + runtime dialogue each time you need to access data — you can use an + <em>intent based request</em>. Android provides some system intents that + applications can use without requiring permissions because the user chooses + what, if anything, to share with the app at the time the intent based request + is issued. +</p> + +<p> + For example, an intent action type of <code><a href= + "{@docRoot}reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE">MediaStore.ACTION_IMAGE_CAPTURE</a></code> + or <code><a href= + "{@docRoot}reference/android/provider/MediaStore.html#ACTION_VIDEO_CAPTURE">MediaStore.ACTION_VIDEO_CAPTURE</a></code> + can be used to capture images or videos without directly using the <a href= + "{@docRoot}reference/android/hardware/Camera.html">Camera</a> object (or + requiring the permission). In this case, the system intent will ask for the + user’s permission on your behalf every time an image is captured. +</p> + +<h3 id="b_running_in_the_background_after_losing_audio_focus">Running in +the background after losing audio focus</h3> + +<p> + <em>In this case, your application needs to go into the background when the + user gets a phone call and refocus only once the call stops.</em> +</p> + +<p> + The common approach in these cases - for example, a media player muting or + pausing during a phone call - is to listen for changes in the call state + using <code>PhoneStateListener</code> or listening for the broadcast of + <code>android.intent.action.PHONE_STATE</code>. The problem with this + solution is that it requires the <code>READ_PHONE_STATE</code> permission, + which forces the user to grant access to a wide cross section of sensitive + data such as their device and SIM hardware IDs and the phone number of the + incoming call. +</p> + +<p> + You can avoid this by requesting <code>AudioFocus</code> for your app, which + doesn't require explicit permissions (because it does not access sensitive + information). Simply put the code required to background your audio in the + <code><a href= + "{@docRoot}reference/android/media/AudioManager.OnAudioFocusChangeListener.html#onAudioFocusChange(int)"> + onAudioFocusChange()</a></code> event handler and it will run automatically + when the OS shifts its audio focus. More detailed documentation on how to do + this can be found <a href= + "{@docRoot}training/managing-audio/audio-focus.html">here</a>. +</p> + +<h3 id="c_determine_the_device_your_instance_is_running_on">Determine the +device your instance is running on</h3> + +<p> + <em>In this case, you need a unique identifier to determine which device the + instance of your app is running on.</em> +</p> + +<p> + Applications may have device-specific preferences or messaging (e.g., saving + a device-specific playlist for a user in the cloud so that they can have a + different playlist for their car and at home). A common solution is to + leverage device identifiers such as <code>Device IMEI</code>, but this + requires the <code>Device ID and call information</code> + permission group (<code>PHONE</code> in M+). It also uses an identifier which + cannot be reset and is shared across all apps. +</p> + +<p> + There are two alternatives to using these types of identifiers: +</p> + +<ol> + <li> Use the <code>com.google.android.gms.iid</code> InstanceID API. + <code>getInstance(Context context).getID()<strong></code> </strong>will return a + unique device identifier for your application instance. The +result is an app instance scoped identifier that can be used as a key when +storing information about the app and is reset if the user re-installs the app. + <li> Create your own identifier that’s scoped to your app’s storage using basic + system functions like <a + href="{@docRoot}reference/java/util/UUID.html#randomUUID()"><code>randomUUID()</code></a>.</li> +</ol> + +<h3 id="d_create_a_unique_identifier_for_advertising_or_user_analytics">Create a unique +identifier for advertising or user analytics</h3> + +<p> + <em>In this case, you need a unique identifier for building a profile for + users who are not signed in to your app (e.g., for ads targeting or measuring + conversions).</em> +</p> + +<p> + Building a profile for advertising and user analytics sometimes requires an + identifier that is shared across other applications. Common solutions for + this involve leveraging device identifiers such as <code>Device IMEI</code>, + which requires the <code>Device ID</code> <code>and call information</code> + permission group (<code>PHONE</code> in API level 23+) and cannot be reset by + the user. In any of these cases, in addition to using a non-resettable + identifier and requesting a permission that might seem unusual to users, you + will also be in violation of the <a href= + "https://play.google.com/about/developer-content-policy.html">Play Developer + Program Policies</a>. +</p> + +<p> + Unfortunately, in these cases using the + <code>com.google.android.gms.iid</code> InstanceID API or system functions to + create an app-scoped ID are not appropriate solutions because the ID may need + to be shared across apps. An alternative solution is to use the + <code>Advertising Identifier</code> available from the <code><a href= + "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html"> + AdvertisingIdClient.Info</a></code> class via the <code>getId()</code> + method. You can create an <code>AdvertisingIdClient.Info</code> object using + the <code>getAdvertisingIdInfo(Context)</code> method and call the + <code>getId()</code> method to use the identifier. <em><strong>Note that this + method is blocking</strong></em>, so you should not call it from the main + thread; a detailed explanation of this method is available <a href= + "{@docRoot}google/play-services/id.html">here</a>. +</p> + +<h2 id="know_the_libraries_you're_working_with">Know the Libraries You're +Working With</h2> + +<p> + Sometimes permissions are required by the libraries you use in your app. For + example, ads and analytics libraries may require access to the + <code>Location</code> or <code>Identity</code> permissions groups to + implement the required functionality. But from the user’s point of view, the + permission request comes from your app, not the library. +</p> + +<p> + Just as users select apps that use fewer permissions for the same + functionality, developers should review their libraries and select + third-party SDKs that are not using unnecessary permissions. For example, try + to avoid libraries that require the <code>Identity</code> permission group + unless there is a clear user-facing reason why the app needs those permissions. + In particular, for libraries that provide location functionality, make sure you + are not required to request the <code>FINE_LOCATION</code> permission unless + you are using location-based targeting functionality. +</p> + +<h2 id="be_transparent">Be Transparent</h2> + +<p>You should inform your users about what you’re accessing and why. Research shows +that users are much less uncomfortable with permissions requests if they know +why the app needs them. A user study showed that:</p> + +<div style="padding:.5em 2em;"> +<div style="border-left:4px solid #999;padding:0 1em;font-style:italic;"> +<p>...a user’s willingness to grant a given permission to a given mobile app is +strongly influenced by the purpose associated with such a permission. For +instance a user’s willingness to grant access to his or her location will vary +based on whether the request is required to support the app’s core +functionality or whether it is to share this information with an advertising +network or an analytics company.<span +style="font-size:.8em;color:#777"><sup><em><a + href="#references" style="color:#777;padding-left:.1em;">1</a></em></sup></span></p> +</div> +</div> + +<p> + Based on his group’s research, Professor Jason Hong from CMU concluded that, + in general: +</p> + +<div style="padding:.5em 2em;"> +<div style="border-left:4px solid #999;padding:0 1em;font-style:italic;"> +<p>...when people know why an app is using something as sensitive as their location — +for example, for targeted advertising — it makes them more comfortable than +when simply told an app is using their location.<span +style="font-size:.8em;color:#777"><sup><em><a + href="#references" style="color:#777;padding-left:.1em;">1</a></em></sup></span></p> +</div> +</div> + +<p> + As a result, if you’re only using a fraction of the API calls that fall under + a permission group, it helps to explicitly list which of those permissions + you're using, and why. For example: +</p> + +<ul> + <li> If you’re only using coarse location, let the user know this in your app + description or in help articles about your app. </li> + <li> If you need access to SMS messages to receive authentication codes that + protect the user from fraud, let the user know this in your app description + and/or the first time you access the data.</li> +</ul> + +<p> + Under certain conditions, it's also advantageous to let users know about + sensitive data accesses in real-time. For example, if you’re accessing the + camera or microphone, it’s usually a good idea to let the user know with a + notification icon somewhere in your app, or in the notification tray (if the + application is running in the background), so it doesn't seem like you're + collecting data surreptitiously. +</p> + +<p> + Ultimately, if you need to request a permission to make something in your app + work, but the reason is not clear to the user, find a way to let the user + know why you need the most sensitive permissions. +</p> + +<h2 id="references">References</h2> + +<p> + [1] <em>Modeling Users’ Mobile App Privacy Preferences: Restoring Usability + in a Sea of Permission Settings</em>, by J. Lin B. Liu, N. Sadeh and J. Hong. + In Proceedings of SOUPS 2014. +</p> diff --git a/docs/html/training/best-permissions-ids.jd b/docs/html/training/best-permissions-ids.jd new file mode 100644 index 000000000000..e98c0953ddfa --- /dev/null +++ b/docs/html/training/best-permissions-ids.jd @@ -0,0 +1,9 @@ +page.title=Best Practices for Permissions and Identifiers +page.trainingcourse=true + +@jd:body + + + +<p>The articles below highlight key guidelines for using permissions +and identifiers properly in your apps.</p>
\ No newline at end of file diff --git a/docs/html/training/contacts-provider/retrieve-names.jd b/docs/html/training/contacts-provider/retrieve-names.jd index d97b81b1e340..49d6e955536c 100644..100755 --- a/docs/html/training/contacts-provider/retrieve-names.jd +++ b/docs/html/training/contacts-provider/retrieve-names.jd @@ -230,7 +230,7 @@ public class ContactsFragment extends Fragment implements {@link android.provider.ContactsContract.Contacts#DISPLAY_NAME_PRIMARY Contacts.DISPLAY_NAME_PRIMARY} requires Android 3.0 (API version 11) or later, setting your app's <code>minSdkVersion</code> to 10 or below generates an Android Lint warning in - Eclipse with ADK. To turn off this warning, add the annotation + Android Studio. To turn off this warning, add the annotation <code>@SuppressLint("InlinedApi")</code> before the definition of <code>FROM_COLUMNS</code>. </p> <h3 id="InitializeFragment">Initialize the Fragment</h3> diff --git a/docs/html/training/in-app-billing/preparing-iab-app.jd b/docs/html/training/in-app-billing/preparing-iab-app.jd index ca33008d3c15..2c6e9a074d31 100644..100755 --- a/docs/html/training/in-app-billing/preparing-iab-app.jd +++ b/docs/html/training/in-app-billing/preparing-iab-app.jd @@ -84,9 +84,9 @@ presented with the welcome screen.</li> <p>To add the In-app Billing Version 3 library to your new In-app Billing project:</p> <ol> <li>Copy the {@code TrivialDrive} sample files into your Android project.</li> -<li>Modify the package name in the files you copied to use the package name for your project. In Eclipse, you can use this shortcut: right-click the package name, then select <strong>Refactor</strong> > <strong>Rename</strong>.</li> +<li>Modify the package name in the files you copied to use the package name for your project. In Android Studio, you can use this shortcut: right-click the package name, then select <strong>Refactor</strong> > <strong>Rename</strong>.</li> <li>Open the {@code AndroidManifest.xml} file and update the package attribute value to use the package name for your project.</li> -<li>Fix import statements as needed so that your project compiles correctly. In Eclipse, you can use this shortcut: press <strong>Ctrl+Shift+O</strong> in each file showing errors.</li> +<li>Fix import statements as needed so that your project compiles correctly. In Android Studio, you can use this shortcut: press <strong>Ctrl+Shift+O</strong> in each file showing errors.</li> <li>Modify the sample to create your own application. Remember to copy the Base64 public license key for your application from the Developer Console over to your {@code MainActivity.java}.</li> </ol> @@ -98,7 +98,6 @@ presented with the welcome screen.</li> <li>In Android Studio: Create a directory named {@code aidl} under {@code src/main}, add a new package {@code com.android.vending.billing} in this directory, and import the {@code IInAppBillingService.aidl} file into this package.</li> - <li>In Eclipse: Import the {@code IInAppBillingService.aidl} file into your {@code /src} directory.</li> <li>In other dev environments: Create the following directory {@code /src/com/android/vending/billing} and copy the {@code IInAppBillingService.aidl} file into this directory.</li> </ul> </li> diff --git a/docs/html/training/index.jd b/docs/html/training/index.jd index 16658b909a75..7673a37dd659 100644 --- a/docs/html/training/index.jd +++ b/docs/html/training/index.jd @@ -27,10 +27,10 @@ Classes are organized into several groups you can see at the top-level of the le </div> </div> -<div style="clear:left"></div> -</div> +<div style="clear:left" id="classes"></div> - <div><h2 class="norule">Online video courses</h2> +<section class="dac-section dac-small" id="latest-games"><div class="wrap"> + <h2 class="norule">Online video courses</h2> <p>If you prefer to learn through interactive video training, check out these free courses.</p> <div class="resource-widget resource-flow-layout col-16" @@ -38,5 +38,7 @@ Classes are organized into several groups you can see at the top-level of the le data-sortOrder="random" data-cardSizes="6x6" data-maxResults="24" + data-items-per-page="24" data-initial-results="6"></div> -</div>
\ No newline at end of file + </div> +</section>
\ No newline at end of file diff --git a/docs/html/training/location/change-location-settings.jd b/docs/html/training/location/change-location-settings.jd new file mode 100644 index 000000000000..70733eb588fb --- /dev/null +++ b/docs/html/training/location/change-location-settings.jd @@ -0,0 +1,251 @@ +page.title=Changing Location Settings +trainingnavtop=true +@jd:body + +<div id="tb-wrapper"> + <div id="tb"> + + <h2>This lesson teaches you how to</h2> + <ol> + <li><a href="#connect">Connect to Location Services</a></li> + <li><a href="#location-request">Set Up a Location Request</a></li> + <li><a href="#get-settings">Get Current Location Settings</a></li> + <li><a href="#prompt">Prompt the User to Change Location Settings</a></li> + </ol> + + <h2>You should also read</h2> + <ul> + <li> + <a href="https://developers.google.com/android/guides/setup" + class="external-link">Setting up Google Play Services</a> + </li> + <li> + <a href="retrieve-current.html">Getting the Last Known Location</a> + </li> + </ul> + </div> +</div> + +<p>If your app needs to request location or receive permission updates, the + device needs to enable the appropriate system settings, such as GPS or Wi-Fi + scanning. Rather than directly enabling services such as the device's GPS, + your app specifies the required level of accuracy/power consumption and + desired update interval, and the device automatically makes the appropriate + changes to system settings. These settings are defined by the + <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest" + class="external-link">{@code LocationRequest}</a> + data object. </p> + +<p>This lesson shows you how to use the + <a href="https://developers.google.com/android/reference/com/google/android/gms/location/SettingsApi">Settings API</a> + to check which settings are enabled, and present the Location Settings + dialog for the user to update their settings with a single tap.</p> + +<h2 id="connect">Connect to Location Services</h2> + +<p>In order to use the location services provided by Google Play Services and + the fused location provider, connect your app using the + <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient">Google API Client</a>, + then check the current location settings and prompt the user to enable the + required settings if needed. For details on connecting with the + Google API client, see <a href="retrieve-current.html">Getting the Last Known Location</a>.</p> + +<p>Apps that use location services must request location permissions. For this + lesson, coarse location detection is sufficient. Request this permission + with the <code>uses-permission</code> element in your app manifest, as shown + in the following example:</p> + +<pre><code><manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.google.android.gms.location.sample.locationupdates" > + + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> +</manifest> +</code></pre> + +<p>If the device is running Android 6.0 or higher, and your app's target + SDK is 23 or higher, the app has to list the permissions in the manifest + <em>and</em> request those permissions at run time. For more information, see +<a href="{@docRoot}training/permissions/requesting.html">Requesting Permissions at Run Time</a>.</p> + +<h2 id="location-request">Set Up a Location Request</h2> + +<p>To store parameters for requests to the fused location provider, create a + <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html">{@code LocationRequest}</a>. + The parameters determine the level of accuracy for location requests. For + details of all available location request options, see the + <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html">{@code LocationRequest}</a> + class reference. This lesson sets the update interval, fastest update + interval, and priority, as described below:</p> + +<dl> + <dt> + Update interval + </dt> + <dd> + <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">{@code setInterval()}</a> + - This method sets the rate in milliseconds at which your app prefers to + receive location updates. Note that the location updates may be faster than + this rate if another app is receiving updates at a faster rate, or slower + than this rate, or there may be no updates at all (if the device has no + connectivity, for example). + </dd> + <dt> + Fastest update interval + </dt> + <dd> + <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">{@code setFastestInterval()}</a> + - This method sets the <strong>fastest</strong> rate in milliseconds at which + your app can handle location updates. You need to set this rate because + other apps also affect the rate at which updates are sent. The Google Play + services location APIs send out updates at the fastest rate that any app + has requested with + <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">{@code setInterval()}</a>. + If this rate is faster + than your app can handle, you may encounter problems with UI flicker or data + overflow. To prevent this, call + <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">{@code setFastestInterval()}</a> + to set an upper limit to the update rate. + </dd> + <dt>Priority</dt> + <dd> + <p> + <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#setPriority(int)">{@code setPriority()}</a> + - This method sets the priority of the request, which gives the Google Play + services location services a strong hint about which location sources to use. + The following values are supported:</p> + <ul> + <li> + <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_BALANCED_POWER_ACCURACY">{@code PRIORITY_BALANCED_POWER_ACCURACY}</a> + - Use this setting to request location precision to within a city + block, which is an accuracy of approximately 100 meters. This is + considered a coarse level of accuracy, and is likely to consume less + power. With this setting, the location services are likely to use WiFi + and cell tower positioning. Note, however, that the choice of location + provider depends on many other factors, such as which sources are + available.</li> + <li> + <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_HIGH_ACCURACY">{@code PRIORITY_HIGH_ACCURACY}</a> + - Use this setting to request the most precise location possible. With + this setting, the location services are more likely to use GPS + to determine the location.</li> + <li><a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_LOW_POWER">{@code PRIORITY_LOW_POWER}</a> + - Use this setting to request city-level precision, which is + an accuracy of approximately 10 kilometers. This is considered a + coarse level of accuracy, and is likely to consume less power.</li> + <li><a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_NO_POWER">{@code PRIORITY_NO_POWER}</a> + - Use this setting if you need negligible impact on power consumption, + but want to receive location updates when available. With this + setting, your app does not trigger any location updates, but + receives locations triggered by other apps.</li> + </ul> + </dd> +</dl> + +<p>Create the location request and set the parameters as shown in this + code sample:</p> + +<pre> +protected void createLocationRequest() { + LocationRequest mLocationRequest = new LocationRequest(); + mLocationRequest.setInterval(10000); + mLocationRequest.setFastestInterval(5000); + mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); +} +</pre> + +<p>The priority of + <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_HIGH_ACCURACY">{@code PRIORITY_HIGH_ACCURACY}</a>, + combined with the + {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} + permission setting that you've defined in the app manifest, and a fast update + interval of 5000 milliseconds (5 seconds), causes the fused location + provider to return location updates that are accurate to within a few feet. + This approach is appropriate for mapping apps that display the location in + real time.</p> + +<p class="note"><strong>Performance hint:</strong> If your app accesses the + network or does other long-running work after receiving a location update, + adjust the fastest interval to a slower value. This adjustment prevents your + app from receiving updates it can't use. Once the long-running work is done, + set the fastest interval back to a fast value.</p> + +<h2 id="get-settings">Get Current Location Settings</h2> + +<p>Once you have connected to Google Play services and the location services + API, you can get the current location settings of a user's device. To do + this, create a + <a href="{@docRoot}reference/com/google/android/gms/location/LocationSettingsRequest.Builder"><code>LocationSettingsRequest.Builder</code></a>, + and add one or more location requests. The following code snippet shows how + to add the location request that was created in the previous step:</p> + +<pre>LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder() + .addLocationRequest(mLocationRequest); +</pre> + +<p>Next check whether the current location settings are satisfied:</p> + +<pre>PendingResult<LocationSettingsResult> result = + LocationServices.SettingsApi.checkLocationSettings(mGoogleClient, + builder.build());</pre> + +<p>When the <a href="{@docRoot}reference/com/google/android/gms/common/api/PendingResult"><code>PendingResult</code></a> + returns, your app can check the location settings by looking at the status + code from the <a href="{@docRoot}reference/com/google/android/gms/location/LocationSettingsResult"><code>LocationSettingsResult</code></a> + object. To get even more details about the the current state of the relevant + location settings, your app can call the + <a href="{@docRoot}reference/com/google/android/gms/location/LocationSettingsResult">{@code LocationSettingsResult}</a> + object's + <a href="{@docRoot}reference/com/google/android/gms/location/LocationSettingsResult#getLocationSettingsStates"><code>getLocationSettingsStates()</code></a> + method.</p> + +<h2 id="prompt">Prompt the User to Change Location Settings</h2> + +<p>To determine whether the location settings are appropriate for the location + request, check the status code from the + <a href="{@docRoot}reference/com/google/android/gms/location/LocationSettingsResult">{@code LocationSettingsResult}</a> + object. A status code of <code>RESOLUTION_REQUIRED</code> indicates that the + settings must be changed. To prompt the user for permission to modify the + location settings, call + <a href="{@docRoot}reference/com/google/android/gms/common/api/Status#startResolutionForResult(android.app.Activity, int)"> + {@code startResolutionForResult(Activity, int)}</a>. + This method brings up a dialog asking for the user's permission to modify + location settings. The following code snippet shows how to check the location + settings, and how to call {@code startResolutionForResult(Activity, int)}. +</p> + +<pre>result.setResultCallback(new ResultCallback<LocationSettingsResult>()) { + @Override + public void onResult(LocationSettingsResult result) { + final Status status = result.getStatus(); + final LocationSettingsStates = result.getLocationSettingsStates(); + switch (status.getStatusCode()) { + case LocationSettingsStatusCodes.SUCCESS: + // All location settings are satisfied. The client can + // initialize location requests here. + ... + break; + case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: + // Location settings are not satisfied, but this can be fixed + // by showing the user a dialog. + try { + // Show the dialog by calling startResolutionForResult(), + // and check the result in onActivityResult(). + status.startResolutionForResult( + OuterClass.this, + REQUEST_CHECK_SETTINGS); + } catch (SendIntentException e) { + // Ignore the error. + } + break; + case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE: + // Location settings are not satisfied. However, we have no way + // to fix the settings so we won't show the dialog. + ... + break; + } + } + });</pre> + + <p>The next lesson, + <a href="receive-location-updates.html">Receiving Location Updates</a>, shows + you how to receive periodic location updates.</p> diff --git a/docs/html/training/location/index.jd b/docs/html/training/location/index.jd index 8ed207112c9c..dd6825cf1435 100644 --- a/docs/html/training/location/index.jd +++ b/docs/html/training/location/index.jd @@ -79,6 +79,10 @@ href="https://www.youtube.com/watch?v=S8sugXgUVEI"> Learn how to retrieve the last known location of an Android device, which is usually equivalent to the user's current location. </dd> <dt> + <b><a href="change-location-settings.html">Changing Location Settings</a></b> + <dt> <dd> + Learn how to detect and apply system settings for location features. + </dd> <dt> <b><a href="receive-location-updates.html">Receiving Location Updates</a></b> </dt> <dd> diff --git a/docs/html/training/location/receive-location-updates.jd b/docs/html/training/location/receive-location-updates.jd index 208dc1799faf..d82905f909d5 100644 --- a/docs/html/training/location/receive-location-updates.jd +++ b/docs/html/training/location/receive-location-updates.jd @@ -7,8 +7,7 @@ trainingnavtop=true <h2>This lesson teaches you how to</h2> <ol> - <li><a href="#connect">Connect to Location Services</a></li> - <li><a href="#location-request">Set Up a Location Request</a></li> + <li><a href="#get-last-location">Get the Last Known Location</a></li> <li><a href="#updates">Request Location Updates</a></li> <li><a href="#callback">Define the Location Update Callback</a></li> <li><a href="#stop-updates">Stop Location Updates</a></li> @@ -19,7 +18,7 @@ trainingnavtop=true <ul> <li> <a href="{@docRoot}google/play-services/setup.html">Setting up Google Play - Services</a> + Services</a> </li> <li> <a href="retrieve-current.html">Getting the Last Known Location</a> @@ -64,16 +63,7 @@ trainingnavtop=true <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#requestLocationUpdates(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.location.LocationRequest, com.google.android.gms.location.LocationListener)">{@code requestLocationUpdates()}</a> method in the fused location provider. -<h2 id="connect">Connect to Location Services</h2> - -<p>Location services for apps are provided through Google Play services and the - fused location provider. In order to use these services, you connect your app - using the Google API Client and then request location updates. For details on - connecting with the - <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html">{@code GoogleApiClient}</a>, - follow the instructions in - <a href="retrieve-current.html">Getting the Last Known Location</a>, including - requesting the current location.</p> +<h2 id="get-last-location">Get the Last Known Location</h2> <p>The last known location of the device provides a handy base from which to start, ensuring that the app has a known location before starting the @@ -101,112 +91,13 @@ trainingnavtop=true </manifest> </pre> -<h2 id="location-request">Set Up a Location Request</h2> - -<p>To store parameters for requests to the fused location provider, create a - <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html">{@code LocationRequest}</a>. - The parameters determine the levels of accuracy requested. For details of all - the options available in the location request, see the - <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html">{@code LocationRequest}</a> - class reference. This lesson sets the update interval, fastest update - interval, and priority, as described below:</p> - -<dl> - <dt> - Update interval - </dt> - <dd> - <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">{@code setInterval()}</a> - - This method sets the rate in milliseconds at which your app prefers to - receive location updates. Note that the location updates may be faster than - this rate if another app is receiving updates at a faster rate, or slower - than this rate, or there may be no updates at all (if the device has no - connectivity, for example). - </dd> - <dt> - Fastest update interval - </dt> - <dd> - <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">{@code setFastestInterval()}</a> - - This method sets the <strong>fastest</strong> rate in milliseconds at which - your app can handle location updates. You need to set this rate because - other apps also affect the rate at which updates are sent. The Google Play - services location APIs send out updates at the fastest rate that any app - has requested with - <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)">{@code setInterval()}</a>. - If this rate is faster - than your app can handle, you may encounter problems with UI flicker or data - overflow. To prevent this, call - <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setFastestInterval(long)">{@code setFastestInterval()}</a> - to set an upper limit to the update rate. - </dd> - <dt>Priority</dt> - <dd> - <p> - <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setPriority(int)">{@code setPriority()}</a> - - This method sets the priority of the request, which gives the Google Play - services location services a strong hint about which location sources to use. - The following values are supported:</p> - <ul> - <li> - <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_BALANCED_POWER_ACCURACY">{@code PRIORITY_BALANCED_POWER_ACCURACY}</a> - - Use this setting to request location precision to within a city - block, which is an accuracy of approximately 100 meters. This is - considered a coarse level of accuracy, and is likely to consume less - power. With this setting, the location services are likely to use WiFi - and cell tower positioning. Note, however, that the choice of location - provider depends on many other factors, such as which sources are - available.</li> - <li> - <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_HIGH_ACCURACY">{@code PRIORITY_HIGH_ACCURACY}</a> - - Use this setting to request the most precise location possible. With - this setting, the location services are more likely to use GPS - (Global Positioning System) to determine the location.</li> - <li><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_LOW_POWER">{@code PRIORITY_LOW_POWER}</a> - - Use this setting to request city-level precision, which is - an accuracy of approximately 10 kilometers. This is considered a - coarse level of accuracy, and is likely to consume less power.</li> - <li><a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_NO_POWER">{@code PRIORITY_NO_POWER}</a> - - Use this setting if you need negligible impact on power consumption, - but want to receive location updates when available. With this - setting, your app does not trigger any location updates, but - receives locations triggered by other apps.</li> - </ul> - </dd> -</dl> - -<p>Create the location request and set the parameters as shown in this - code sample:</p> - -<pre> -protected void createLocationRequest() { - LocationRequest mLocationRequest = new LocationRequest(); - mLocationRequest.setInterval(10000); - mLocationRequest.setFastestInterval(5000); - mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); -} -</pre> - -<p>The priority of - <a href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#PRIORITY_HIGH_ACCURACY">{@code PRIORITY_HIGH_ACCURACY}</a>, - combined with the - {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} - permission setting that you've defined in the app manifest, and a fast update - interval of 5000 milliseconds (5 seconds), causes the fused location - provider to return location updates that are accurate to within a few feet. - This approach is appropriate for mapping apps that display the location in - real time.</p> - -<p class="note"><strong>Performance hint:</strong> If your app accesses the - network or does other long-running work after receiving a location update, - adjust the fastest interval to a slower value. This adjustment prevents your - app from receiving updates it can't use. Once the long-running work is done, - set the fastest interval back to a fast value.</p> - <h2 id="updates">Request Location Updates</h2> -<p>Now that you've set up a location request containing your app's requirements - for the location updates, you can start the regular updates by calling +<p>Before requesting location updates, your app must connect to location + services and make a location request. The lesson on + <a href="change-location-settings.html">Changing Location Settings</a> + shows you how to do this. Once a location request is in place you can start + the regular updates by calling <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#requestLocationUpdates(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.location.LocationRequest, com.google.android.gms.location.LocationListener)">{@code requestLocationUpdates()}</a>. Do this in the <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)">{@code onConnected()}</a> diff --git a/docs/html/training/location/retrieve-current.jd b/docs/html/training/location/retrieve-current.jd index 206345f64b87..c49b666c77bb 100644 --- a/docs/html/training/location/retrieve-current.jd +++ b/docs/html/training/location/retrieve-current.jd @@ -77,7 +77,7 @@ trainingnavtop=true <pre> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.android.gms.location.sample.basiclocationsample" > - + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> </manifest> </pre> @@ -180,5 +180,6 @@ public class MainActivity extends ActionBarActivity implements when the location is not available.</p> <p>The next lesson, - <a href="receive-location-updates.html">Receiving Location Updates</a>, shows - you how to receive periodic location updates.</p> + <a href="change-location-settings.html">Changing Location Settings</a>, shows + you how to detect the current location settings, and prompt the user to + change settings as appropriate for your app's requirements.</p> diff --git a/docs/html/training/testing/index.jd b/docs/html/training/testing/index.jd new file mode 100644 index 000000000000..d6405c8a3530 --- /dev/null +++ b/docs/html/training/testing/index.jd @@ -0,0 +1,72 @@ +page.title=Best Practices for Testing +page.article=true +page.image=images/testing/hwtest_junit_success.png + +meta.tags="testing" +page.tags="testing" + +page.metaDescription=Starting point for testing Android apps, with guidelines, information, and examples. + +@jd:body + +<img src="/images/testing/testing-icon.png" +style="float:right; margin:0 0 20px 30px" width="245" height="229" /> + +<p> + Testing your app is an integral part of the app development process. Testing allows you to verify + the correctness, functional behavior, and usability of your app before it is released publicly. +</p> +<br> +<br> + +<h2 id="start">Get Started</h2> + +<p> + Learn the basics of testing your app, with information about building and running your tests with + Android Studio: +</p> + +<div class="resource-widget resource-flow-layout col-12" + data-query="collection:training/testing/overview" + data-cardSizes="6x3" + data-maxresults="3"> +</div> + + +<h2 id="tools">Testing Tools and APIs</h2> + +<p> + Learn about the tools provided by the Android platform that help you test every aspect of your app + at every level: +</p> + +<div class="resource-widget resource-flow-layout landing col-12" + data-query="collection:training/testing/tools" + data-cardSizes="15x3, 9x2, 9x2, 9x2, 9x2" + data-maxResults="5"> +</div> + + +<h2 id="techniques">App Testing Techniques</h2> + +<p> + Learn techniques for testing your apps: +</p> + +<div class="resource-widget resource-flow-layout landing col-12" + data-query="collection:training/testing/techniques" + data-cardSizes="6x3 + data-maxResults="3"> +</div> + +<h2 id="resources">Other Resources</h2> + +<p> + More resources for app testing: +</p> + +<div class="resource-widget resource-flow-layout landing col-12" + data-query="collection:training/testing/resources" + data-cardSizes="9x3" + data-maxResults="6"> +</div>
\ No newline at end of file diff --git a/docs/html/training/testing/integration-testing/content-provider-testing.jd b/docs/html/training/testing/integration-testing/content-provider-testing.jd new file mode 100644 index 000000000000..75869d9d1794 --- /dev/null +++ b/docs/html/training/testing/integration-testing/content-provider-testing.jd @@ -0,0 +1,174 @@ +page.title=Testing Your Content Provider +page.tags=testing, content provider +trainingnavtop=true + +@jd:body + +<!-- This is the training bar --> +<div id="tb-wrapper"> +<div id="tb"> + <h2>Dependencies and Prerequisites</h2> + + <ul> + <li>Android 2.2 (API level 8) or higher</li> + <li><a href="{@docRoot}tools/testing-support-library/index.html"> + Android Testing Support Library</a></li> + <li><a href="{@docRoot}tools/studio/index.html">Android Studio 1.4.1 or higher</a>.</li> + </ul> + + <h2>This lesson teaches you to</h2> + + <ol> + <li><a href="#build">Create Integration Tests for Content Providers</a></li> + <li><a href="#WhatToTest">What to Test</a></li> + </ol> + + <h2>You should also read</h2> + <ul> + <li><a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> + </li> + </ul> +</div> +</div> + +<p> + If you are implementing a <a href="{@docRoot}guide/topics/providers/content-providers.html"> + content provider</a> to store and retrieve data or to make data + accessible to other apps, you should test your provider to ensure that it doesn't behave in an + unexpected way. This lesson describes how to test public content providers, and is also + applicable to providers that you keep private to your own app. +</p> +<h2 id="build">Create Integration Tests for Content Providers</h2> +<p> +In Android, apps view content providers as data APIs that provide +tables of data, with their internals hidden from view. A content provider may have many +public constants, but it usually has few if any public methods and no public variables. +For this reason, you should write your tests based only on the provider's public members. +A content provider that is designed like this is offering a contract between itself and its users. +</p> +<p> +Content providers let you access actual user data, so it's important to ensure +that you test the content provider in an isolated testing environment. This approach allows you to +only run against data dependencies set explicitly in the test case. It also means that your tests +do not modify actual user data. For example, you should avoid writing a test that fails because +there was data left over from a previous test. Similarly, your test should avoid adding or deleting +actual contact information in a provider. +</p> + +<p> +To test your content provider in isolation, use the {@link android.test.ProviderTestCase2} class. +This class allows you to use Android mock object classes such as {@link android.test.IsolatedContext} +and {@link android.test.mock.MockContentResolver} to access file and database information without +affecting the actual user data. +</p> + +<p>Your integration test should be written as a JUnit 4 test class. To learn more about creating +JUnit 4 test classes and using JUnit 4 assertions, see +<a href="{@docRoot}training/testing/unit-testing/local-unit-tests.html#build"> +Create a Local Unit Test Class</a>.</p> + +<p>To create an integration test for your content provider, you must perform these steps:</p> +<ul> + <li>Create your test class as a subclass of {@link android.test.ProviderTestCase2}.</li> + <li>Add the +{@code @RunWith(AndroidJUnit4.class)} annotation at the beginning of your test class +definition.</li> + <li>Specify the +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> +{@code AndroidJUnitRunner}</a> class that the +<a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a> +provides as your default test runner. This step is described in more detail in +<a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests"> +Getting Started with Testing</a>.</li> + <li>Set the {@link android.content.Context} object from the +<a href="{@docRoot}reference/android/support/test/InstrumentationRegistry.html"> +{@code InstrumentationRegistry}</a> class. See the snippet below for an example. + <pre> +@Override +protected void setUp() throws Exception { + setContext(InstrumentationRegistry.getTargetContext()); + super.setUp(); +}</pre> + </li> +</ul> + +<h3 id="ProviderTestCase2">How ProviderTestCase2 works</h3> +<p> + You test a provider with a subclass of {@link android.test.ProviderTestCase2}. This base class + extends {@link android.test.AndroidTestCase}, so it provides the JUnit testing framework as well + as Android-specific methods for testing application permissions. The most important + feature of this class is its initialization, which creates the isolated test environment. +</p> +<p> + The initialization is done in the constructor for {@link android.test.ProviderTestCase2}, which + subclasses call in their own constructors. The {@link android.test.ProviderTestCase2} + constructor creates an {@link android.test.IsolatedContext} object that allows file and + database operations but stubs out other interactions with the Android system. + The file and database operations themselves take place in a directory that is local to the + device or emulator and has a special prefix. +</p> +<p> + The constructor then creates a {@link android.test.mock.MockContentResolver} to use as the + resolver for the test. +</p> +<p> + Lastly, the constructor creates an instance of the provider under test. This is a normal + {@link android.content.ContentProvider} object, but it takes all of its environment information + from the {@link android.test.IsolatedContext}, so it is restricted to + working in the isolated test environment. All of the tests done in the test case class run + against this isolated object. +</p> + +<p> +You run integration tests for content providers the same way as instrumented unit tests. To run the +integration test for your content provider, follow the steps described in <a +href="{@docRoot}training/testing/unit-testing/instrumented-unit-tests.html#run"> +Run Instrumented Unit Tests</a>. +</p> + +<h2 id="WhatToTest">What to Test</h2> +<p> +Here are some specific guidelines for testing content providers. +</p> +<ul> + <li> + Test with resolver methods: Even though you can instantiate a provider object in + {@link android.test.ProviderTestCase2}, you should always test with a resolver object + using the appropriate URI. Doing so ensures that you are testing the provider by performing + the same interaction that a regular application would use. + </li> + <li> + Test a public provider as a contract: If you intend your provider to be public and + available to other applications, you should test it as a contract. Some examples of how to + do so are as follows: + <ul> + <li> + Test with constants that your provider publicly exposes. For + example, look for constants that refer to column names in one of the provider's + data tables. These should always be constants publicly defined by the provider. + </li> + <li> + Test all the URIs that your provider offers. Your provider may offer several URIs, + each one referring to a different aspect of the data. + </li> + <li> + Test invalid URIs: Your unit tests should deliberately call the provider with an + invalid URI, and look for errors. A good provider design is to throw an + {@code IllegalArgumentException} for invalid URIs. + + </li> + </ul> + </li> + <li> + Test the standard provider interactions: Most providers offer six access methods: + {@code query()}, {@code insert()}, {@code delete()}, {@code update()}, + {@code getType()}, and {@code onCreate()}. Your tests should verify that all + of these methods work. These methods are described in more detail in the topic + <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>. + </li> + <li> + Test business logic: If the content provider implements business logic, you should test it. + Business logic includes handling of invalid values, financial or arithmetic calculations, + elimination or combining of duplicates. + </li> +</ul>
\ No newline at end of file diff --git a/docs/html/training/testing/integration-testing/index.jd b/docs/html/training/testing/integration-testing/index.jd new file mode 100644 index 000000000000..d7ce899f16e1 --- /dev/null +++ b/docs/html/training/testing/integration-testing/index.jd @@ -0,0 +1,55 @@ +page.title=Testing App Component Integrations +page.tags=testing,integration + +trainingnavtop=true +startpage=true + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + <h2> + You should also read + </h2> + <ul> + <li> + <a href="{@docRoot}tools/testing-support-library/index.html">Testing Support Library</a> + </li> + </ul> +</div> +</div> + +<p> +If your app uses components that users do not directly interact with, such as +a <a href="{@docRoot}guide/components/services.html">Service</a> or +<a href="{@docRoot}guide/topics/providers/content-providers.html">Content Provider</a>, you +should validate that these components behave in a correct way with your app.</p> +<p>When developing such components, you should get into the habit of writing +<em>integration tests</em> in order to validate the component's behavior when your app runs on a +device or an emulator.</p> + +<p class="note"><strong>Note:</strong> Android does not provide a separate test case class for +{@link android.content.BroadcastReceiver}. To verify that a +{@link android.content.BroadcastReceiver} responds correctly, you can test the component that sends +it an {@link android.content.Intent} object. Alternatively, you can create an instance of your +{@link android.content.BroadcastReceiver} by calling +<a href="{@docRoot}reference/android/support/test/InstrumentationRegistry.html#getContext()"> +{@code InstrumentationRegistry.getTargetContext()}</a>, then call the +{@link android.content.BroadcastReceiver} method that you want to test (usually, this is +the +{@link android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent) +onReceive()} method).</p> + +<p>This class teaches you to build automated integration tests using the testing APIs and tools +that the Android platform provides.</p> +<h2>Lessons</h2> +<dl> + <dt><strong><a href="service-testing.html"> +Testing Your Service</a></strong></dt> + <dd>Learn how to build integration tests to verify that a service works correctly with your + app.</dd> + <dt><strong><a href="content-provider-testing.html"> +Testing Your Content Provider</a></strong></dt> + <dd>Learn how to build integration tests to verify that a content provider works correctly with + your app.</dd> +</dl>
\ No newline at end of file diff --git a/docs/html/training/testing/integration-testing/service-testing.jd b/docs/html/training/testing/integration-testing/service-testing.jd new file mode 100644 index 000000000000..7b420acede05 --- /dev/null +++ b/docs/html/training/testing/integration-testing/service-testing.jd @@ -0,0 +1,140 @@ +page.title=Testing Your Service +page.tags=testing, service +trainingnavtop=true + +@jd:body + +<!-- This is the training bar --> +<div id="tb-wrapper"> +<div id="tb"> + <h2>Dependencies and Prerequisites</h2> + + <ul> + <li>Android 2.2 (API level 8) or higher</li> + <li><a href="{@docRoot}tools/testing-support-library/index.html"> + Android Testing Support Library</a></li> + <li><a href="{@docRoot}tools/studio/index.html">Android Studio 1.4.1 or higher</a>.</li> + </ul> + + <h2>This lesson teaches you to</h2> + + <ol> + <li><a href="#setup">Set Up Your Testing Environment</a></li> + <li><a href="#build">Create an Integrated Test for Services</a></li> + <li><a href="#run">Run Integration Tests for Services</a></li> + </ol> + + <h2>You should also read</h2> + <ul> + <li><a href="{@docRoot}guide/components/services.html">Services</a></li> + </ul> + + <h2>Try it out</h2> + + <ul> + <li> +<a href="https://github.com/googlesamples/android-testing/tree/master/integration/ServiceTestRuleSample" +class="external-link">Service Test Code Samples</a></li> + </ul> +</div> +</div> + +<p> +If you are implementing a local {@link android.app.Service} as a component of +your app, you should test the {@link android.app.Service} to ensure that it doesn't behave in an +unexpected way. You can create +<a href="{@docRoot}training/testing/unit-testing/instrumented-unit-tests.html"> +instrumented unit tests</a> to verify that the behavior in the {@link android.app.Service} +is correct; for example, the service stores and returns valid data values and performs +data operations correctly. +</p> + +<p> +The <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a> +provides an API for testing your {@link android.app.Service} objects in isolation. +The +<a href="{@docRoot}reference/android/support/test/rule/ServiceTestRule.html">ServiceTestRule</a> +class is a JUnit 4 rule that starts your service before your unit test methods +run, and shuts down the service after tests complete. By using this test rule, you ensure that the +connection to the service is always established before your test method runs. To +learn more about JUnit 4 rules, see the <a href="https://github.com/junit-team/junit/wiki/Rules" +class="external-link">JUnit documentation</a>. +</p> + +<p style="note"> +<strong>Note</strong>: The +<a href="{@docRoot}reference/android/support/test/rule/ServiceTestRule.html">ServiceTestRule</a> +class does not support testing of {@link android.app.IntentService} objects. +If you need to test a {@link android.app.IntentService} object, you should encapsulate the logic +in a separate class and create a corresponding unit test instead. +</p> + +<h2 id="setup">Set Up Your Testing Environment</h2> +<p>Before building your integration test for the service, make sure to configure your project for + instrumented tests, as described in +<a href="{@docRoot}training/testing/start/index.html#config-instrumented-tests"> +Getting Started with Testing</a>.</p> + +<h2 id="build">Create an Integration Test for Services</h2> +<p>Your integration test should be written as a JUnit 4 test class. To learn more about creating +JUnit 4 test classes and using JUnit 4 assertion methods, see +<a href="{@docRoot}training/testing/unit-testing/instrumented-unit-tests.html#build"> +Create an Instrumented Unit Test Class</a>.</p> + +<p>To create an integration test for your service, add the {@code @RunWith(AndroidJUnit4.class)} +annotation at the beginning of your test class definition. You also need to specify the +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> +{@code AndroidJUnitRunner}</a> class that the Android Testing Support Library provides as your +default test runner. This step is described in more detail in +<a href="{@docRoot}training/testing/unit-testing/instrumented-unit-tests.html#run"> +Run Instrumented Unit Tests</a>.</p> + +<p>Next, create a +<a href="{@docRoot}reference/android/support/test/rule/ServiceTestRule.html">ServiceTestRule</a> +instance in your test by using the {@code @Rule} annotation.</p> + +<pre> +@Rule +public final ServiceTestRule mServiceRule = new ServiceTestRule(); +</pre> + +<p>The following example shows how you might implement an integration test for a service. +The test method {@code testWithBoundService} verifies that the app binds successfully to a +local service and that the service interface behaves correctly.</p> + +<pre> +@Test +public void testWithBoundService() throws TimeoutException { + // Create the service Intent. + Intent serviceIntent = + new Intent(InstrumentationRegistry.getTargetContext(), + LocalService.class); + + // Data can be passed to the service via the Intent. + serviceIntent.putExtra(LocalService.SEED_KEY, 42L); + + // Bind the service and grab a reference to the binder. + IBinder binder = mServiceRule.bindService(serviceIntent); + + // Get the reference to the service, or you can call + // public methods on the binder directly. + LocalService service = + ((LocalService.LocalBinder) binder).getService(); + + // Verify that the service is working correctly. + assertThat(service.getRandomInt(), is(any(Integer.class))); +} +</pre> + +<h2 id="run">Run Integration Tests for Services</h2> +<p> +You can run integration tests from <a href="{@docRoot}sdk/index.html">Android Studio</a> or +from the command-line. Make sure to specify +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> + {@code AndroidJUnitRunner}</a> as the default instrumentation runner in your project. +</p> +<p> +To run the integration test for your service, follow the steps for running instrumented tests +described in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests"> +Getting Started with Testing</a>. +</p> diff --git a/docs/html/training/testing/performance.jd b/docs/html/training/testing/performance.jd index 2b968b376e5c..8592c0f85120 100644 --- a/docs/html/training/testing/performance.jd +++ b/docs/html/training/testing/performance.jd @@ -28,6 +28,7 @@ page.keywords=performance, fps, tools </ul> </li> </ol> + </div> </div> diff --git a/docs/html/training/testing/start/index.jd b/docs/html/training/testing/start/index.jd new file mode 100644 index 000000000000..a4b4aea9ef01 --- /dev/null +++ b/docs/html/training/testing/start/index.jd @@ -0,0 +1,252 @@ +page.title=Getting Started with Testing +page.tags="testing" +page.article=true +page.image=images/tools/studio-main-screen.png + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<!-- Required platform, tools, add-ons, devices, knowledge, etc. --> +<h2>Dependencies and prerequisites</h2> +<ul> + <li><a href="{@docRoot}tools/studio/index.html">Android Studio (latest version)</a>.</li> +</ul> + +<h2>This lesson teaches you to</h2> +<ol> +<li><a href="#setup">Set Up Your Testing Environment</a></li> +<li><a href="#build">Build and Run Your Tests</a></li> +</ol> + +<h2>You Should Also Read</h2> +<ul> +<li><a href="{@docRoot}tools/testing/testing_android.html">Testing Concepts</a></li> +<li><a href="https://github.com/googlesamples/android-testing" + class="external-link">Android Testing Samples</a></li> +<li><a href="{@docRoot}about/dashboards/index.html">Android Dashboards</a></li> +</ul> + +</div> +</div> + +<p>You should be writing and running tests as part of your Android app development cycle. +Well-written tests can help you catch bugs early in development and give you confidence in your +code.</p> + +<p>To verify specific behavior in your app, and to check for consistency across different Android +devices, you can write a <a href="//en.wikipedia.org/wiki/Test_case" +class="external-link">test case</a>. This lesson teaches you how to build a test case using the +JUnit 4 framework and the testing APIs and tools provided by Google, and how to run your +tests.</p> + +<h2 id="setup">Set Up Your Testing Environment</h2> + +<p>Before you start writing and running your tests, you must set up your test +development environment. Android Studio provides an integrated development environment for you to +create, build, and run Android app test cases from a graphical user interface (GUI).</p> + +<p>You must first download the prerequisite Android development tools before proceeding: +<ul> +<li><a href="{@docRoot}sdk/index.html">Android Studio</a> (latest version).</li> +<li>The latest Android Support Repository using the + <a href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a>. </li> +</ul> + +<p>Based on the type of test you want to create, configure the test code source location and the + project dependencies in Android Studio as described in the following sections.</p> + +<h3 id="config-local-tests">Configure Your Project for Local Unit Tests</h3> +<p><em>Local unit tests</em> are tests that run on your local machine, without needing access to the +Android framework or an Android device. To learn how to develop local units tests, see +<a href="{@docRoot}training/testing/unit-testing/local-unit-tests.html"> +Building Local Unit Tests</a>.</p> +<p>In your Android Studio project, you must store the source files for local unit tests under a +specific source directory ({@code src/test/java}). This feature improves your project organization +by letting you group your unit tests together into a single source set.</p> +<p>As with production code, you can create local unit tests for a +<a href="http://developer.android.com/tools/building/configuring-gradle.html#workBuildVariants" +class="external-link">specific flavor or build type</a>. Keep your unit tests in a test +source tree location that corresponds to your production source tree, such as:</p> + +<table> +<tr> +<th>Path to Production Class</th> +<th>Path to Local Unit Test Class</th> +</tr> +<tr> +<td>{@code src/main/java/Foo.java}</td> +<td>{@code src/test/java/FooTest.java}</td> +</tr> +<tr> +<td>{@code src/debug/java/Foo.java}</td> +<td>{@code src/testDebug/java/FooTest.java}</td> +</tr> +<tr> +<td>{@code src/myFlavor/java/Foo.java}</td> +<td>{@code src/testMyFlavor/java/FooTest.java}</td> +</tr> +</table> + +<p>You'll need to configure the testing dependencies for your project to use the + standard APIs provided by the JUnit 4 framework. To simplify your local unit test development, + we recommend that you include the <a href="https://github.com/mockito/mockito" + class="external-link">Mockito</a> library if your test needs to interact with Android + dependencies. To learn more about using mock objects in your local unit tests, see +<a href="{@docRoot}training/testing/unit-testing/local-unit-tests.html#mocking-dependencies"> + Mocking Android dependencies</a>.</p> +<p>In the {@code build.gradle} file of your Android app module, specify your dependencies like +this:</p> + +<pre> +dependencies { + // Required -- JUnit 4 framework + testCompile 'junit:junit:4.12' + // Optional -- Mockito framework + testCompile 'org.mockito:mockito-core:1.10.19' +} +</pre> + +<h3 id="config-instrumented-tests">Configure Your Project for Instrumented Tests</h3> +<p><em>Instrumented tests</em> are tests that run on an Android device or emulator. These tests +have access to {@link android.app.Instrumentation} information, such as the +{@link android.content.Context} for the app under test. Instrumented tests can be used for unit, +user interface (UI), or app component integration testing. To learn how to develop instrumented +tests for your specific needs, see these additional topics: +<ul> +<li><a href="{@docRoot}training/testing/unit-testing/instrumented-unit-tests.html"> + Building Instrumented Unit Tests</a> - Build more complex unit tests that have Android + dependencies which cannot be easily filled by using mock objects.</li> +<li><a href="{@docRoot}training/testing/ui-testing/index.html"> + Automating User Interface Tests</a> - Create tests to verify that the user interface behaves + correctly for user interactions within a single app or for interactions across multiple apps.</li> +<li><a href="{@docRoot}training/testing/integration-testing/index.html"> + Testing App Component Integrations</a> - Verify the behavior of components that users do not +directly interact with, such as a <a href="{@docRoot}guide/components/services.html">Service</a> or +a <a href="guide/topics/providers/content-providers.html">Content Provider</a>.</li> +</ul> +</p> +<p> +In your Android Studio project, you must place the source code for your instrumentated tests under +a specific directory (<code>src/androidTest/java</code>). +</p> +<p> +Download the Android Testing Support Library, which provides APIs that allow you to quickly build and +run instrumented test code for your apps. The Testing Support Library includes a JUnit 4 test runner +(<a href="{@docRoot}tools/testing-support-library/index.html#AndroidJUnitRunner">AndroidJUnitRunner +</a>) and APIs for functional UI tests +(<a href="{@docRoot}tools/testing-support-library/index.html#Espresso">Espresso</a> and +<a href="{@docRoot}tools/testing-support-library/index.html#UIAutomator">UI Automator</a>). To +learn how to install the library, see +<a href="{@docRoot}tools/testing-support-library/index.html#setup">Testing Support Library Setup</a>. +</p> +<p>You'll need to configure the Android testing dependencies for your project to use the test runner +and the rules APIs provided by the Testing Support Library. To simplify your test development, +we also recommend that you include the <a href="https://github.com/hamcrest" +class="external-link">Hamcrest</a> library, which lets you create more flexible assertions using the +Hamcrest matcher APIs.</p> +<p>In the {@code build.gradle} file of your Android app module, specify your dependencies like +this:</p> +<pre> +dependencies { + androidTestCompile 'com.android.support:support-annotations:23.0.1' + androidTestCompile 'com.android.support.test:runner:0.4.1' + androidTestCompile 'com.android.support.test:rules:0.4.1' + // Optional -- Hamcrest library + androidTestCompile 'org.hamcrest:hamcrest-library:1.3' + // Optional -- UI testing with Espresso + androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1' + // Optional -- UI testing with UI Automator + androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1' +} +</pre> + +<h2 id="build">Build and Run Your Tests</h2> + +<p>You can run build and run your tests in a similar way to how you run your Android apps -- + graphically in Android Studio or from the command-line using the +<a href="{@docRoot}tools/building/plugin-for-gradle.html"> +Android Plugin for Gradle</a>.</p> + +<h3 id="run-local-tests">Run Local Unit Tests</h3> +<p> +The Android Plugin for Gradle compiles the local unit test code located in the default directory +({@code src/test/java}), builds a test app, and executes it locally +using the default test runner class. +</p> +<p> +To run local unit tests in your Gradle project from Android Studio: +</p> +<ol> +<li>In the <strong>Project</strong> window, right click on the project and synchronize your project. +</li> +<li>Open the <strong>Build Variants</strong> window by clicking the left-hand tab, then change the +test artifact to <em>Unit Tests</em>. +</li> +<li>In the <strong>Project</strong> window, drill down to your unit test class or method, +then right-click and run it. To run all tests in the unit test directory, select the directory then +right-click and press <strong>Run tests</strong>. +</li> +</ol> + +<p>Android Studio displays the results of the unit test execution in the <strong>Run</strong> +window.</p> + +<p>To run local unit tests in your Gradle project from the command-line, call the {@code test} task +command.</p> + +<pre> +./gradlew test +</pre> + +<p>If there are failing tests, the command will display links to HTML reports (one per build +variant). You can find the generated HTML test result reports in the +{@code <path_to_your_project>/app/build/reports/tests/} directory, and the corresponding XML +files in the {@code <path_to_your_project>/app/build/test-results/} directory.</p> + +<h3 id="run-instrumented-tests">Run Instrumented Tests</h3> +<p> +The Android Plugin for Gradle compiles the instrumented test code located in the default directory +({@code src/androidTest/java}), builds a test APK and production APK, installs both APKs on the +connected device or emulator, and executes the tests.</p> + +<p>Make sure to specify +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> +{@code AndroidJUnitRunner}</a> as the default test instrumentation runner in your project. To do +this, add the following setting in your {@code build.gradle} file:</p> + +<pre> +android { + defaultConfig { + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } +} +</pre> + +<p>To run your instrumented tests in Android Studio:</p> +<ol> +<li>Open the <strong>Build Variants</strong> window by clicking the left-hand tab, then set the +test artifact to <em>Android Instrumentation Tests</em>. +</li> +<li>In the <strong>Project</strong> window, drill down to your instrumented test class or method, + then right-click and run it using the Android Test configuration. To run all tests in the +instrumented test directory, select the directory then right-click and press +<strong>Run tests</strong>. +</li> +</ol> + +<p>Android Studio displays the results of the instrumented test execution in the +<strong>Run</strong> window.</p> + +<p>To run your instrumented tests from the command-line via Gradle, call the + {@code connectedAndroidTest} (or {@code cAT}) task:</p> + +<pre> +./gradlew cAT +</pre> + +<p>You can find the generated HTML test result reports in the +{@code <path_to_your_project>/app/build/outputs/reports/androidTests/connected/} directory, +and the corresponding XML files in the +{@code <path_to_your_project>/app/build/outputs/androidTest-results/connected/} directory.</p>
\ No newline at end of file diff --git a/docs/html/training/testing/ui-testing/espresso-testing.jd b/docs/html/training/testing/ui-testing/espresso-testing.jd index 72689ff49f1f..45a4ceba279b 100644 --- a/docs/html/training/testing/ui-testing/espresso-testing.jd +++ b/docs/html/training/testing/ui-testing/espresso-testing.jd @@ -55,6 +55,8 @@ trainingnavtop=true <a href="https://github.com/googlesamples/android-testing" class="external-link">Espresso Code Samples</a> </li> + <li><a href="https://www.code-labs.io/codelabs/android-testing/index.html?index=..%2F..%2Findex#0" + class="external-link">Android Testing Codelab</a></li> </ul> </div> </div> @@ -90,75 +92,51 @@ trainingnavtop=true Set Up Espresso </h2> - <p> - Before you begin using Espresso, you must: - </p> - - <ul> - <li> - <strong>Install the Android Testing Support Library</strong>. The Espresso API is - located under the {@code com.android.support.test.espresso} package. These classes allow - you to create tests that use the Espresso testing framework. To learn how to install the - library, see <a href="{@docRoot}tools/testing-support-library/index.html#setup"> - Testing Support Library Setup</a>. - </li> +<p>Before building your UI test with Espresso, make sure to configure your test source code +location and project dependencies, as described in +<a href="{@docRoot}training/testing/start/index.html#config-instrumented-tests"> +Getting Started with Testing</a>.</p> - <li> - <strong>Set up your project structure.</strong> In your Gradle project, the source code for - the target app that you want to test is typically placed under the {@code app/src/main} - folder. The source code for instrumentation tests, including - your Espresso tests, must be placed under the <code>app/src/androidTest</code> folder. To - learn more about setting up your project directory, see - <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>. - </li> - - <li> - <strong>Specify your Android testing dependencies</strong>. In order for the - <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a> to - correctly build and run your Espresso tests, you must specify the following libraries in - the {@code build.gradle} file of your Android app module: +<p>In the {@code build.gradle} file of your Android app module, you must set a dependency + reference to the Espresso library:</p> - <pre> +<pre> dependencies { - androidTestCompile 'com.android.support:support-annotations:23.0.1' - androidTestCompile 'com.android.support.test:runner:0.4.1' - androidTestCompile 'com.android.support.test:rules:0.4.1' + ... androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1' - // Set this dependency if you want to use Hamcrest matching - androidTestCompile 'org.hamcrest:hamcrest-library:1.3' } </pre> - </li> - <li> - <strong>Turn off animations on your test device.</strong> Leaving system animations turned - on in the test device might cause unexpected results or may lead your test to fail. Turn - off animations from <em>Settings</em> by opening <em>Developing Options</em> and - turning all the following options off: +<p>Turn off animations on your test device — leaving system animations turned on in the test +device might cause unexpected results or may lead your test to fail. Turn off animations from +<em>Settings</em> by opening <em>Developing Options</em> and turning all the following options off: +</p> <ul> <li> - <em>Window animation scale</em> + <strong>Window animation scale</strong> </li> <li> - <em>Transition animation scale</em> + <strong>Transition animation scale</strong> </li> <li> - <em>Animator duration scale</em> + <strong>Animator duration scale</strong> </li> </ul> </li> </ul> +<p>If you want to set up your project to use Espresso features other than what the core API + provides, see this + <a href="https://google.github.io/android-testing-support-library/docs/espresso/index.html" + class="external-link">resource</a>.</p> <h2 id="build"> Create an Espresso Test Class </h2> <p> - To create an Espresso test, create a Java class or an - {@link android.test.ActivityInstrumentationTestCase2} - subclass that follows this programming model: + To create an Espresso test, create a Java class that follows this programming model: </p> <ol> @@ -203,11 +181,70 @@ onView(withId(R.id.my_view)) // withId(R.id.my_view) is a ViewMatcher .perform(click()) // click() is a ViewAction .check(matches(isDisplayed())); // matches(isDisplayed()) is a ViewAssertion </pre> +<h3 id="espresso-atr">Using Espresso with ActivityTestRule</h3> +<p> +The following section describes how to create a new Espresso test in the JUnit 4 style and use +<a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html"> +{@code ActivityTestRule}</a> to reduce the amount of boilerplate code you need to write. By using +<a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html"> +{@code ActivityTestRule}</a>, the testing framework launches the activity under test +before each test method annotated with {@code @Test} and before any method annotated with +{@code @Before}. The framework handles shutting down the activity after the test finishes +and all methods annotated with {@code @After} are run.</p> + +<pre> +package com.example.android.testing.espresso.BasicSample; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +... + +@RunWith(AndroidJUnit4.class) +@LargeTest +public class ChangeTextBehaviorTest { + + private String mStringToBetyped; + + @Rule + public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>( + MainActivity.class); + + @Before + public void initValidString() { + // Specify a valid string. + mStringToBetyped = "Espresso"; + } + + @Test + public void changeText_sameActivity() { + // Type text and then press the button. + onView(withId(R.id.editTextUserInput)) + .perform(typeText(mStringToBetyped), closeSoftKeyboard()); + onView(withId(R.id.changeTextBt)).perform(click()); + + // Check that the text was changed. + onView(withId(R.id.textToBeChanged)) + .check(matches(withText(mStringToBetyped))); + } +} +</pre> <h3 id="espresso-aitc2"> Using Espresso with ActivityInstrumentationTestCase2 </h3> - +<p>The following section describes how to migrate to Espresso if you have existing test classes +subclassed from {@link android.test.ActivityInstrumentationTestCase2} and you don't want to rewrite +them to use JUnit4.</p> +<p class="note"><strong>Note:</strong> For new UI tests, we strongly recommend that you write your +test in the JUnit 4 style and use the +<a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html"> +{@code ActivityTestRule}</a> class, instead of +{@link android.test.ActivityInstrumentationTestCase2}.</p> <p> If you are subclassing {@link android.test.ActivityInstrumentationTestCase2} to create your Espresso test class, you must inject an @@ -544,40 +581,13 @@ public void testChangeText_sameActivity() { </pre> <h2 id="run">Run Espresso Tests on a Device or Emulator</h2> - - <p> - To run Espresso tests, you must use the - <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> - class provided in the - <a href="{@docRoot}tools/testing-support-library/index.html"> - Android Testing Support Library</a> as your default test runner. The - <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for - Gradle</a> provides a default directory ({@code src/androidTest/java}) for you to store the - instrumented test classes and test suites that you want to run on a device. The - plug-in compiles the test code in that directory and then executes the test app using - the configured test runner class. - </p> - - <p> - To run Espresso tests in your Gradle project: - </p> - - <ol> - <li>Specify - <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> - as the default test instrumentation runner in - your {@code build.gradle} file: - - <pre> -android { - defaultConfig { - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - } -}</pre> - </li> - <li>Run your tests from the command-line by calling the the {@code connectedAndroidTest} - (or {@code cAT}) task: - <pre> -./gradlew cAT</pre> - </li> - </ol> +<p> +You can run Espresso tests from <a href="{@docRoot}sdk/index.html">Android Studio</a> or +from the command-line. Make sure to specify +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> + {@code AndroidJUnitRunner}</a> as the default instrumentation runner in your project. +</p> +<p> +To run your Espresso test, follow the steps for running instrumented tests +described in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests"> +Getting Started with Testing</a>.</p> diff --git a/docs/html/training/testing/ui-testing/index.jd b/docs/html/training/testing/ui-testing/index.jd index d660c601d503..1aa95a412f7e 100644 --- a/docs/html/training/testing/ui-testing/index.jd +++ b/docs/html/training/testing/ui-testing/index.jd @@ -1,5 +1,6 @@ page.title=Automating User Interface Tests page.tags=testing +page.image=images/testing/UIAutomatorViewer.png trainingnavtop=true startpage=true diff --git a/docs/html/training/testing/ui-testing/uiautomator-testing.jd b/docs/html/training/testing/ui-testing/uiautomator-testing.jd index ea15d8b2d1f3..5dca40b81afa 100644 --- a/docs/html/training/testing/ui-testing/uiautomator-testing.jd +++ b/docs/html/training/testing/ui-testing/uiautomator-testing.jd @@ -61,43 +61,21 @@ test runner. </p> <h2 id="setup">Set Up UI Automator</h2> -<p>Before you begin using UI Automator, you must:</p> - <ul> - <li> - <strong>Install the Android Testing Support Library</strong>. The UI Automator API is - located under the {@code com.android.support.test.uiautomator} package. These classes allow - you to create tests that use the Espresso testing framework. To learn how to install the - library, see <a href="{@docRoot}tools/testing-support-library/index.html#setup"> - Testing Support Library Setup</a>. - </li> - - <li> - <strong>Set up your project structure.</strong> In your Gradle project, the source code for - the target app that you want to test is typically placed under the {@code app/src/main} - folder. The source code for instrumentation tests, including - your UI Automator tests, must be placed under the <code>app/src/androidTest</code> folder. - To learn more about setting up your project directory, see - <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>. - </li> - - <li> - <strong>Specify your Android testing dependencies</strong>. In order for the - <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a> to - correctly build and run your UI Automator tests, you must specify the following libraries in - the {@code build.gradle} file of your Android app module: - - <pre> +<p>Before building your UI test with UI Automator, make sure to configure your test source code +location and project dependencies, as described in +<a href="{@docRoot}training/testing/start/index.html#config-instrumented-tests"> +Getting Started with Testing</a>.</p> + +<p>In the {@code build.gradle} file of your Android app module, you must set a dependency + reference to the UI Automator library:</p> + +<pre> dependencies { - androidTestCompile 'com.android.support:support-annotations:23.0.1' - androidTestCompile 'com.android.support.test:runner:0.4.1' + ... androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1' - // Set this dependency if you want to use Hamcrest matching - androidTestCompile 'org.hamcrest:hamcrest-library:1.3' } </pre> - </li> - </ul> <p>To optimize your UI Automator testing, you should first inspect the target app’s UI components and ensure that they are accessible. These optimization tips are described in the next two @@ -257,14 +235,10 @@ and simulate a Home button press:</p> <pre> import org.junit.Before; import android.support.test.runner.AndroidJUnit4; -import android.support.test.InstrumentationRegistry; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.By; import android.support.test.uiautomator.Until; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import static org.junit.Assert.assertThat; +... @RunWith(AndroidJUnit4.class) @SdkSuppress(minSdkVersion = 18) @@ -305,6 +279,10 @@ public class ChangeTextBehaviorTest { } </pre> +<p>In the example, the {@code @SdkSuppress(minSdkVersion = 18)} statement helps to ensure that + tests will only run on devices with Android 4.3 (API level 18) or higher, as required by the + UI Automator framework.</p> + <p>Use the <a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html#findObject(android.support.test.uiautomator.UiSelector)">{@code findObject()}</a> method to retrieve a @@ -533,33 +511,14 @@ public void testTwoPlusThreeEqualsFive() { </pre> <h2 id="run">Run UI Automator Tests on a Device or Emulator</h2> -<p>UI Automator tests are based on the {@link android.app.Instrumentation} class. The -<a href="https://developer.android.com/tools/building/plugin-for-gradle.html"> - Android Plug-in for Gradle</a> -provides a default directory ({@code src/androidTest/java}) for you to store the instrumented test -classes and test suites that you want to run on a device. The plug-in compiles the test -code in that directory and then executes the test app using a test runner class. You are -strongly encouraged to use the -<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> -class provided in the -<a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a> -as your default test runner. </p> - -<p>To run UI Automator tests in your Gradle project:</p> - -<ol> -<li>Specify -<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a> -as the default test instrumentation runner in your {@code build.gradle} file: -<pre> -android { - defaultConfig { - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - } -}</pre> -</li> -<li>Run your tests from the command-line by calling the {@code connectedCheck} - (or {@code cC}) task: -<pre>./gradlew cC</pre> -</li> -</ol>
\ No newline at end of file +<p> +You can run UI Automator tests from <a href="{@docRoot}sdk/index.html">Android Studio</a> or +from the command-line. Make sure to specify +<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> + {@code AndroidJUnitRunner}</a> as the default instrumentation runner in your project. +</p> +<p> +To run your UI Automator test, follow the steps for running instrumented tests +described in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests"> +Getting Started with Testing</a>. +</p>
\ No newline at end of file diff --git a/docs/html/training/testing/unit-testing/index.jd b/docs/html/training/testing/unit-testing/index.jd index a35ba80a1faf..66107612f43d 100644 --- a/docs/html/training/testing/unit-testing/index.jd +++ b/docs/html/training/testing/unit-testing/index.jd @@ -1,5 +1,6 @@ page.title=Building Effective Unit Tests page.tags=testing,androidjunitrunner,junit,unit test +page.image=images/testing/hwtest_junit_success.png trainingnavtop=true startpage=true diff --git a/docs/html/training/testing/unit-testing/instrumented-unit-tests.jd b/docs/html/training/testing/unit-testing/instrumented-unit-tests.jd index db4cc8ca395f..38321eed93b3 100644 --- a/docs/html/training/testing/unit-testing/instrumented-unit-tests.jd +++ b/docs/html/training/testing/unit-testing/instrumented-unit-tests.jd @@ -13,6 +13,7 @@ trainingnavtop=true <li>Android 2.2 (API level 8) or higher</li> <li><a href="{@docRoot}tools/testing-support-library/index.html"> Android Testing Support Library</a></li> + <li><a href="{@docRoot}tools/studio/index.html">Android Studio (latest version)</a>.</li> </ul> <h2>This lesson teaches you to</h2> @@ -29,6 +30,8 @@ trainingnavtop=true <li> <a href="https://github.com/googlesamples/android-testing/tree/master/unit/BasicUnitAndroidTest" class="external-link">Instrumented Unit Tests Code Samples</a></li> + <li><a href="https://www.code-labs.io/codelabs/android-studio-testing/index.html?index=..%2F..%2Findex#0" +class="external-link">Unit and UI Testing in Android Studio (codelab)</a></li> </ul> </div> </div> @@ -46,45 +49,10 @@ and supporting APIs, such as the Android Testing Support Library. </p> <h2 id="setup">Set Up Your Testing Environment</h2> -<p>Before building instrumented unit tests, you must:</p> - - <ul> - <li> - <strong>Install the Android Testing Support Library</strong>. The - <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> - {@code AndroidJUnitRunner}</a> API, located under the - {@code com.android.support.test.runner} package, allows you to - create and run instrumented unit tests. To learn how to install the - library, see <a href="{@docRoot}tools/testing-support-library/index.html#setup"> - Testing Support Library Setup</a>. - </li> - - <li> - <strong>Set up your project structure.</strong> In your Gradle project, the source code for - the target app that you want to test is typically placed under the {@code app/src/main/java} - folder. The source code for instrumentatation tests, including your unit tests, must be - placed under the <code>app/src/androidTest/java</code> folder. - To learn more about setting up your project directory, see - <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>. - </li> - - <li> - <strong>Specify your Android testing dependencies</strong>. In order for the - <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a> to - correctly build and run your instrumented unit tests, you must specify the following - libraries in the {@code build.gradle} file of your Android app module: - - <pre> -dependencies { - androidTestCompile 'com.android.support:support-annotations:23.0.1' - androidTestCompile 'com.android.support.test:runner:0.4.1' - androidTestCompile 'com.android.support.test:rules:0.4.1' - // Set this dependency if you want to use Hamcrest matching - androidTestCompile 'org.hamcrest:hamcrest-library:1.3' -} -</pre> - </li> - </ul> +<p>Before building your instrumented unit test, make sure to configure your test source code +location and project dependencies, as described in +<a href="{@docRoot}training/testing/start/index.html#config-instrumented-tests"> +Getting Started with Testing</a>.</p> <h2 id="build">Create an Instrumented Unit Test Class</h2> <p> @@ -97,8 +65,8 @@ annotation at the beginning of your test class definition. You also need to spec <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> {@code AndroidJUnitRunner}</a> class provided in the Android Testing Support Library as your default test runner. This step is described -in more detail in <a href="#run">Run Instrumented Unit Tests</a>. -</p> +in more detail in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests"> +Getting Started with Testing</p> <p>The following example shows how you might write an instrumented unit test to test that the {@link android.os.Parcelable} interface is implemented correctly for the @@ -115,6 +83,7 @@ import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; @RunWith(AndroidJUnit4.class) +@SmallTest public class LogHistoryAndroidUnitTest { public static final String TEST_STRING = "This is a string"; @@ -195,57 +164,7 @@ public class UnitTestSuite {} <h2 id="run">Run Instrumented Unit Tests</h2> <p> -The -<a href="https://developer.android.com/tools/building/plugin-for-gradle.html"> - Android Plug-in for Gradle</a> -provides a default directory ({@code src/androidTest/java}) for you to store the instrumented unit -and integration test classes and test suites that you want to run on a device. The plug-in compiles -the test code in that directory and then executes the test app using a test runner class. You must -set the -<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> -{@code AndroidJUnitRunner}</a> class provided in the -<a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a> -as your default test runner.</p> -</p> - -<p>To specify -<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> -{@code AndroidJUnitRunner}</a> as the default test instrumentation runner, add the following -setting in your {@code build.gradle} file:</p> -<pre> -android { - defaultConfig { - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - } -} -</pre> - -<h3 id="run-from-Android-Studio">Running instrumented unit tests from Android Studio</h3> -<p> -To run instrumented unit tests in your Gradle project from Android Studio: -</p> -<ol> -<li>Open the <strong>Build Variants</strong> window by clicking the left-hand tab, then set the -test artifact to <em>Android Instrumentation Tests</em>. -</li> -<li>In the <strong>Project</strong> window, drill down to your unit test class or method, then - right-click and run it using the Android Test configuration. -</li> -</ol> - -<p>Android Studio displays the results of the unit test execution in the <strong>Run</strong> -window.</p> - -<h3 id="run-from-commandline">Running instrumented unit tests from the command-line</h3> - -<p>To run instrumented unit tests in your Gradle project from the command-line, call the - {@code connectedCheck} (or {@code cC}) task:</p> - -<pre> -./gradlew cC -</pre> - -<p>You can find the generated HTML test result reports in the -{@code <path_to_your_project>/app/build/outputs/reports/androidTests/connected/} directory, -and the corresponding XML files in the -{@code <path_to_your_project>/app/build/outputs/androidTest-results/connected/} directory.</p>
\ No newline at end of file +To run your test, follow the steps for running instrumented tests +described in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests"> +Getting Started with Testing</a>. +</p>
\ No newline at end of file diff --git a/docs/html/training/testing/unit-testing/local-unit-tests.jd b/docs/html/training/testing/unit-testing/local-unit-tests.jd index 98939fab2386..893d957fcc41 100644 --- a/docs/html/training/testing/unit-testing/local-unit-tests.jd +++ b/docs/html/training/testing/unit-testing/local-unit-tests.jd @@ -10,7 +10,7 @@ trainingnavtop=true <h2>Dependencies and Prerequisites</h2> <ul> - <li>Android Plug-in for Gradle 1.1.0 or higher</li> + <li><a href="{@docRoot}tools/studio/index.html">Android Studio (latest version)</a>.</li> </ul> <h2>This lesson teaches you to</h2> @@ -27,6 +27,8 @@ trainingnavtop=true <li> <a href="https://github.com/googlesamples/android-testing/tree/master/unit/BasicSample" class="external-link">Local Unit Tests Code Samples</a></li> + <li><a href="https://codelabs.developers.google.com/codelabs/android-testing/index.html?index=..%2F..%2Findex#0" +class="external-link">Android Testing Codelab</a></li> </ul> </div> </div> @@ -36,47 +38,15 @@ your test on a local development machine. This testing approach is efficient bec you avoid the overhead of loading the target app and unit test code onto a physical device or emulator every time your test is run. Consequently, the execution time for running your unit test is greatly reduced. With this approach, you normally use a mocking framework, like -<a href="https://code.google.com/p/mockito/" class="external-link">Mockito</a>, to fulfill any +<a href="https://github.com/mockito/mockito" class="external-link">Mockito</a>, to fulfill any dependency relationships.</p> -<p><a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a> -version 1.1.0 and higher allows you to create a source directory ({@code src/test/java}) in your -project to store JUnit tests that you want to run on a local machine. This feature improves your -project organization by letting you group your unit tests together into a single source set. You -can run the tests from Android Studio or the command-line, and the plugin executes them on the -local Java Virtual Machine (JVM) on your development machine. </p> - <h2 id="setup">Set Up Your Testing Environment</h2> -<p>Before building local unit tests, you must:</p> - - <ul> - <li> - <strong>Set up your project structure.</strong> In your Gradle project, the source code for - the target app that you want to test is typically placed under the {@code app/src/main/java} - folder. The source code for your local unit tests must be placed under the - <code>app/src/test/java</code> folder. - To learn more about setting up your project directory, see - <a href="#run">Run Local Unit Tests</a> and - <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>. - </li> +<p>Before building your local unit test, make sure to configure your test source code location and +project dependencies, as described in +<a href="{@docRoot}training/testing/start/index.html#config-local-tests"> +Getting Started with Testing</a>.</p> - <li> - <strong>Specify your Android testing dependencies</strong>. In order to use JUnit 4 and - Mockito with your local unit tests, specify the following libraries in - the {@code build.gradle} file of your Android app module: - - <pre> -dependencies { - // Unit testing dependencies - testCompile 'junit:junit:4.12' - // Set this dependency if you want to use Mockito - testCompile 'org.mockito:mockito-core:1.10.19' - // Set this dependency if you want to use Hamcrest matching - testCompile 'org.hamcrest:hamcrest-library:1.1' -} -</pre> - </li> - </ul> <h2 id="build">Create a Local Unit Test Class</h2> <p>Your local unit test class should be written as a JUnit 4 test class. @@ -116,44 +86,10 @@ public class EmailValidatorTest { <a href="http://junit.org/javadoc/latest/org/junit/Assert.html" class="external-link"> junit.Assert</a> methods to perform validation checks (or <em>assertions</em>) to compare the state of the component under test against some expected value. To make tests more readable, you -can use <a href="https://code.google.com/p/hamcrest/wiki/Tutorial" class="external-link"> +can use <a href="https://github.com/hamcrest" class="external-link"> Hamcrest matchers</a> (such as the {@code is()} and {@code equalTo()} methods) to match the returned result against the expected result.</p> -<p>In your JUnit 4 test class, you can use annotations to call out sections in your test code for -special processing, such as:</p> - -<ul> -<li> -{@code @Before}: Use this annotation to specify a block of code with test setup operations. This -code block will be invoked before each test. You can have multiple {@code @Before} methods but -the order which these methods are called is not fixed. -</li> -<li> -{@code @After}: This annotation specifies a block of code with test tear-down operations. This -code block will be called after every test method. You can define multiple {@code @After} -operations in your test code. Use this annotation to release any resources from memory. -</li> -<li> -{@code @Test}: Use this annotation to mark a test method. A single test class can contain -multiple test methods, each prefixed with this annotation. -</li> -<li> -{@code @BeforeClass}: Use this annotation to specify static methods to be invoked only once per -test class. This testing step is useful for expensive operations such as connecting to a database. -</li> -<li> -{@code @AfterClass}: Use this annotation to specify static methods to be invoked only after all -tests in the class have been run. This testing step is useful for releasing any resources allocated -in the {@code @BeforeClass} block. -</li> -<li> -{@code @Test(timeout=<milliseconds>)}: Specifies a timeout period for the test. If the -test starts but does not complete within the given timeout period, it automatically fails. You must -specify the timeout period in milliseconds, for example: {@code @Test(timeout=5000)}. -</li> -</ul> - <h3 id="mocking-dependencies">Mocking Android dependencies</h3> <p> By default, the <a href="{@docRoot}tools/building/plugin-for-gradle.html"> @@ -166,7 +102,7 @@ You can use a mocking framework to stub out external dependencies in your code, your component interacts with a dependency in an expected way. By substituting Android dependencies with mock objects, you can isolate your unit test from the rest of the Android system while verifying that the correct methods in those dependencies are called. The -<a href="https://code.google.com/p/mockito/" class="external-link">Mockito</a> mocking framework +<a href="https://github.com/mockito/mockito" class="external-link">Mockito</a> mocking framework for Java (version 1.9.5 and higher) offers compatibility with Android unit testing. With Mockito, you can configure mock objects to return some specific value when invoked.</p> @@ -240,63 +176,8 @@ class="external-link">sample code</a>. <h2 id="run">Run Local Unit Tests</h2> <p> -The Android Plug-in for Gradle provides a default directory ({@code src/test/java}) for you to -store unit test classes that you want to run on a local JVM. The plug-in compiles the test code in -that directory and then executes the test app locally using the default test runner class. +To run your tests, follow the steps for running local unit tests +described in <a href="{@docRoot}training/testing/start/index.html#run-local-tests"> +Getting Started with Testing</a>. </p> -<p> -As with production code, you can create unit tests for a -<a href="http://developer.android.com/tools/building/configuring-gradle.html#workBuildVariants" -class="external-link">specific flavor or build type</a>. You should keep unit tests in a test -source tree location that corresponds to your production source tree, such as: - -<table> -<tr> -<th>Path to Production Class</th> -<th>Path to Local Unit Test Class</th> -</tr> -<tr> -<td>{@code src/main/java/Foo.java}</td> -<td>{@code src/test/java/FooTest.java}</td> -</tr> -<tr> -<td>{@code src/debug/java/Foo.java}</td> -<td>{@code src/testDebug/java/FooTest.java}</td> -</tr> -<tr> -<td>{@code src/myFlavor/java/Foo.java}</td> -<td>{@code src/testMyFlavor/java/FooTest.java}</td> -</tr> -</table> - -<h3 id="run-from-Android-Studio">Running local unit tests from Android Studio</h3> -<p> -To run local unit tests in your Gradle project from Android Studio: -</p> -<ol> -<li>In the <strong>Project</strong> window, right click on the project and synchronize your project. -</li> -<li>Open the <strong>Build Variants</strong> window by clicking the left-hand tab, then change the -test artifact to <em>Unit Tests</em>. -</li> -<li>In the <strong>Project</strong> window, drill down to your unit test class or method, then -right-click and run it. -</li> -</ol> - -<p>Android Studio displays the results of the unit test execution in the <strong>Run</strong> -window.</p> - -<h3 id="run-from-commandline">Running local unit tests from the command-line</h3> - -<p>To run local unit tests in your Gradle project from the command-line, call the {@code test} task -command with the {@code --continue} option.</p> - -<pre> -./gradlew test --continue -</pre> -<p>If there are failing tests, the command will display links to HTML reports (one per build -variant). You can find the generated HTML test result reports in the -{@code <path_to_your_project>/app/build/reports/tests/} directory, and the corresponding XML -files in the {@code <path_to_your_project>/app/build/test-results/} directory.</p> diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index 9e156d0821d3..5b0d60344a9b 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -62,7 +62,6 @@ <li class="nav-section"> <div class="nav-section-header"> <a href="<?cs var:toroot ?>training/basics/activity-lifecycle/index.html" - es-lang="" ja-lang="アクティビティのライフサイクル 管理" ko-lang="액티비티 수명 주기 관리하기" pt-br-lang="Como gerenciar o ciclo de vida da atividade" @@ -76,7 +75,6 @@ </div> <ul> <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/starting.html" - es-lang="" ja-lang="アクティビティを開始する" ko-lang="액티비티 시작하기" pt-br-lang="Iniciando uma atividade" @@ -87,18 +85,10 @@ </a> </li> <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/pausing.html" - es-lang="" - ja-lang="" - ko-lang="" - pt-br-lang="" - ru-lang="" - zh-cn-lang="" - zh-tw-lang=""> Pausing and Resuming an Activity </a> </li> <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/stopping.html" - es-lang="" ja-lang="アクティビティの一時停止と再開" ko-lang="액티비티 일시정지 및 재개하기" pt-br-lang="Pausando e reiniciando uma atividade" @@ -109,7 +99,6 @@ </a> </li> <li><a href="<?cs var:toroot ?>training/basics/activity-lifecycle/recreating.html" - es-lang="" ja-lang="アクティビティを再作成する" ko-lang="액티비티 재생성하기" pt-br-lang="Recriando uma atividade" @@ -150,7 +139,6 @@ <li class="nav-section"> <div class="nav-section-header"><a href="<?cs var:toroot?>training/basics/data-storage/index.html" - es-lang="" ja-lang="データの保存" ko-lang="데이터 저장하기" pt-br-lang="Salvando dados" @@ -164,7 +152,6 @@ </div> <ul> <li><a href="<?cs var:toroot ?>training/basics/data-storage/shared-preferences.html" - es-lang="" ja-lang="キー値セットを保存する" ko-lang="키-값 세트 저장하기" pt-br-lang="Salvando conjuntos de valor-chave" @@ -175,7 +162,6 @@ </a> </li> <li><a href="<?cs var:toroot ?>training/basics/data-storage/files.html" - es-lang="" ja-lang="ファイルを保存する" ko-lang="파일 저장하기" pt-br-lang="Salvando arquivos" @@ -186,7 +172,6 @@ </a> </li> <li><a href="<?cs var:toroot ?>training/basics/data-storage/databases.html" - es-lang="" ja-lang="SQL データベースにデータを保存する" ko-lang="SQL 데이터베이스에 데이터 저장하기" pt-br-lang="Salvando dados em bancos de dados do SQL" @@ -202,7 +187,6 @@ <li class="nav-section"> <div class="nav-section-header"> <a href="<?cs var:toroot ?>training/basics/intents/index.html" - es-lang="" ja-lang="他のアプリとの相互操作" ko-lang="액티비티 수명 주기 관리하기" pt-br-lang="Interagindo com outros aplicativos" @@ -217,7 +201,6 @@ </div> <ul> <li><a href="<?cs var:toroot ?>training/basics/intents/sending.html" - es-lang="" ja-lang="別のアプリにユーザーを送る" ko-lang="다른 앱으로 사용자 보내기" pt-br-lang="Enviando o usuário para outro aplicativo" @@ -228,7 +211,6 @@ </a> </li> <li><a href="<?cs var:toroot ?>training/basics/intents/result.html" - es-lang="" ja-lang="アクティビティから結果を取得する" ko-lang="액티비티로부터 결과 가져오기" pt-br-lang="Obtendo resultados de uma atividade" @@ -239,7 +221,6 @@ </a> </li> <li><a href="<?cs var:toroot ?>training/basics/intents/filters.html" - es-lang="" ja-lang="他のアプリからのアクティビティの開始を許可する" ko-lang="다른 앱이 자신의 액티비티를 시작하도록 허용하기" pt-br-lang="Permitindo que outros aplicativos iniciem sua atividade" @@ -780,6 +761,11 @@ </a> </li> <li> + <a href="<?cs var:toroot ?>training/location/change-location-settings.html"> + Changing Location Settings + </a> + </li> + <li> <a href="<?cs var:toroot ?>training/location/receive-location-updates.html"> Receiving Location Updates </a> @@ -1098,6 +1084,10 @@ ja-lang="再生中カードを表示する"> Displaying a Now Playing Card</a> </li> + <li> + <a href="<?cs var:toroot ?>training/tv/playback/options.html"> + Enabling Background Playback</a> + </li> </ul> </li> @@ -1569,6 +1559,10 @@ results." Developing Accessibility Services </a> </li> + <li><a href="<?cs var:toroot ?>training/accessibility/testing.html"> + Accessibility Testing Checklist + </a> + </li> </ul> </li> @@ -2085,41 +2079,64 @@ results." <li class="nav-section"> <div class="nav-section-header"> - <a href="<?cs var:toroot ?>training/testing.html"> + <a href="<?cs var:toroot ?>training/best-permissions-ids.html"> + <span class="small">Best Practices for</span><br/> + Permissions & Identifiers + </a> + </div> + <ul> + <li> + <a href="<?cs var:toroot ?>training/articles/user-data-overview.html" + description= + "Overview of app permissions on Android and how they affect your users." + >Permissions and User Data</a> + </li> + <li> + <a href="<?cs var:toroot ?>training/articles/user-data-permissions.html" + description= + "How to manage permissions the right way for users." + >Best Practices for App Permissions</a> + </li> + <li> + <a href="<?cs var:toroot ?>training/articles/user-data-ids.html" + description= + "Unique identifiers available and how to choose the right one for your use case." + >Best Practices for Unique Identifiers</a> + </li> + </ul> + </li> + <!-- End Permissions and identifiers --> + + <li class="nav-section"> + <div class="nav-section-header"> + <a href="<?cs var:toroot ?>training/testing/index.html"> <span class="small">Best Practices for</span><br/> Testing </a> </div> <ul> + <li> + <a href="<?cs var:toroot ?>training/testing/start/index.html" + description="How to get started with testing your Android applications."> + Getting Started with Testing + </a> + </li> <li class="nav-section"> - <div class="nav-section-header"><a href="<?cs var:toroot ?>training/activity-testing/index.html" - description="How to test Activities in your Android applications."> - Testing Your Activity + <div class="nav-section-header"><a href="<?cs var:toroot ?>training/testing/unit-testing/index.html" + description="How to build effective unit tests for Android apps."> + Building Effective Unit Tests </a></div> <ul> - <li><a href="<?cs var:toroot ?>training/activity-testing/preparing-activity-testing.html"> - <span class="en">Setting Up Your Test Environment</span> - </a> - </li> - <li><a href="<?cs var:toroot ?>training/activity-testing/activity-basic-testing.html"> - <span class="en">Creating and Running a Test Case</span> - </a> - </li> - <li><a href="<?cs var:toroot ?>training/activity-testing/activity-ui-testing.html"> - <span class="en">Testing UI Components</span> - </a> - </li> - <li><a href="<?cs var:toroot ?>training/activity-testing/activity-unit-testing.html"> - <span class="en">Creating Unit Tests</span> - </a> + <li><a href="<?cs var:toroot ?>training/testing/unit-testing/local-unit-tests.html"> + <span class="en">Building Local Unit Tests</span> + </a> </li> - <li><a href="<?cs var:toroot ?>training/activity-testing/activity-functional-testing.html"> - <span class="en">Creating Functional Tests</span> - </a> + <li><a href="<?cs var:toroot ?>training/testing/unit-testing/instrumented-unit-tests.html"> + <span class="en">Building Instrumented Unit Tests</span> + </a> </li> </ul> </li> - <li class="nav-section"> <div class="nav-section-header"><a href="<?cs var:toroot ?>training/testing/ui-testing/index.html" description="How to automate your user interface tests for Android apps."> @@ -2136,27 +2153,20 @@ results." </li> </ul> </li> - <li class="nav-section"> - <div class="nav-section-header"><a href="<?cs var:toroot ?>training/testing/unit-testing/index.html" - description="How to build effective unit tests for Android apps."> - Building Effective Unit Tests + <div class="nav-section-header"><a href="<?cs var:toroot ?>training/testing/integration-testing/index.html" + description="How to build effective integration tests for Android apps."> + Testing App Component Integrations </a></div> <ul> - <li><a href="<?cs var:toroot ?>training/testing/unit-testing/local-unit-tests.html"> - <span class="en">Building Local Unit Tests</span> - </a> - </li> - <li><a href="<?cs var:toroot ?>training/testing/unit-testing/instrumented-unit-tests.html"> - <span class="en">Building Instrumented Unit Tests</span> - </a> - </li> + <li><a href="<?cs var:toroot ?>training/testing/integration-testing/service-testing.html"> + <span class="en">Testing Your Service</span></a></li> + <li><a href="<?cs var:toroot ?>training/testing/integration-testing/content-provider-testing.html"> + <span class="en">Testing Your Content Provider</span></a></li> </ul> </li> - <li><a href="<?cs var:toroot ?>training/testing/performance.html" - description="How to automate UI performance testing."> - Testing Display Performance</a> + description="How to automate UI performance testing.">Testing Display Performance</a> </li> </ul> </li> diff --git a/docs/html/training/tv/playback/index.jd b/docs/html/training/tv/playback/index.jd index e39e34a0e971..43c6d41e09c1 100644 --- a/docs/html/training/tv/playback/index.jd +++ b/docs/html/training/tv/playback/index.jd @@ -64,4 +64,7 @@ startpage=true <dt><b><a href="now-playing.html">Displaying a Now Playing Card</a></b></dt> <dd>Learn how to use a MediaSession to display a Now Playing card on the home screen.</dd> + + <dt><b><a href="options.html">Enabling Background Playback</a></b></dt> + <dd>Learn how to continue playback when the user clicks on <strong>Home</strong>.</dd> </dl> diff --git a/docs/html/training/tv/playback/options.jd b/docs/html/training/tv/playback/options.jd new file mode 100644 index 000000000000..c65343df6805 --- /dev/null +++ b/docs/html/training/tv/playback/options.jd @@ -0,0 +1,66 @@ +page.title=Enabling Background Playback +page.tags=tv, play, playback, background +helpoutsWidget=true + +trainingnavtop=true + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + <h2>This lesson teaches you to</h2> + <ol> + <li><a href="#background">Request Background Playback</a></li> + </ol> +</div> +</div> + +<p> +A user watching content on a TV device may decide to switch to the TV launcher at any time. +If a user switches to the launcher while using a TV playback app, by default the app is paused. +Since the user did not explicitly request to pause playback, the default behavior might seem +abrupt and unexpected. This lesson describes how to enable background playback in your app, +which provides a better user experience. +</p> + +<h2 id="background">Request Background Playback</h2> + +<p>Normally, when the user clicks on <strong>Home</strong> to display the TV +launcher, the activity pauses. However, your app can request background playback, in +which the activity continues playing behind the TV launcher.</p> + +<p>To request background playback, call +{@link android.app.Activity#requestVisibleBehind requestVisibleBehind()}. +Be sure to clean up media resources if the activity stops being +visible. For example, you should free media resources if +{@link android.app.Activity#requestVisibleBehind requestVisibleBehind()} +returns <code>false</code> to indicate that the request failed, or if the system calls +your override of {@link android.app.Activity#onVisibleBehindCanceled onVisibleBehindCanceled()}. +</p> + +<pre> +@Override +public void onPause() { + super.onPause(); + if (mVideoView.isPlaying()) { + // Argument equals true to notify the system that the activity + // wishes to be visible behind other translucent activities + if (! requestVisibleBehind(true)) { + // App-specific method to stop playback and release resources + // because call to requestVisibleBehind(true) failed + stopPlayback(); + } + } else { + // Argument equals false because the activity is not playing + requestVisibleBehind(false); + } +} + +@Override +public void onVisibleBehindCanceled() { + // App-specific method to stop playback and release resources + stopPlayback(); + super.onVisibleBehindCanceled(); +} +</pre> + diff --git a/docs/html/training/tv/start/start.jd b/docs/html/training/tv/start/start.jd index 743b61b1acf7..0ed6e15950a6 100644..100755 --- a/docs/html/training/tv/start/start.jd +++ b/docs/html/training/tv/start/start.jd @@ -367,7 +367,5 @@ supported by Android TV.</p> For more information about using emulators see, <a href="{@docRoot}tools/devices/emulator.html"> Using the Emulator</a>. For more information on deploying apps from Android Studio to virtual devices, see <a href="{@docRoot}sdk/installing/studio-debug.html">Debugging with Android - Studio</a>. For more information about deploying apps to emulators from Eclipse with ADT, see - <a href="{@docRoot}tools/building/building-eclipse.html">Building and Running from Eclipse with - ADT</a>. + Studio</a>. </p> diff --git a/docs/html/training/volley/index.jd b/docs/html/training/volley/index.jd index 2cefc903cd68..6ee7d4e0ab9f 100644..100755 --- a/docs/html/training/volley/index.jd +++ b/docs/html/training/volley/index.jd @@ -77,9 +77,9 @@ git clone https://android.googlesource.com/platform/frameworks/volley </pre> </li> -<li>Import the downloaded source into your app project as an Android library project -(as described in <a href="{@docRoot}tools/projects/projects-eclipse.html"> -Managing Projects from Eclipse with ADT</a>, if you're using Eclipse) or make a +<li>Import the downloaded source into your app project as an Android library module +(as described in <a href="{@docRoot}sdk/installing/create-project.html#SettingUpLibraryModule"> +Managing Projects from Android Studio</a>, if you're using Android Studio) or make a <a href="{@docRoot}guide/faq/commontasks.html#addexternallibrary"><code>.jar</code> file</a>.</li> </ol> diff --git a/docs/html/tv/index.jd b/docs/html/tv/index.jd index 73b343567253..53948ff8e7ca 100644 --- a/docs/html/tv/index.jd +++ b/docs/html/tv/index.jd @@ -260,24 +260,6 @@ page.type=about </div> <!-- end .landing-rest-of-page --> - <div class="content-footer wrap" itemscope="" itemtype="http://schema.org/SiteNavigationElement"> - <div class="layout-content-col col-16" style="padding-top:4px"> - <style>#___plusone_0 {float:right !important;}</style> - <div class="g-plusone" data-size="medium"></div> - </div> - </div> - <div id="footer" class="wrap" style="width:940px;position:relative;top:-35px;z-index:-1"> - <div id="copyright"> - Except as noted, this content is - licensed under <a href="http://creativecommons.org/licenses/by/2.5/"> - Creative Commons Attribution 2.5</a>. For details and - restrictions, see the <a href="/license.html">Content - License</a>. - </div> - </div> - - </div> <!-- end .landing-hero-container --> - <script> $("a.landing-down-arrow").on("click", function(e) { $("body").animate({ diff --git a/docs/html/wear/images/partners/casio.png b/docs/html/wear/images/partners/casio.png Binary files differnew file mode 100644 index 000000000000..41f36d873f60 --- /dev/null +++ b/docs/html/wear/images/partners/casio.png diff --git a/docs/html/wear/images/partners/mobvoi.png b/docs/html/wear/images/partners/mobvoi.png Binary files differnew file mode 100644 index 000000000000..9a2eb4da2f58 --- /dev/null +++ b/docs/html/wear/images/partners/mobvoi.png diff --git a/docs/html/wear/images/partners/nb.png b/docs/html/wear/images/partners/nb.png Binary files differnew file mode 100644 index 000000000000..224b27e81b42 --- /dev/null +++ b/docs/html/wear/images/partners/nb.png diff --git a/docs/html/wear/index.jd b/docs/html/wear/index.jd index e18ada44c5b9..618fb30cfdf8 100644 --- a/docs/html/wear/index.jd +++ b/docs/html/wear/index.jd @@ -213,6 +213,9 @@ page.image=images/cards/android-wear_2x.png <div class="col-4"> <img src="/wear/images/partners/broadcom.png" alt="Broadcom"> </div> + <div class="col-4"> + <img src="/wear/images/partners/casio.png" alt="Casio"> + </div> <div class="col-4"> <img src="/wear/images/partners/fossil.png" alt="Fossil"> </div> @@ -234,9 +237,15 @@ page.image=images/cards/android-wear_2x.png <div class="col-4"> <img src="/wear/images/partners/mips.png" alt="MIPS"> </div> + <div class="col-4"> + <img src="/wear/images/partners/mobvoi.png" alt="Mobvoi"> + </div> <div class="col-4"> <img src="/wear/images/partners/motorola.png" alt="Motorola"> </div> + <div class="col-4"> + <img src="/wear/images/partners/nb.png" alt="New Balance"> + </div> <div class="col-4"> <img src="/wear/images/partners/qualcomm.png" alt="Qualcomm"> </div> @@ -249,6 +258,7 @@ page.image=images/cards/android-wear_2x.png <div class="col-4"> <img src="/wear/images/partners/tagheuer.png" alt="Tag Heuer"> </div> + </div> </div> <!-- end .wrap --> </div> @@ -332,22 +342,6 @@ page.image=images/cards/android-wear_2x.png </div> <!-- end .wrap --> </div> <!-- end .landing-section --> </div> <!-- end .landing-rest-of-page --> - <div class="content-footer wrap" itemscope="" itemtype="http://schema.org/SiteNavigationElement"> - <div class="layout-content-col col-16" style="padding-top:4px"> - <style>#___plusone_0 {float:right !important;}</style> - <div class="g-plusone" data-size="medium"></div> - </div> - </div> - <div id="footer" class="wrap" style="width:940px;position:relative;top:-35px;z-index:-1"> - <div id="copyright"> - Except as noted, this content is - licensed under <a href="http://creativecommons.org/licenses/by/2.5/"> - Creative Commons Attribution 2.5</a>. For details and - restrictions, see the <a href="{@docRoot}license.html">Content - License</a>. - </div> - </div> - </div> <!-- end .landing-hero-container --> <script> $("a.landing-down-arrow").on("click", function(e) { |