Adición de widgets a una página de lanzamiento sin bindAppWidgetId ()

Estoy tratando de convertir el lanzador ICS de valores en una aplicación independiente. Estoy casi allí – las únicas cosas que no funcionan son el icono de búsqueda y la caída de widgets en la pantalla, lo que provoca un accidente.

El bloqueo se debe a que el lanzador de valores utiliza appWidgetManager.bindAppWidgetId(appWidgetId, componentName); Para agregar widgets, que al parecer sólo las aplicaciones del sistema tienen permiso para hacerlo .

Así que mi pregunta es: ¿cuál es la forma correcta de que una aplicación que no sea del sistema agregue widgets y obtenga la misma experiencia de interfaz de usuario que el lanzador ICS de stock ?

Timmmm,

Su problema es que está buscando el objeto equivocado. Realmente no puedes controlar el AppWidgetManager . No es tu trabajo, es el sistema. Lo que PUEDES hacer es controlar un AppWidgetHost , solo requiere una semántica. Aquí están los conceptos básicos.

EDIT: Fondo adicional en el proceso de vinculación de Widget

AppWidgetManager es un objeto singleton que se ejecuta cuando se inicia el sistema. Esto significa que cada instancia de cada lanzador utiliza el mismo AppWidgetManager. Lo que los diferencia es su AppWidgetHost y las RemoteViews que están reteniendo actualmente. El AppWidgetManager básicamente mantiene una lista de todos los hosts activos y los widgets que contienen. Un AppWidgetHost no es un objeto privilegiado. Es decir, cualquier actividad puede tener un solo anfitrión. Por lo tanto, una aplicación completa puede ser nada más que Widgets, si así lo desean.

Cuando instancia el host, debe agregar vistas al mismo. Por lo tanto, básicamente, es una lista de vistas secundarias sin límites paternos obligatorios, excepto lo que su Actividad le da. Primero, usted pide una identificación (vía myHost.allocateAppWidgetId() ). A continuación, utiliza su Pick Widget Activity / Dialog. El cuadro de diálogo devuelve el WidgetInfo. La vista se recupera cuando solicita al host que cree la vista (a través de createView ) con WidgetInfo y el ID que solicitó. A continuación, pregunta al widget por su RemoteView .

Finalmente, enlaza el widget colocando la vista en su actividad como un niño. Esto se hace a través del método addView () del ViewGroup que contiene todos sus widgets.

El Proceso en Acción (EDITADO)

En primer lugar, usted tiene que asegurarse de que tiene esto en su manifiesto android:

 <uses-permission android:name="android.permission.BIND_APPWIDGET" /> 

A continuación, tienes que crear un AppWidgetHost (extiendo mi propio para mi lanzador). La clave para el Host es mantener una referencia a AppWidgetManager través de AppWidgetManager.getInstance(); .

 AppWidgetHost myHost = new AppWidgetHost(context, SOME_NUMERICAL_CONSTANT_AS_AN_ID); 

Ahora, obtenga su identificación:

 myHost.allocateAppWidgetId() 

El siguiente paso se realiza por cualquier método que utilice para obtener la información del widget. La mayoría de las veces se devuelve a través de un intento a través de onActivityResult. Ahora, todo lo que realmente tienes que hacer es usar el appInfo y crear la vista. El WidgetId normalmente es proporcionado por el resultado de la actividad del widget de selección.

 AppWidgetProviderInfo withWidgetInfo = AppWidgetManager.getInstance().getAppWidgetInfo(forWidgetId); AppWidgetHostView hostView = myWidgetHost.createView(myContext, forWidgetId, withWidgetInfo); hostView.setAppWidget(forWidgetId, withWidgetInfo); 

Ahora sólo debes vincular la vista como un niño a lo que quieras vincularlo.

 myViewGroup.addView(hostView); 

Por supuesto, usted siempre tiene que considerar dónde y cómo colocarlo, etc Además, usted tiene que asegurarse de que su AppWidgetHost está escuchando antes de empezar a agregar widgets.

myHost.startListening()

Para resumir

El proceso de vinculación de widgets abarca muchos métodos y pasos, pero todo se produce a través de AppWidgetHost . Debido a que los widgets están codificados fuera de su espacio de nombres, no tiene ningún control, excepto en el lugar en el que los ha colocado y en el tamaño de la vista. Puesto que en última instancia son código que se ejecuta en su espacio pero fuera de su control, el AppWidgetManager actúa como un mediador neutral , mientras que el AppWidgetHost sirve como facilitador en nombre de su aplicación. Una vez que esto se entiende, su tarea es simple. Los pasos anteriores son todos los pasos necesarios para cualquier lanzador personalizado (incluido el mío).

EDIT: Aclaración final

El ICS Launcher también lo hace. El appWidgetManager que utilizan es sólo un contenedor que contiene el AppWidgetHost y las llamadas a AppWidgetManager . Me olvido de que muy poco de esto se explica en el sitio web de Android Development Central.

¡Espero que esto ayude! Déjeme saber si usted necesita más detalles.

FuzzicalLogic

Ahora sé la respuesta definitiva. En Android 4.0, no puedes hacerlo. Acabé haciendo mis usuarios elegir el widget dos veces, lo que es una mierda, pero no hay manera de evitarlo.

En Android 4.1 arreglaron el problema!

¡Las aplicaciones SDK ahora pueden alojar widgets y no tienen que usar la API del selector de widget de basura! Puedes buscar en el código fuente de Jellybean Launcher2 para obtener detalles, pero básicamente, cuando intentes vincular un widget, Android mostrará un cuadro de diálogo que dice "¿Quieres permitir que esta aplicación vincule widgets?", Y luego el usuario puede Decidir darle permiso o no.

No estoy seguro de por qué fueron por el cuadro de diálogo de concesión de permisos modal en lugar del modelo de todos los permisos de instalación que usaron para todo lo demás, pero ¡funciona bien!

Ahora sólo tenemos que esperar 4 o 5 años hasta que todos tengan Android 4.1 o superior!

Acabo de encontrar este tutorial sobre cómo agregar appwidgets a las aplicaciones normales, lo que podría ayudar: http://coderender.blogspot.com/2012/01/hosting-android-widgets-my.html

Este tutorial todavía usa la lista de "Selección de AppWidget", por lo que podría no funcionar para usted ya que ICS tiene el selector de widgets dentro del propio cajón de la aplicación.

Aún así, vale la pena mencionar ya que los tutoriales sobre widgets de alojamiento son muy raros 🙂

Aclamaciones,
Yuvi

Fuzzical Logic, con su código de abajo,

 AppWidgetProviderInfo withWidgetInfo = AppWidgetManager.getInstance().getAppWidgetInfo(forWidgetId); AppWidgetHostView hostView = myWidgetHost.createView(myContext, forWidgetId, withWidgetInfo); hostView.setAppWidget(forWidgetId, withWidgetInfo); 

Si no tiene el permiso de bind_widget, widgethost no tiene nada, cus withwidgetinfo es nulo, widgethost crear nada.

  • ¿Cómo reconstruir la aplicación "Launcher" por defecto?
  • ¿Cómo obtener iconos hdpi de la aplicación en las tabletas de Android API 11 y más (en el código java)?
  • Información sobre Android sobre superposiciones flotantes / elementos sobre otras aplicaciones
  • Crear un ícono de inicio de Android para Website
  • El lanzador de encargo de android vuelve al lanzador de defecto al presionar el botón de la parte posterior
  • ¿Qué lanzador está funcionando?
  • Instalar el icono del lanzador en la pantalla de inicio una vez
  • Recuperación de la información de la aplicación del gestor de paquetes
  • Android, ¿cómo borrar la lista de tareas recientes que podría obtener desde el botón Inicio en la mayoría de teléfono? ¿La reflexión es una manera posible?
  • Diferenciar entre un inicio de actividad de la pantalla de inicio o de otra actividad de la aplicación
  • Proceso de construcción de Android secreto
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.