El proyecto AMP siempre ha tenido como fin ayudar a los editores a monetizar el contenido que publican en las páginas AMP de la manera más efectiva posible. Eso significa ayudar a los editores a capturar la mayor demanda de anunciantes posible para cada espacio de anuncio en sus páginas.


El proyecto AMP siempre ha tenido como fin ayudar a los editores a monetizar el contenido que publican en las páginas AMP de la manera más efectiva posible. Eso significa ayudar a los editores a capturar la mayor demanda de anunciantes posible para cada espacio de anuncio en sus páginas.

Una manera en que permitimos a los editores hacer esto es mediante la posibilidad de contar con espacios de anuncios en las páginas AMP que sirvan para diferentes tamaños de unidades de anuncios, manteniendo al mismo tiempo la promesa de AMP de un diseño estable que no “salta de un lado a otro” delante del usuario. Con más unidades de anuncios elegibles para utilizar en un solo espacio de anuncio, más anunciantes pueden competir en subastas programáticas y aumentar el potencial de ingresos de dicho espacio.

Hoy, anunciamos que Yieldmo y DoubleClick han implementado el servicio de soporte de solicitudes de anuncios de múltiples tamaños para páginas AMP.

El problema de las solicitudes de anuncios de múltiples tamaños en la actualidad


Hace ya un tiempo que los editores vienen utilizando las solicitudes de anuncios de múltiples tamaños para optimizar los ingresos en todas sus propiedades web. Sin embargo, hasta el momento, la implementación ha provocado malas experiencias de los usuarios. Los espacios de anuncios de múltiples tamaños existentes han causado el reprocesamiento de las páginas, lo que, a su vez, podría derivar en lo siguiente:

1) Clics accidentales que sacan al usuario de la experiencia de contenido original

2) Experiencias de contenido no deseadas con contenido que rebota para adaptarse a la nueva unidad de anuncio

3) Escaso rendimiento técnico de la página

La solución AMP


AMP siempre prioriza la experiencia del usuario y el rendimiento de la página por sobre todas las cosas. Para ello, aplica estrictamente el principio de contención, es decir, la respuesta del anuncio nunca puede causar el reprocesamiento del resto del contenido.

AMP siempre reservará el tamaño principal requerido para el espacio del anuncio antes de que se realice la solicitud de anuncio. Para poder respaldar las solicitudes de anuncios de múltiples tamaños, se mejoró la API render-start  para que acepte un parámetro de tamaño opcional. Cuando el proveedor técnico del anuncio envía este parámetro, AMP redimensiona automáticamente el tamaño principal del contenedor (cuando es necesario) para que pueda albergar el diseño creativo sin causar el reprocesamiento de la página.

Cómo permitir que los clientes de Yieldmo aprovechen las solicitudes de anuncios de múltiples tamaños en AMP


Como uno de los primeros defensores del proyecto AMP, Yieldmo ha invertido fuertemente en ayudar a los editores a monetizar de manera efectiva su contenido en las páginas AMP.

“Hace ya un tiempo que los editores y los anunciantes nos piden que ofrezcamos soporte para solicitudes de anuncios de múltiples tamaños en AMP. Pero hacerlo de un modo no intrusivo para la experiencia del usuario era un desafío. Hemos trabajado en estrecha colaboración con el equipo AMP en este proyecto, incluso ayudando a definir parte de la implementación. La integración con la nueva API fue realmente sencilla, y nos alegra ver cómo esta nueva función generará ingresos para nuestros clientes”. – Rahul Rao, Yieldmo.

Para obtener más información sobre la implementación de Yieldmo, consulta la documentación.

Para obtener más información sobre el soporte para solicitudes de anuncios de múltiples tamaños de DoubleClick, consulta la documentación y los ejemplos.

Publicado por Rahul Rao, Director, SDK, Yieldmo y Vamsee Jasti, Gerente de producto, Proyecto AMP.


¡Comencemos! Gracias por compartir con nosotros esta tercera parte de la serie de blogs sobre la API Play Services Task para Android. Hasta ahora, has visto los aspectos básicos de la API en la ...

¡Comencemos! Gracias por compartir con nosotros esta tercera parte de la serie de blogs sobre la API Play Services Task para Android. Hasta ahora, has visto los aspectos básicos de la API en la primera parte y cómo seleccionar el mejor estilo de receptor en la segunda parte. Entonces, a esta altura, probablemente ya tengas todo lo necesario para saber cómo usar de la manera más efectiva las Tasks generadas por las API de Firebase. Pero si deseas ahondar en el uso avanzado de Tasks, sigue leyendo.


Ponte a trabajar con Task
Sabemos que algunas de las funciones de Firebase para Android harán el trabajo por ti y notificarán una Task una vez completada. ¿Y si quisieras crear tus propias Tasks para realizar trabajo en subprocesos? La API Task te ofrece las herramientas para que puedas hacerlo. Si deseas trabajar con la API Task sin tener que integrar Firebase en tu app, puedes obtener la biblioteca con una dependencia en build.gradle:
    compile 'com.google.android.gms:play-services-tasks:9.6.1'

Pero si integras Firebase, se incluirá esta biblioteca de forma gratuita, por lo que no será necesario solicitarla específicamente en ese caso.

Solo hay un método (con dos variantes) que puedes utilizar para iniciar una nueva tarea. Puedes usar el método estático, llamado "call" en la clase de utilidad Tasks para esto. Las variantes son las siguientes:
    Task<TResult> call(Callable<TResult> callable)
    Task<TResult> call(Executor executor, Callable<TResult> callable)

Al igual que con addOnSuccessListener(), tienes una versión de call() que ejecuta el trabajo en el subproceso principal y otra que envía el trabajo a un Ejecutor. Debes especificar el trabajo que se debe realizar dentro del Callable pasado. Un objeto Callable de Java es similar a un Runnable, salvo que está parametrizado por algún tipo de resultado, y ese tipo se convierte en el tipo de objeto devuelto del método call(). Este tipo de resultado se convierte luego en el tipo de la Task devuelta por call(). A continuación, se presenta un Callable realmente sencillo que solo devuelve un String:
    public class CarlyCallable implements Callable<String> {
        @Override
        public String call() throws Exception {
            return "Call me maybe";
        }
    }

Observa que CarlyCallable está parametrizado por String, lo que significa que su método call() debe devolver un String. Ahora puedes crear una Task a partir de él con una sola línea:
    Task<String> task = Tasks.call(new CarlyCallable());

Después de que se ejecuta esta línea, puedes estar seguro de que el método call() en CarlyCallable se invocará en el subproceso principal y puedes agregar un receptor a la Task para encontrar el resultado (a pesar de que ese resultado es completamente predecible). Los Callables más interesantes pueden incluso cargar algunos datos de una base de datos o de un extremo de red, por lo que querrás que esos Callables de bloqueo se ejecuten en un Ejecutor que use la segunda forma de call() que acepta al Ejecutor como el primer argumento.
Working on the Chain Gang o «Atados por la cadena»
Digamos, a modo de ejemplo, que deseas procesar el resultado del String de la Task CarlyCallable después de que se ha generado. Imagina que no nos interesa tanto el texto del String resultante en sí, sino una lista de las palabras individuales del String. Pero no necesariamente deseamos modificar CarlyCallable porque realiza exactamente la acción que debe realizar, y podría usarse en otros lugares tal como está escribo ahora. En lugar de ello, preferiríamos encapsular la lógica que divide las palabras en su propia clase, y usarla después de que CarlyCallable devuelva el String. Podemos hacerlo con una interfaz Continuation. La implementación de la interfaz Continuation toma el resultado de una Task, realiza un procesamiento y devuelve un objeto de resultado, no necesariamente del mismo tipo. Esta es una Continuation que divide un string de palabras en una Lista de strings con cada palabra:
    public class SeparateWays implements Continuation<String, List<String>> {
        @Override
        public List<String> then(Task<String> task) throws Exception {
            return Arrays.asList(task.getResult().split(" +"));
        }
    }

Observa que la interfaz Continuation que se implementa aquí está parametrizada por dos tipos, un tipo de entrada (String) y uno de salida (Lista). Los tipos de entrada y salida se usan en la firma del método solitario then() para definir lo que se supone que debe realizar. Cabe destacar el parámetro pasado a then(). Es una Task, y el String debe coincidir con el tipo de entrada de la interfaz Continuation. Este es el modo en que Continuation obtiene su entrada: extrae el resultado terminado de la Task completada.

Esta es otra Continuation que aleatoriza una Lista de strings:
    public class AllShookUp implements Continuation<List<String>, List<String>> {
        @Override
        public List<String> then(@NonNull Task<List<String>> task) throws Exception {
            // Randomize a copy of the List, not the input List itself, since it could be immutable
            final ArrayList<String> shookUp = new ArrayList<>(task.getResult());
            Collections.shuffle(shookUp);
            return shookUp;
        }
    }

Y otra que une una Lista de strings en un solo string separado por espacios.
    private static class ComeTogether implements Continuation<List<String>, String> {
        @Override
        public String then(@NonNull Task<List<String>> task) throws Exception {
            StringBuilder sb = new StringBuilder();
            for (String word : task.getResult()) {
                if (sb.length() > 0) {
                    sb.append(' ');
                }
                sb.append(word);
            }
            return sb.toString();
        }
    }

Seguramente puedas ver a dónde apunto con esto. Unamos todo en una cadena de operaciones que aleatorice el orden de las palabras de un String de una Task inicial y genere un nuevo String con ese resultado:
    Task<String> playlist = Tasks.call(new CarlyCallable())
            .continueWith(new SeparateWays())
            .continueWith(new AllShookUp())
            .continueWith(new ComeTogether());
    playlist.addOnSuccessListener(new OnSuccessListener<String>() {
        @Override
        public void onSuccess(String message) {
            // The final String with all the words randomized is here
        }
    });

El método continueWith() en la Task devuelve una nueva Task que representa el cálculo de la Task anterior después de haber sido procesada por la Continuation determinada. Entonces, lo que hacemos aquí es generar una cadena de llamadas a continueWith() para formar un proceso de operaciones que culmina en una Task final que espera que cada etapa termine antes de completarse.

Esta cadena de operaciones puede ser problemática si tiene que manejar Strings grandes; para evitarlo, vamos a modificarla para que todo el procesamiento se realice en otros subprocesos a fin de no bloquear el subproceso principal:
    Executor executor = ... // you decide!

    Task<String> playlist = Tasks.call(executor, new CarlyCallable())
        .continueWith(executor, new SeparateWays())
        .continueWith(executor, new AllShookUp())
        .continueWith(executor, new ComeTogether());
    playlist.addOnSuccessListener(executor, new OnSuccessListener() {
        @Override
        public void onSuccess(String message) {
            // Do something with the output of this playlist!
        }
    });

Ahora, el Callable, todas las Continuations y el receptor de la Task final se ejecutarán en algún subproceso determinado por el Ejecutor, liberando el subproceso principal para que se ocupe de las cuestiones relacionadas con la IU cuando aparezcan. Debe estar completamente libre de bloqueos.

La primera impresión puede ser que parezca un poco tonto separar todas estas operaciones en todas las clases diferentes. También podrías fácilmente escribir esto como unas pocas líneas en un solo método que realiza lo que se requiere. No debemos olvidar que este es un ejemplo simplificado que tiene por objeto destacar cómo pueden funcionar las Tasks. El beneficio de encadenar las Tasks y Continuations (incluso para funciones relativamente sencillas) se torna más evidente cuando tenemos en cuenta lo siguiente:
  • ¿Cómo podrías incorporar nuevos orígenes de Strings de entrada? ¿Y si, además, tuviéramos un BlondieCallable? ¿Y un PaulSimonCallable?
  • ¿Qué hay de las diferentes clases de procesos para los Strings de entrada, como una Continuation YouSpinMeRound que rotara el orden de los Strings en una lista una posición hacia la derecha (como un disco)?
  • ¿Y si desearas que diferentes componentes de la segmentación de procesos se ejecutaran en diferentes subprocesos?

En la práctica, es más probable que utilices las continuaciones de Task para realizar una serie de cadena modular de filtro, mapa, y reducir las funciones en un conjunto de datos y mantener esas unidades de trabajo fuera del subproceso principal, si las colecciones pueden ser grandes. Me divertí con el tema de la música aquí.
¿Si la playlist se interrumpe?
Algo más que debes saber sobre las Continuations. Si se lanza una excepción de tiempo de ejecución durante el procesamiento en cualquier etapa del proceso, esa excepción normalmente se propagará hasta los receptores de falla en la Task final de la cadena. Puedes comprobar esto tú mismo en cualquier Continuation consultando a la Task de entrada si se completó correctamente con el método isSuccessful(). Puedes también llamar ciegamente a getResult() (como en los ejemplos anteriores) y, si existió una falla previa, se volverá a lanzar y finalizará automáticamente en la Continuation siguiente. Los receptores de la Task final de la cadena siempre deben comprobar si existe una falla (en caso de que exista la opción de una falla).

Entonces si, por ejemplo, CarlyCallable en la cadena anterior devolvió un valor nulo, esto hará que la Continuation SeparateWays lance una NullPointerException, la cual se propagará hasta el final de la Task. Y si tuviéramos una OnFailureListener registrada, se invocaría con la misma instancia de excepción.
Cuestionario
¿Cuál es el modo más eficiente , con la cadena anterior, de conocer la cantidad de palabras en el string original, sin modificar ninguno de los componentes de procesamiento? Tómate un momento para pensarlo antes de seguir leyendo.

Probablemente, la respuesta sea más sencilla de lo que imaginas. La solución más obvia es contar la cantidad de palabras en el string de salida final, dado que solo se aleatorizó el orden. Pero existe un truco más. Cada llamada a continueWith() devuelve una nueva instancia de Task, pero esto no es visible aquí porque utilizamos una sintaxis de cadena para reunirlas en la Task final. Puedes interceptar cualquiera de esas Tasks y agregarles otro receptor, además de la Continuation siguiente:
    Task<List<String>> split_task = Tasks.call(new CarlyCallable())
        .continueWith(executor, new SeparateWays());
    split_task =
        .continueWith(executor, new AllShookUp())
        .continueWith(executor, new ComeTogether());
    split_task.addOnCompleteListener(executor, new OnCompleteListener<List<String>>() {
        @Override
        public void onComplete(@NonNull Task<List<String>> task) {
            // Find the number of words just by checking the size of the List
            int size = task.getResult().size();
        }
    });
    playlist.addOnCompleteListener( /* as before... */ );

Cuando una Task finaliza, activará ambas Continuations y también todos los receptores agregados. Todo lo que hicimos aquí es interceptar la Task que captura la salida de la Continuation SeparateWays y escuchar la salida de esta directamente, sin afectar la cadena de Continuations. Con esta Task interceptada, solo tenemos que llamar a size() en la lista para obtener el conteo.
Para concluir (la parte 3 de esta serie)
Dejando de lado las bromas, la API Task hace que sea relativamente fácil expresar y ejecutar una segmentación secuencial de procesos de manera modular, y te ofrece la capacidad de especificar qué Ejecutor se utiliza en cada etapa del proceso. Puedes hacer esto integrando Firebase en tu app o no, usando tus propias Tasks o las que vienen en las API de Firebase. En la siguiente y última parte de esta serie, veremos cómo las Tasks pueden usarse en paralelo para iniciar varias unidades de trabajo al mismo tiempo.

Como siempre, si tienes alguna pregunta, puedes usar Twitter con el hashtag #AskFirebase o el Grupo de Google firebase-talk. También tenemos un canal dedicado a Firebase Slack. También puede seguirme @CodingDoug en Twitter para recibir notificaciones de la siguiente publicación de esta serie.

Por último, si te preguntas por todas las canciones que mencioné en esta publicación, puedes encontrarlas aquí:


Publicado por Chris Jones, Equipo social, AdMob.

Publicado por Chris Jones, Equipo social, AdMob.


En AdMob, sabemos la importancia que tiene la experiencia del usuario cuando se trata de crear una app excelente. Los patrones uniformes, una simplicidad renovadora y un estilo acabado y considerado dan satisfacción a los usuarios y pueden aumentar las tasas de atracción por anuncios. La publicidad nativa es el siguiente paso hacia el cumplimiento de las expectativas del cliente en términos de experiencia de usuario. Los anuncios nativos son menos chocantes que los tradicionales y se adecuan al contenido de la app de manera más natural, lo que proporciona una mejor experiencia de usuario. Eso es hacer negocios con inteligencia.
A continuación, presentamos cuatro maneras de convertir la experiencia del usuario en una prioridad en tu app y en la experiencia publicitaria.

1. Uniformidad

A veces, es bueno ser predecible. Ateniéndote a patrones de experiencia de usuario uniformes en tu app, puedes ayudar a los usuarios a concentrarse menos en navegar y más en el contenido y el valor de tu app. No sorprendas al usuario con elementos nuevos. Mantén la constancia en los aspectos del flujo de estos, como el deslizamiento del dedo hacia la izquierda en apps de noticias para cerrar un artículo o navegar por el feed del título. Usa elementos de diseño uniformes, como tamaños de fuente, colores, botones y tamaños de pantalla dedicados.

Lo mismo se aplica a la experiencia publicitaria de tus usuarios. Aplicando patrones de experiencia de usuario confiables, establecerás en tus apps puntos de interrupción claros en los cuales los usuarios esperarán ver anuncios atractivos. En el caso de la app de noticias, es posible que también quieras usar la función de deslizamiento del dedo hacia la izquierda para permitir que los usuarios descarten anuncios. Esto también se aplica a los ajustes de estilo de los anuncios. Por ejemplo, si usas la fuente Lato con parámetros como 14 px, negrita y color gris oscuro para dar prominencia al texto, aplica también esta fuente al título del anuncio. ¿El resultado? Los usuarios preverán que los ajustes de estilo se dedicarán a pasajes de texto importantes.





2. Claridad

A nadie le agrada el desorden. En tu app, la simplicidad transmitirá la idea de que no desperdiciarás el tiempo de tus usuarios presentándoles cualquier opción posible sin pensar en lo que necesitan. Simplifica tu app ordenando la pantalla, usando un estilo de redacción comercial conciso, conservando la legibilidad y un espaciado correcto en el diseño, y ofreciendo botones de llamada a la acción simples cuando sea posible. Asimismo, el uso de anuncios de llamada a la acción despejados, atractivos e individuales demostrará que comprendes a tus usuarios y contribuirá a ganar su confianza.

3. Nada de trucos

Seamos francos: un anuncio nativo no deja de ser un anuncio. No intentes distorsionar ni superponer componentes de anuncios (es la forma más rápida de hacer que un usuario se moleste). En Google, generar confianza en el ecosistema publicitario de las apps es importante para nosotros. Por ejemplo, hemos extendido nuestra protección contra clics accidentales a los formatos de anuncios nativos (incluidos los clics rápidos y en los bordes), a fin de proteger a los usuarios contra deslizamientos involuntarios y brindar mayor valor a los anunciantes.

4. Diseño considerado

La incorporación de detalles vinculados con la consideración en tu app es importante para demostrar a tus usuarios que te importan. Entre estos detalles se incluyen imágenes definidas, fuentes seleccionadas, márgenes conforme a las especificaciones y tiempos de carga reducidos. Es importante aplicar el mismo nivel de cuidado y terminación a los detalles menores del diseño de tus anuncios nativos. En un anuncio nativo, la simplicidad, el aspecto intuitivo y un buen diseño pueden ayudarte a expresar gratitud a tu valiosa base de usuarios.


Hasta la próxima ocasión, permanece conectado con AdMob siguiendo la actividad de nuestras páginas de Twitter, LinkedIn y Google+.


AdMob by Google es una de las principales plataformas de anuncios para dispositivos móviles, en la que confían más de 650.000 aplicaciones en todo el mundo. Si deseas conocer más acerca de AdMob, visita este enlace.


Publicado por Nathan Martz, Gerente de producto, Google VR
Nuestro equipo de Google VR trabaja para llevar la realidad virtual a todos, gracias a Google Cardboard y Daydream. Además de facilitar el acceso a la realidad virtual gracias al uso del smartphone, hace poco dejó de ser beta el ...

Publicado por Nathan Martz, Gerente de producto, Google VR
Nuestro equipo de Google VR trabaja para llevar la realidad virtual a todos, gracias a Google Cardboard y Daydream. Además de facilitar el acceso a la realidad virtual gracias al uso del smartphone, hace poco dejó de ser beta el SDK de Google VR, cuenta con integración nativa para Unity y UE4, simplificando el trabajo de todos los programadores que quieran unírsenos.

Para animar aún más a los programadores a crear experiencias de realidad virtual, nos hemos asociado con Udacity para crear el curso VR Developer Nanodegree. Los estudiantes aprenderán a crear entornos en 3D, definir comportamientos y hacer que las experiencias de realidad virtual sean algo más confortable, inmersivo y con un buen desempeño.


Aunque las aplicaciones de Google Cardboard cuentan con más de 50 millones de descargas en Google Play, todavía nos encontramos dando los primeros pasos en la realidad virtual. Los estudiantes que finalicen el curso de aprender programando de "VR Developer Nanodegree" ya contarán con un portfolio de experiencias de realidad virtual.

Para obtener más información y recibir actualizaciones sobre el programa VR Developer Nanodegree, regístrate en https://www.udacity.com/vr

Publicado por Arudea Mahartianto, especialista de Google AMP



En el mundo digital, sin importar si estás escribiendo historias para tus lectores leales, creando contenido creativo que tus fans adoran, ayudando a la comunidad digital o brindando artículos y servicios para tu cliente, entender a tu audiencia es el centro de todo. La clave para desbloquear esa información es acceder a herramientas para medir a tu audiencia y entender su comportamiento. Además de hacer que tu página cargue más rápido, las páginas móviles aceleradas (Accelerated Mobile Pages, AMP) ofrecen múltiples opciones analíticas sin comprometer el rendimiento.
Publicado por Arudea Mahartianto, especialista de Google AMP



En el mundo digital, sin importar si estás escribiendo historias para tus lectores leales, creando contenido creativo que tus fans adoran, ayudando a la comunidad digital o brindando artículos y servicios para tu cliente, entender a tu audiencia es el centro de todo. La clave para desbloquear esa información es acceder a herramientas para medir a tu audiencia y entender su comportamiento. Además de hacer que tu página cargue más rápido, las páginas móviles aceleradas (Accelerated Mobile Pages, AMP) ofrecen múltiples opciones analíticas sin comprometer el rendimiento.

Puedes escoger utilizar una solución como amp-pixel que funcione como un simple pixel rastreador. Utiliza una sola URL que permite sustituciones variables, por lo tanto, se deja personalizar. Consulta la documentación de amp-pixel para obtener más información.

Por otro lado, el componente amp-analytics es una potente solución que reorganiza muchos tipos de activadores de eventos para ayudarte a recolectar métricas específicas. Dado que amp-analytics es compatible con varios proveedores de analítica, puedes utilizar amp-analytics para configurar múltiples puntos de finalización y conjunto de datos. AMP administra toda la instrumentación para obtener los datos específicos y compartirlos con estos proveedores de soluciones analíticas.

Para utilizar amp-analytics, incluye la biblioteca de componente en los <head>de los documentos:
<script async custom-element="amp-analytics"


src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>

Y luego incluye el componente de la siguiente manera (para estos ejemplos, asegúrate de especificar tu propio número de cuenta en vez de un marcador de posición):
<amp-analytics type="googleanalytics">


<script type="application/json">
{
  "vars": {
    "account": "UA-YYYY-Y" 
  },
  "triggers": {
    "defaultPageview": {
      "on": "visible",
      "request": "pageview",
      "vars": {
        "title": "Name of the Article"
      }
    }
  }
}
</script>
</amp-analytics>

El formato JSON es muy flexible para describir varios tipos diferentes de eventos y no incluye código JavaScript que pueda potencialmente llevar a errores.

Profundizando en este ejemplo, podemos agregar otro activador, clickOnHeader:
<amp-analytics type="googleanalytics">
<script type="application/json">
{
  "vars": {
    "account": "UA-YYYY-Y"
  },
  "triggers": {
    "defaultPageview": {
      "on": "visible",
      "request": "pageview",
      "vars": {
        "title": "Name of the Article"
      }
    },
    "clickOnHeader": {
      "on": "click",
      "selector": "#header",
      "request": "event",
      "vars": {
        "eventCategory": "examples",
        "eventAction": "clicked-header"
      }
    }
  }
}
</script>
</amp-analytics>

Para una descripción detallada del conjunto de datos que puedes solicitar, como también la lista de los proveedores de analítica que son compatibles con amp-analytics, revisa la documentación de amp-analytics. También puedes ver más ejemplos de implementación en el Sitio Ejemplos de Amp.

Si quieres llevar a cabo un experimento de experiencia del usuario en tus páginas AMP, como una prueba A/B, puedes utilizar el elemento amp-experiment. Cualquier configuración hecha en este elemento también será expuesta a amp-analytics y amp-pixel, de tal modo que podrás fácilmente hacer un análisis estadístico de tu experimento.

Aún hay muchos desarrollos en marcha para AMP Analytics que te pueden ayudar a obtener una visión a medida que AMPlificas la experiencia del usuario en tu sitio. Visita la hoja de ruta del proyecto AMP para ver un resumen de lo que el equipo está preparando. Si ves que falta alguna característica, presenta una solicitud en GitHub.

Publicado por Nathan Martz, Gerente de producto, Google VR

En Google I/O, anunciamos Daydream, la plataforma de Google para realidad virtual móvil de alta calidad, y lanzamos los recursos para desarrolladores de antemano para que la comunidad empiece a construir para Daydream. Desde ese momento, el equipo ha trabajado duro, escuchado comentarios y evolucionado estos recursos en un conjunto de herramientas poderosas para desarrolladores.
Publicado por Nathan Martz, Gerente de producto, Google VR

En Google I/O, anunciamos Daydream, la plataforma de Google para realidad virtual móvil de alta calidad, y lanzamos los recursos para desarrolladores de antemano para que la comunidad empiece a construir para Daydream. Desde ese momento, el equipo ha trabajado duro, escuchado comentarios y evolucionado estos recursos en un conjunto de herramientas poderosas para desarrolladores.

Hoy en día, estamos orgullosos de anunciar que Google VR SDK 1.0 con compatibilidad para Daydream ha progresado de la versión beta y ahora está disponible en el sitio para programadores de Daydream. Nuestro SDK actualizado simplifica las tareas comunes de desarrollo VR de tal forma que te puedes enfocar en construir aplicaciones interactivas y móviles de VR para teléfonos y auriculares listos para usar Daydream, y compatible con reproyección asincrónica integrada, audio espacial de alta fidelidad e interacciones usando el controlador de Daydream.





Para hacer más fácil empezar a desarrollar con Google VR SDK 1.0, nos hemos asociado con Unity y Unreal para que puedas usar los motores de juegos y las herramientas con las que ya estás familiarizado. También hemos actualizado el sitio con documentación completa, aplicaciones de ejemplo para la referencia y tutoriales.

Integración nativa de Unity

Este lanzamiento marca el debut de la integración nativa de Daydream en Unity, lo cual permite a los desarrolladores de Daydream aprovechar al máximo todas las optimizaciones de Unity en reproducción de VR. También agrega compatibilidad a características como el seguimiento de cabeza, vínculo directo y la configuración manifiesta de Android de manera sencilla. Muchas aplicaciones de Daydream lanzadas ya están funcionando con las características recientes de integración, y ahora puedes descargar el nuevo complemento ejecutable de Unity aquí y el nuevo complemento de Daydream aquí.

Integración nativa UE4

Hemos hecho mejoras significativas a nuestra integración UE4 que ayudará a los desarrolladores a construir aplicaciones Daydream con una mejor calidad. La última versión incluye la compatibilidad del controlador de Daydream en el editor, un nuevo modelo de cuello, nuevas optimizaciones de reproducción y mucho más. Los desarrolladores de UE4 pueden descargar la fuente aquí.

Comienza hoy

Mientras que los primeros teléfonos y auriculares listos para usar Daydream salen al mercado este otoño, puedes empezar a desarrollar aplicaciones Daydream de alta calidad ahora mismo con Google VR SDK 1.0 y el kit del desarrollador DIY.

También abrimos aplicaciones a nuestro Programa de acceso de Daydream (Daydream Access Program, DAP) para que podemos trabajar más de cerca con más desarrolladores para construir un gran contenido para Daydream. Envía tu propuesta de aplicaciones de Daydream para aplicar y ser parte de nuestro DAP.

Cuando creas contenido para la plataforma Daydream, sabes que tus aplicaciones trabajarán sin problemas en todos los teléfonos y auriculares listos para usar Daydream. Daydream apenas está empezando y esperamos trabajar juntos para ayudarte a construir nuevas experiencias VR interactivas y profundas. Mantente al tanto para obtener más información sobre los teléfonos y auriculares listos para usar Daydream y los controladores que saldrán próximamente.


Tu aplicación, tu estilo de mapa. Para iOS y Android.


Los estilos de mapas personalizados multiplataforma están aquí: cambia la paleta de colores de los mapas, oculta etiquetas, modifica la densidad de las rutas y activa o desactiva puntos de interés. Tus mapas ahora pueden coincidir con tu marca y estilo en tu sitio web y tus apps.

Tu aplicación, tu estilo de mapa. Para iOS y Android.


Los estilos de mapas personalizados multiplataforma están aquí: cambia la paleta de colores de los mapas, oculta etiquetas, modifica la densidad de las rutas y activa o desactiva puntos de interés. Tus mapas ahora pueden coincidir con tu marca y estilo en tu sitio web y tus apps.

Las API de Google Maps ahora te permiten crear mapas con un estilo hermoso para tus apps en Android e iOS, así como para tu sitio web con el mismo objeto de estilo JSON.

Crea fácilmente tu estilo

El nuevo Asistente de ajuste de estilo de la API de Google Maps te ayuda a crear un estilo de mapa con unos pocos clics. Usa uno de nuestros estilos prediseñados o crea tu propio estilo desde cero.

Accede a opciones avanzadas para tener mayor control sobre cada aspecto disponible de tu estilo de mapa, incluidos la visibilidad, los rellenos y el grosor de trazo.

Utiliza el asistente de ajuste de estilo para crear un estilo personalizado con la función de señalar y hacer clic.

Muestra lo que es importante, oculta el resto

El ajuste de estilo de mapas te ofrece modos de personalizar tu mapa para un caso de uso particular. ¿Tienes tus propias paradas de tránsito y deseas desactivar las de Google? Podemos hacerlo. ¿Deseas ocultar las rutas y destacar los cursos de agua? Listo. Puedes controlar la visibilidad de etiquetas, paisajes, íconos de tránsito, puntos de interés, rutas y más para crear la apariencia que refleje tu marca y finalidad. Consulta la ejemplos para Android, iOS y JavaScript.

Los SDK para iOS y Android ahora también admiten puntos de interés comerciales; esto significa que ahora puedes ver hoteles, restaurantes y comercios en tus mapas. Solo estarán visibles cuando realices la compilación con los SDK más recientes y podrás controlar su visibilidad mediante los ajustes de estilo.

Ajusta el estilo solo una vez y utilízalo en cualquier plataforma

Cuando estés satisfecho con el nuevo estilo de mapa, puedes exportarlo y utilizar el mismo objeto de estilo JSON en nuestras API de Maps en iOS, Android y JavaScript. El Asistente de estilo también proporciona la URL que debes usar con la API de Google Static Maps.

Para habilitar un estilo personalizado en tu app o sitio web, echa un vistazo a los ejemplos de código: Android, iOS y JavaScript.

Puedes distribuir los estilos con tu app, obtenerlos dinámicamente e, incluso, cambiarlos durante el tiempo de ejecución.
Los estilos personalizados ahora funcionan en apps nativas en iOS y Android, al igual que en la Web.
Las notas de la versión para Android e iOS contienen información detallada sobre errores corregidos y las funciones de estilo de mapa básico personalizado mencionadas en esta publicación. Lee las guías de estilo de las API de Maps para Android, iOS y JavaScript, y mira el Geocast “Styling your Maps” (incorporado a continuación).






Agradecemos enormemente
 a los programadores de Android e iOS de todas partes por usar la API de Google Maps para Android, los SDK de Google Maps para iOS y enviar comentarios a través del seguimiento de problemas. Los hemos tenido en cuenta.

Comparte tus mapas básicos con estilo en Twitter y G+ a través de #mapstyle y muéstranos lo que has hecho.
author image Publicado por Megan Boundey, Gerente de producto, API de Google Maps para dispositivos móviles

Publicado por Michael Winser, jefe de producción, Google Apps y Wesley Chun, representante de desarrolladores, Google Apps
La semana pasada, explicamos las expectativas y responsabilidades inherentes al acceso a los datos de un usuario de Google a través de Oauth 2.0. Hoy queremos anunciar que a partir del ...
Publicado por Michael Winser, jefe de producción, Google Apps y Wesley Chun, representante de desarrolladores, Google Apps
La semana pasada, explicamos las expectativas y responsabilidades inherentes al acceso a los datos de un usuario de Google a través de Oauth 2.0. Hoy queremos anunciar que a partir del 5 de octubre de 2016 vamos a aumentar la seguridad de las cuentas para los usuarios empresariales de Gmail. Hoy entrará en vigencia una nueva política: a partir de esta fecha, a los usuarios en un dominio de Google Apps que cambien sus contraseñas se les anularán los token de Oauth 2.0 de las aplicaciones que tienen acceso a sus casillas de correo utilizando ámbitos de autorización basados en Gmail. Ten en cuenta que hoy los usuarios no notarán ningún cambio en especial y sus aplicaciones continuarán funcionando. Los tokens relacionados a Gmail pertenecientes a un usuario en particular solo quedarán invalidados a partir del momento en que este cambie su contraseña.

Los programadores deberían modificar sus aplicaciones para que puedan encargarse de códigos de error tales como HTTP 400 o 401, que son el resultado de tokens anulados y que solicitan a sus usuarios volver a repetir el proceso de OAuth para autorizar nuevamente a esas aplicaciones, de manera que puedan acceder otra vez a la casilla de correo del usuario (más abajo podrás encontrar más detalles). A fines del año pasado, anunciamos un cambio previsto y similar para nuestra política de seguridad, que afectó a un grupo más amplio de ámbitos de autorización. Luego de un tiempo, decidimos no implementar ese cambio para los clientes de las aplicaciones, y comenzamos a trabajar en una actualización de menor impacto, como lo explicamos más abajo.

¿Qué es un token anulado?

Un token de Oauth 2.0 anulado ya no proporcionará acceso a los recursos de un usuario. Cualquier intento de utilizar un token anulado en alguna llamada a una API dará como resultado un error. Las strings de los tokens que sigan existiendo ya no tendrán ningún valor, y deberían ser eliminadas. Se deben modificar las aplicaciones que accedan a las API de Google para que puedan encargarse de las llamadas erróneas a una API.

La anulación de un token no es una característica nueva. Los usuarios siempre pudieron anular el acceso a las aplicaciones en el control de seguridad, y los administradores de Google Apps pueden hacer lo mismo en la consola del administrador. A su vez, los tokens que no se utilizan por largos períodos de tiempo siempre han estado destinados a expirar o ser anulados. Este cambio en nuestra política de seguridad aumentará ciertamente la cantidad de tokens anulados que ven las aplicaciones, dado que en algunos casos el proceso se llevará a cabo en forma automática.

¿Cuáles son las API y ámbitos afectados por esto?

Hemos decidido limitar su aplicación solamente a ámbitos de correo y excluir tokens de scripts de aplicaciones para conseguir los beneficios de seguridad de este cambio de política, minimizar la confusión para los administradores y poner fin a la disrupción para el usuario final. Las aplicaciones que se instalen a través del Google Apps Marketplace tampoco estarán sujetas a la anulación del token. Una vez que este cambio haya sido implementado, las aplicaciones de correo de terceros como Apple Mail y Thunderbird (al igual que otras aplicaciones que usan varios ámbitos, que incluyen al menos un ámbito de correo) dejarán de tener acceso a los datos luego de un restablecimiento de contraseña, hasta que se haya otorgado un nuevo token de OAuth 2.0. Tu aplicación deberá detectar este caso en particular, notificar al usuario que tu aplicación ha perdido el acceso a los datos de su cuenta y solicitarle que vuelva a realizar el proceso de OAuth 2.0.

En este cambio de política también están incluidas las aplicaciones de correo para dispositivos móviles. Por ejemplo, los usuarios que utilizan la aplicación de correo nativa en iOS deberán volver a autorizarla con sus credenciales de cuenta de Google cuando cambien sus contraseñas. Este nuevo comportamiento en las aplicaciones de correo de terceros para plataformas móviles se pone en concordancia con el comportamiento actual de las aplicaciones de Gmail en iOS y Android, que también necesitan volver a autorizarlas luego de cambiar la contraseña.

¿Cómo puedo saber si mi token fue anulado?

Tanto los tokens de acceso de corta duración como los de larga duración serán anulados cuando un usuario cambie su contraseña. La utilización de un token de acceso anulado para acceder a una API o para generar un nuevo token de acceso dará como resultado un error HTTP 400 o 401. Si tu aplicación utiliza una biblioteca para acceder a la API o para controlar el proceso de OAuth, seguramente estos errores aparecerán como excepciones. En la documentación de la biblioteca, podrás encontrar información sobre cómo interceptar estas excepciones. NOTA: debido a que los errores HTTP 400 pueden estar causados por una gran variedad de motivos, debes tener en cuenta que la carga de un tipo 400 que haya sido producto de un token anulado, puede ser similar a:

{
  "error_description": "Token has been revoked.", 
  "error": "invalid_grant"
}

¿Cómo puede mi aplicación controlar los tokens anulados?

Este cambio hace hincapié en que la anulación de un token debería ser considerada una condición normal, no un caso erróneo. Tu aplicación debería esperar y detectar a la condición, y tu IU debería estar optimizada para ser capaz de restaurar un token.

Para asegurarte de que tu aplicación funcione correctamente, te recomendamos lo siguiente:

  • Agrega código que se encargue de controlar los errores entre las llamadas a una API y actualizaciones de token que puedan detectar los token anulados.
  • Luego de detectar un token anulado, deshabilita las funciones de la aplicación que dependan del acceso a las API de Google, hasta que el usuario pueda volver a autorizar tu aplicación. Por ejemplo, suspende cualquier tarea recurrente en segundo plano que sincronice datos con alguna API de Google que pudiera estar afectada.
  • Notifica al usuario que el acceso ha sido anulado y pídele que vuelva a autorizar el acceso a sus recursos.
    • Si tu aplicación interactúa directamente con el usuario, deberás pedirle a este que vuelva a autorizar, por ejemplo, enviarle un correo electrónico al usuario y/o mostrarle un mensaje de alerta la próxima vez que inicie tu aplicación.
    • Sin embargo, si tu aplicación se ejecuta de forma independiente con respecto al usuario, por ejemplo, una aplicación de segundo plano que utilice la API de Gmail, deberás darle aviso al usuario a través de un correo electrónico u otro tipo de mecanismo.
    • Asegúrate de brindar una IU simple para volver a autorizar el acceso. Evita que los usuarios tengan que explorar tu aplicación para encontrar la configuración original.
    • Ten en cuenta que los token anulados darán como resultado mensajes de error similares, sin importar cómo haya sido anulado cada uno. El mensaje que envíes no debería dar por sentado que el token fue anulado debido a un cambio de contraseña.

Si tu aplicación utiliza la autorización progresiva juntar varios ámbitos dentro del mismo token, deberías monitorear qué funcionalidades y ámbitos han sido habilitadas por un usuario en particular. El resultado final es que si tu aplicación solicitó y obtuvo autorización para varios ámbitos y por lo menos uno de estos es un ámbito de correo, entonces ese token será anulado; significa que deberás pedirle al usuario que vuelva a conceder autorización para todos los ámbitos que originalmente estaban autorizados.

Muchas aplicaciones usan los token para realizar llamadas a API en segundo plano o de servidor a servidor. Los usuarios confían en que esta actividad en segundo plano funciona sin problemas. Dado que este cambio de política también afecta a aquellas aplicaciones, esto eleva la importancia que tienen las notificaciones para solicitar una nueva autorización.

¿Para cuándo está programado este cambio?

En resumen, las aplicaciones que estén adecuadamente configuradas deberían, por lo general, ser capaces de controlar a los token anulados, sin importar si su condición es producto de una caducidad, una inexistencia o un anulamiento. Alentamos a los programadores a realizar los cambios necesarios para proporcionarle a los usuarios la mejor experiencia posible. Este cambio de política entrará en vigencia el 5 de octubre de 2016.

Consulta este artículo del Centro de ayuda y las preguntas frecuentes para obtener más información y la lista completa de los ámbitos de correo. De ahora en adelante se comunicará por adelantado cuando sea necesario agregar ámbitos adicionales a la política. Informaremos a medida que los detalles estén disponibles.


  • Se pueden enviar múltiples solicitudes en una sola conexión. Con HTTP/2, la necesidad de concentrar recursos es menor.
  • Es un protocolo binario, lo que significa que los títulos se pueden comprimir y los datos se pueden enviar eficientemente.
  • Los servidores pueden "empujar" contenido a los clientes.

Hoy nos emociona anunciar la disponibilidad de HTTP/2 en el Hosting de Firebase. HTTP/2 es una nueva versión del protocolo HTTP que ya es compatible con el 77 % de todos los navegadores a nivel mundial. Ofrece interesantes ventajas para los desarrolladores web:
  • Se pueden enviar múltiples solicitudes en una sola conexión. Con HTTP/2, la necesidad de concentrar recursos es menor.
  • Es un protocolo binario, lo que significa que los títulos se pueden comprimir y los datos se pueden enviar eficientemente.
  • Los servidores pueden "empujar" contenido a los clientes.

En conjunto, estas ventajas se suman a otras ventajas significativas de rendimiento y a muchas oportunidades para que tus aplicaciones web carguen más rápido en los dispositivo móviles con conexiones lentas.

Actualmente HTTP/2 está habilitado para todo el tráfico de *.firebaseapp.com y los dominios personalizados que sean provisionados recientemente. Si ya tienes un dominio personalizado en Firebase, mira Migración de dominios personalizados abajo.

Ventajas de HTTP/2 en el Hosting de Firebase


Para utilizar HTTP/2 en el Hosting de Firebase, ¡no tienes que hacer nada! Funcionará automáticamente si es compatible con el navegador del usuario. Sin embargo, existen algunas buenas prácticas que debes tener en cuenta si quieres optimizar para HTTP/2:
  1. Dado que se puede usar una sola conexión para varias solicitudes múltiples, ya no existe una ventaja en concatenar gran cantidad de recursos juntos. Dado que los navegadores hacen un buen trabajo a la hora de almacenar recursos, es mejor servir más archivos que no cambien de manera frecuente. Ten en cuenta que cuando nos referimos a más archivos, queremos decir decenas, ya que cientos pueden significar un exceso.
  2. Ya no es necesario (o deseable) "dividir" activos entre muchos dominios. El Hosting de Firebase ya es servido en una CDN rápida y HTTP/2 hace que sea una ventaja servir todos tus archivos desde el mismo dominio.
  3. ¡Solo carga los activos que necesites! Con menos viajes, deberías optimizar tu sitio para que cargue únicamente los archivos que necesitas para impulsar el armazón de tu aplicación. Se pueden cargar otros recursos en demanda con base a la interacción del usuario.

Las guías presentadas anteriormente no son normas rígidas. Como ocurre con cualquier optimización de rendimiento, debes experimentar con diferentes combinaciones de optimizaciones para ver cuáles ofrecen el mejor resultado para las necesidades específicas de tu aplicación.

Experimentar con el Servidor Push


El Hosting de Firebase cuenta con una compatibilidad experimental para el servidor push de HTTP/2 que usa encabezados de vínculo. El servidor push permite al servidor enviar automáticamente los contenidos para recursos adicionales cuando se hace una solicitud inicial. El uso más común para el servidor push es enviar activos asociados (como archivos JavaScript o CSS) cuando se carga una página.

Para configurar el servidor push en el Hosting de Firebase, necesitas agregar el encabezado de vínculo en tu configuración firebase.json así:
{
  "hosting": {
    "headers": [
      {
        "source": "/",
        "headers": [{"key": "Link", "value": "</js/app.js>;rel=preload;as=script,</css/app.css>;rel=preload;as=style"}]
      },
      {
         "source": "/users/*",
        "headers": [{"key": "Link", "value": "</js/app.js>;rel=preload;as=script,</css/app.css>;rel=preload;as=style;nopush,</css/users.css>;rel=preload;as=style"}]
      }
    ]
  }
}

Aquí estamos usando el servidor push para precargar /js/app.js y /css/app.css en la ruta de acceso, y /css/users.css en cualquier ruta de acceso que corresponda con /users/*. Puedes usar la directiva nopush (como en app.css en el segundo ejemplo) para precargar el activo sin que HTTP/2 envíe los archivos que probablemente ya estén en la memoria caché del navegador.

El servidor push aún está en una etapa temprana y hay algunas cosas que hay que tener en cuenta:
  1. Ten cuidado con el comodín al configurar los encabezados de vínculo. Los recursos no se deben configurar para que se precarguen ellos mismos.
  2. El servidor push es una compensación entre el rendimiento y el uso del ancho de banda. Si envías activos que ya están en la memoria caché del navegador, estarás enviando información innecesaria. Intenta que los activos enviados sean pequeños, que sean críticos para el rendimiento y ten en cuenta que ¡es posible que tus usuarios tengan que pagar por los datos adicionales en sus dispositivos móviles!.
  3. ¡Precargar es muy bueno para el rendimiento incluso si no se envía! Si agregas ;nopush a tu encabezado de vínculo precargado, le dirá al navegador que lo precargue sin el servidor push. Esto es genial para los activos que consideres que ya pueden estar en la memoria caché del navegador.

Estamos emocionados por el potencial de HTTP/2 para mejorar la experiencia de la primera carga, y continuamos explorando formas adicionales para que el servidor push sea simple, confiable y efectivo para tu sitio.

Migración al Dominio personalizado


Con nuestra migración a HTTP/2 también nos estamos moviendo a la Indicación del nombre del servidor (SNI, por sus siglas en inglés) para nuestros certificados SSL. SNI nos permite continuar con el crecimiento de nuestra infraestructura de una manera confiable y es compatible con cerca del 98 % de los navegadores a nivel mundial. Dado que este cambio tiene la posibilidad de afectar el tráfico del usuario, no estamos cambiando automáticamente en los dominios personalizados existentes hasta diciembre de 2016.

Si tienes un dominio personalizada en el Hosting de Firebase antes de agosto 11 de 2016, necesitarás actualizar tus registros DNS para aprovechar el HTTP/2. Puedes verificar si ya estás en SNI ejecutando dig <your-site>.firebaseapp.com. Si ves s-sni.firebaseapp.com en el resultado, tu sitio ya migró.

Para migrar si estás usando un CNAME, actualiza tu DNS para que se dirija a s-sni.firebaseapp.com. Si usas registros A, actualízalos a:
151.101.1.195
151.101.65.195

Una vez que cambies tu DNS y se haya propagado, ¡tu sitio estará vivo usando HTTP/2! Estaremos en un proceso de transición del trafico del Hosting de Firebase a HTTP/2 y SNI hasta el final del año, por lo tanto busca asesoría si estás preocupado sobre cómo la SNI puede afectar a tus usuarios.

Nuestro objetivo con el Hosting de Firebase es que las mejores prácticas para el desarrollo de las aplicaciones web progresivas estén al alcance de todos. HTTP/2 es otro paso en el camino, ¡y nos gustaría saber los que puedes construir con éste!


publicado originalmente en el blog de eBay por Senthil Padmanabhan, Ingeniero jefe. ...

publicado originalmente en el blog de eBay por Senthil Padmanabhan, Ingeniero jefe.

eBay continúa aprovechando la tecnología AMP para acelerar y mejorar las experiencias móviles.


Native Ads Express de Admob es una forma rápida y sencilla de crear y monetizar sus anuncios nativos de manera efectiva. Tres programadores comparten sus historias de éxito al pasar a Native y lograr el crecimiento de sus ingresos y empresas.

Native Ads Express de Admob es una forma rápida y sencilla de crear y monetizar sus anuncios nativos de manera efectiva. Tres programadores comparten sus historias de éxito al pasar a Native y lograr el crecimiento de sus ingresos y empresas.




1. Word Search, por Fijar Pointer

Los fanáticos de las palabras de todo el mundo no se cansan de usar Word Search (también conocido como Word Find, Word Seek o Word Sleuth), un juego latinoamericano de búsqueda de palabras con más de 22 000 opciones, divididas en 37 idiomas.

Cómo usan los anuncios nativos:


Los anuncios nativos funcionan bien en feeds de contenido, es por ello que Pink Pointer lo utiliza en su feed de juegos de búsqueda de palabras. Cuando los usuarios acceden para jugar, ven una lista con todos los juegos disponibles. El anuncio nativo está incorporado dentro de la lista, lo que lo hace atractivo y fácil de ver, pero nunca invasivo.





Resultados:

Al reemplazar los banners de la parte superior de la página, Thiago Lopes Rosa de Pink Pointer vio un incremento del 50 % en CTR y del 90 % en RPM, lo que permitió maximizar los ingresos sin comprometer la experiencia del usuario.

Sugerencias del programador Thiago Lopes Rosa:


"Recomiendo crear diferentes anuncios para cada ubicación de anuncios nativos. Esto permite analizar el rendimiento de cada uno individualmente, así como implementar acciones adecuadas y obtener estadísticas sobre cómo mejorar".





2. Battery Doctor (también llamado Battery Saver), por Cheetah Mobile

Battery Doctor, que ha recibido consultas de 330 millones de usuarios, es una app mide las aplicaciones que producen un mayor consumo de la batería del teléfono y ofrece una función de optimización que detiene estas aplicaciones con un solo toque. Esta popular herramienta es idea original de uno de los principales programadores a nivel mundial, Cheetah Mobile, que cuenta con más de 600 millones de usuarios activos por mes.

Cómo usan los anuncios nativos:

Battery Doctor mide el uso de las apps y brinda al usuario una predicción de la batería restante en una lista de tarjetas informativas. Esta lista incluye un anuncio nativo que se integra sin problemas como su propia tarjeta.





Resultados:

El uso de anuncios nativos significó una importante recarga en los ingresos de Cheetah. Según Charles Fan, de Cheetah Mobile, "los ingresos por monetización de Battery Doctor se incrementaron en un 400 %, lo que representa un resultado excelente".

Sugerencia del programador Charles Fan:


"Busque áreas en donde pueda integrar anuncios nativos sin interrumpir el flujo de trabajo de la app o el flujo del usuario".





3. Chinese Calendar, por Linghit Limited

Aquellos que necesiten espiar el futuro deben consultar la aplicación Chinese Calendar de Linghit. Esta app integra un calendario y una guía de adivinación basados en las tradicionales creencias chinas y en el calendario lunar. La app destaca los mejores días y momentos para celebrar eventos importantes como bodas y también para planificar vacaciones, remodelaciones o mudanzas.

Cómo usan los anuncios nativos:

La app incluye información sobre las festividades diarias, los feriados y los "cinco elementos" de la suerte, según la tradición china. Este resumen diario se presenta en forma de tarjeta y ofrece un lugar perfecto para que Linghit muestre un anuncio nativo.





Resultados:

Los anuncios nativos fueron de mucha suerte para Jinnee Lee, de Linghit Limited. "Después de implementar los anuncios nativos, las impresiones de nuestro anuncio se incrementaron en 114 %, y los ingresos por anuncios se incrementaron en un 100 %".

Sugerencia de la programadora Jinnee Lee:


“Los anuncios nativos son más intuitivos. Por ello, los mostramos en posiciones más destacadas dentro de las apps. Pudimos ver los efectos de las tasas de clics de los usuarios en tiempo real en base a la información del backend del anuncio. También pudimos realizar ajustes rápidos en los anuncios nativos para maximizar su efecto”.

¿No conoce los anuncios nativos? Consulte nuestro centro de ayuda.





Hasta la próxima, siga nuestras páginas de Twitter, LinkedIn y Google+ para permanecer conectado con AdMob.

Publicado por Chris Jones, Equipo social, AdMob.



AdMob by Google es una de las principales plataformas de anuncios para dispositivos móviles, en la que confían más de 650.000 aplicaciones en todo el mundo. Si deseas conocer más acerca de AdMob, visita este enlace.

publicado por Doug Stevenson,Representante de desarrolladores
publicado por Doug Stevenson,Representante de desarrolladores


¡Hola! Acabas de unirte a nosotros para la segunda parte de una serie de blogs sobre la API Play Services Task, usada por algunas características de Firebase para responder al trabajo realizado por sus API de forma asincrónica. La última vez, nos familiarizamos con una Task usada por la API Almacenamiento de Firebase, y aprendimos un poco sobre cómo funcionan en general las Tasks. Si aún nos has visto la publicación, ahora es el momento para volver a la publicación antes de continuar. En esta publicación, daremos un vistazo a algunos de los matices sobre el comportamiento entre las diferentes variaciones para agregar a un receptor a una Task para capturar su resultado.
La última vez vimos cómo un receptor se adiciona a una Task como esta, usando la API de Almacenamiento de Firebase:
    Task task = forestRef.getMetadata();
    task.addOnSuccessListener(new OnSuccessListener() {
        @Override
        public void onSuccess(StorageMetadata storageMetadata) {
            // Metadata now contains the metadata for 'images/forest.jpg'
        }
    });

En este código, addOnSuccessListener() se llama con un solo argumento, que es un receptor anónimo que se invoca una vez completado. Con esta forma, el receptor se invoca en el hilo principal, lo que significa que podemos hacer cosas que solo se pueden hacer en el hilo principal, como actualizar una Vista. Es genial que la Task ayude a poner devuelta el trabajo en el hilo principal, sin embargo existe una advertencia. Si un receptor se registra así en una Actividad y no es removido antes de que la Actividad se destruya, existe la posibilidad de una fuga de Actividad.

¡Pero yo no quiero Actividades con fugas!


De acuerdo, ¡nadie quiere Actividades con fugas! Entonces, ¿qué es una fuga de Actividad? Brevemente, una fuga de Actividad ocurre cuando un objeto mantiene una referencia de objeto de una Actividad más allá de su método de ciclo de vida de onDestroy(), reteniendo la Actividad más allá del tiempo útil. Cuando se llama onDestroy() en un Actividad, puedes estar seguro de que la instancia nunca se usará de nuevo por Android. Después de onDestroy(), queremos que el recolector de basura de tiempo de ejecución de Android limpie la Actividad, todas sus Vistas y otros objetos muertos. ¡Pero el recolector de basura no limpiará la Actividad y todas sus vistas si otro objeto mantiene una referencia fuerte hacia ésta!

Las fugas de Actividades pueden ser un problema con las Tasks, a menos de las evites. En el código de arriba (si estuviera dentro de una Actividad), el receptor anónimo mantiene una referencia fuerte e implícita hacia la Actividad contenida. Así es como el código dentro del receptor puede hacer cambios a la Actividad y a sus miembros. El compilador resuelve silenciosamente los detalles de esto. Una fuga de Actividad ocurre cuando una Tarea en progreso se mantiene en el receptor previo a onDestroy() de la Actividad. En verdad no tenemos ninguna garantía sobre cuánto tiempo tomará la Task, por lo tanto el receptor se puede mantener indefinidamente. Dado que el receptor mantiene implícitamente una referencia de la Actividad, la Actividad se puede fugar si la Task no se completa antes de onDestroy(). Si muchas de las Tasks que mantienen referencias a Actividades crean una copia de seguridad a medida que pasa el tiempo (por ejemplo, debido a una caída de la red), esto puede causar que tu aplicación se quede sin memoria y falle. Tú. Puedes obtener más información en este video.

Devuelta a la Task a mano


Si estás interesado en Actividades con fugas (¡espero que lo estés!), debes saber que la versión simple del argumento addOnSuccessListener() tiene la advertencia de una posible fuga de la Actividad si no eres cuidadoso al remover el receptor en el momento adecuado.

Existe una mejor manera de hacer esto automáticamente con la API Task. Tomemos como ejemplo el código de arriba en una Actividad y modifiquemos ligeramente su llamada addOnSuccessListener():

    Task task = forestRef.getMetadata();
    task.addOnSuccessListener(this, new OnSuccessListener() {
        @Override
        public void onSuccess(StorageMetadata storageMetadata) {
            // Metadata now contains the metadata for 'images/forest.jpg'
        }
    });

Esto es exactamente como la versión anterior, excepto que ahora hay dos argumentos para addOnSuccessListener(). El primer argumento es `this`, de tal modo que cuando este código esté en una Actividad, hará que `this` se refiera a esa instancia de Actividad encerrada. Cuando el primer parámetro es una referencia de Actividad, esto le dice a la API Task que este receptor debe ser "enfocado" al ciclo de vida de la Actividad. Esto significa que el receptor será automáticamente removido de la tarea cuando la Actividad pase a través de su método del ciclo de vida onStop() Esto es muy útil porque no necesitas recordar que debes hacerlo para todas las Tasks que puedas crear mientras un Actividad está activa. Sin embargo, necesitas estar seguro de que onStop() es el lugar correcto para detener la recepción. onStop() se activa cuando una Actividad no es visible, lo cual comúnmente está bien. Sin embargo, si quieres realizar un seguimiento de la Task en la siguiente Actividad (como cuando un cambio de orientación cambia la Actividad actual por una nueva), necesitarás crear una manera de retener ese conocimiento en la siguiente Actividad. Para más información sobre esto, lee guardar el estado de la Actividad.

Omitir el tráfico en Main St.


Existen algunos casos en donde simplemente no quieres reaccionar para completar la Task en el hilo principal. Tal vez quieres trabajar en bloque en tu receptor, o quieres ser capaz de manejar diferentes resultados de Tasks simultáneamente (en lugar de secuencialmente). Por lo tanto, te gustaría evitar el hilo principal en conjunto y por el contrario procesar el resultado en otro hilo que tú controles. Existe otra forma de addOnSuccessListener() que puede ayudar a tu aplicación con tus hilos. Así es como se ve (con el receptor abreviado):
    Executor executor = ...;  // obtain some Executor instance
    Task task = RemoteConfig.getInstance().fetch();
    task.addOnSuccessListener(executor, new OnSuccessListener() { ... });

Acá estamos llamando a la API Configuración remota de Firebase para obtener nuevos valores de configuración. Luego, la Task que muestra fetch() obtiene una llamada a addOnSuccessListener() y recibe un Ejecutor como primer argumento. Este ejecutor determina el hilo que se usará para invocar al receptor. Para aquellos que no están familiarizados con el Ejecutor, es una utilidad núcleo de Java que acepta unidades de trabajo y las encamina para ser ejecutadas en hilos bajo su control. Esto puede ser un solo hilo, o un conjunto de hilos, todos esperando hacer el trabajo. Para las aplicaciones no es muy común usar el Ejecutor directamente, y puede ser visto como una técnica avanzada para administrar el comportamiento del hilo de tu aplicación. Lo que debes recordar es el hecho de que no necesitas recibir a tus receptores en el hilo principal si no te conviene. Si decides usar un Ejecutor, asegúrate de administrarlos como individuos compartidos, o asegúrate de que sus ciclos de vida también estén administrados para que sus hilos no se fuguen.

Otra cosa interesante para tener en cuenta sobre este código es el hecho de que la Task que muestra la Configuración remota es parametrizada por Void. Esta es la manera en que una Task puede decir que no necesita generar un objeto indirecto. Void es el tipo de datos en Java que indica la ausencia de datos tipo. La API de Configuración remota simplemente usa la Task como un indicador de la terminación de la tarea, y se espera que el emisor use la API Configuración remota para descubrir los nuevos valores que fueron obtenidos.

¡Elige sabiamente!


Existen tres variedades de addOnSuccessListener():
    Task addOnSuccessListener(OnCompleteListener listener) 
    Task addOnSuccessListener(Activity activity, OnSuccessListener listener) 
    Task addOnSuccessListener(Executor executor, OnSuccessListener listener) 

Además de eso, tenemos las mismas variedades para receptores de fallo y terminación:
    Task addOnFailureListener(OnFailureListener listener)
    Task addOnFailureListener(Activity activity, OnFailureListener listener)
    Task addOnFailureListener(Executor executor, OnFailureListener listener)

    Task addOnCompleteListener(OnCompleteListener listener)
    Task addOnCompleteListener(Activity activity, OnCompleteListener listener)
    Task addOnCompleteListener(Executor executor, OnCompleteListener listener)

Espera, ¿qué es un OnCompleteListener?


No hay nada especial sobre OnCompleteListener. Simplemente es un receptor que es capaz de recibir el éxito y el fallo, y debes revisar el estado dentro de la llamada de retorno. El archivo de metadatos de llamada de retorno de la última publicación podría ser reescrito así, en lugar de darle a la aplicación receptores separados de éxito o fallo:
    Task task = forestRef.getMetadata();
    task.addOnCompleteListener(new OnCompleteListener() {
        @Override
        public void onComplete (Task task) {
            if (task.isSuccessful()) {
                StorageMetadata meta = task.getResult();
                // Do something with metadata...
            } else {
                Exception e = task.getException();
                // Handle the failure...
            }
        }
    });

Con OnCompleteListener, puedes tener un receptor independiente que maneja el éxito y el fallo, y puedes descubrir algunos de los dos llamando a isSuccessful() en el objeto de la Task que se pasa a la llamada de retorno. Esto es funcionalmente equivalente a registrar en ambos un OnSuccessListener y un OnFailureListener. El estilo que escojas es principalmente una cuestión de gustos.

Para concluir (la parte 2 de esta serie)


Has aprendido que las Tasks pueden recibir tres tipos de receptores: éxito, fracaso, y terminación total. Para cada uno de estos tipos de receptores, existen tres formas de recibir la llamada de retorno: en el hilo principal, en el hilo principal transferido a una Actividad, y en un hilo determinado por un Ejecutor. Aquí tienes algunas alternativas, y depende de ti escoger la opción que más te convenga. Sin embargo, estas no son las únicas maneras de manejar los resultados de tus Tasks. Puedes crear tuberías de resultados de Task para procesamientos más complejos. Para más detalles, acompáñame en la siguiente sesión, donde podrás continuar el viaje para convertirte en un Taskmaster de Firebase.

Si tienes alguna pregunta, puedes usar Twitter con el hashtag #AskFirebase o el Grupo de Google firebase-talk. También tenemos un canal dedicado a Firebase Slack. Y puedes seguirme en @CodingDoug en Twitter.
Lee la parte 1 de esta serie de blogs.