Acceso a elementos de diseño desde el interior Widget AppWidgetProvider

Estoy empezando a ir loco tratando de averiguar esto. Parece que debería ser muy fácil, estoy empezando a preguntarme si es posible.

Lo que estoy tratando de hacer es crear un widget de pantalla de inicio, que sólo contiene un ImageButton. Cuando se presiona, la idea es cambiar algún ajuste (como el conmutador wi-fi) y luego cambiar la imagen Botones.

Tengo el ImageButton declarado como esto en mi main.xml

<ImageButton android:id="@+id/buttonOne" android:src="@drawable/button_normal_ringer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> 

Mi clase AppWidgetProvider, llamada ButtonWidget

*** Observe que la clase RemoteViews es una variable almacenada localmente. Esto me permitió tener acceso a los elementos de diseño RViews … o por lo que pensé.

 @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { remoteViews = new RemoteViews(context.getPackageName(), R.layout.main); Intent active = new Intent(context, ButtonWidget.class); active.setAction(VIBRATE_UPDATE); active.putExtra("msg","TESTING"); PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context, 0, active, 0); remoteViews.setOnClickPendingIntent(R.id.buttonOne, actionPendingIntent); appWidgetManager.updateAppWidget(appWidgetIds, remoteViews); } @Override public void onReceive(Context context, Intent intent) { // v1.5 fix that doesn't call onDelete Action final String action = intent.getAction(); Log.d("onReceive",action); if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) { final int appWidgetId = intent.getExtras().getInt( AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) { this.onDeleted(context, new int[] { appWidgetId }); } } else { // check, if our Action was called if (intent.getAction().equals(VIBRATE_UPDATE)) { String msg = "null"; try { msg = intent.getStringExtra("msg"); } catch (NullPointerException e) { Log.e("Error", "msg = null"); } Log.d("onReceive",msg); if(remoteViews != null){ Log.d("onReceive",""+remoteViews.getLayoutId()); remoteViews.setImageViewResource(R.id.buttonOne, R.drawable.button_pressed_ringer); Log.d("onReceive", "tried to switch"); } else{ Log.d("F!", "--naughty language used here!!!--"); } } super.onReceive(context, intent); } } 

Así que he estado probando esto y el método onReceive funciona muy bien, puedo enviar notificaciones y todo tipo de cosas (eliminado del código para facilitar la lectura)

Lo único que no puedo hacer es cambiar las propiedades de los elementos de vista.

Para intentar solucionar esto, hice de RemoteViews una variable privada local y estática. Usando el registro, pude ver que cuando hay varias instancias de la aplicación en la pantalla, todas se refieren a una instancia de RemoteViews. Perfecto para lo que estoy tratando de hacer

El problema consiste en intentar cambiar la imagen del ImageButton.

Puedo hacer esto desde dentro del método onUpdate usando esto.

 remoteViews.setImageViewResource(R.id.buttonOne, R.drawable.button_pressed_ringer); 

Que no me hace nada bueno una vez que el widget se crea. Por alguna razón, aunque esté dentro de la misma clase, estar dentro del método onReceive hace que esa línea no funcione.

Esa línea usada para lanzar un puntero Nulo como una cuestión de hecho, hasta que cambié la variable a estática. Ahora pasa la prueba nula, se refiere a la misma layoutId como lo hizo al principio, lee la línea, pero no hace nada.

Es como si el código no estuviera allí, sólo sigue chugging.

ASI QUE……

¿Hay alguna manera de modificar elementos de diseño desde dentro de un widget después de que se ha creado el widget? Quiero hacer esto basado en el entorno, no con un lanzamiento de actividad de configuración.

He estado mirando varias preguntas y esto parece ser un problema que realmente no ha sido resuelto, como el texto del enlace y el texto del enlace

Oh y para cualquiera que encuentre esto y quiera un buen tutorial de inicio para los widgets, esto es fácil de seguir (aunque un poco viejo, se pone cómodo con los widgets) .pdf link text

Espero que alguien puede ayudar aquí. Tengo la sensación de que esto es ilegal y hay una manera diferente de ir sobre esto. Me encantaría que me dijeron otro enfoque !!!!

Gracias

2 Solutions collect form web for “Acceso a elementos de diseño desde el interior Widget AppWidgetProvider”

Puede volver a dibujar la pantalla utilizando otro diseño con sólo el ImageButton modificado. Esto suena como una solución hackish, pero funciona para mí.

 // Your appWidgetProvider class should track which layout it's currently on private static int layoutId; // onReceive should be something like this @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); if (bundle != null) { int newLayoutId = bundle.getInt("layout_id"); // Change the current layout id to the layout id contained in the bundle layoutId = newLayoutId; initViews(context); } else { initViews(context); } } // Initialize the view according to the chosen layout private void initViews(Context context) { RemoteViews views = null; // Set the initial layout if (layoutId == 0) { Intent layoutIntent = new Intent("android.appwidget.action.APPWIDGET_UPDATE"); Bundle layoutBundle = new Bundle(); // I put in the layoutId of the next layout. Note that the layoutId is not // from R. I just made up some easy to remember number for my layoutId layoutBundle.putInt("layout_id", 1); PendingIntent lPendingIntent = PendingIntent.getBroadcast(context, 0, layoutIntent, PendingIntent.FLAG_ONE_SHOT); // Set the layout to the first layout views = new RemoteViews(context.getPackageName(), R.layout.layout_zero); // I used buttons to trigger a layout change views.setOnClickPendingIntent(R.id.btnNext, lPendingIntent); } // Else if there's some trigger to change the layout... else if (layoutId == 1) { Intent layoutIntent = new Intent("android.appwidget.action.APPWIDGET_UPDATE"); Bundle layoutBundle = new Bundle(); // Since I only have two layouts, I put here the id of the previous layout layoutBundle.putInt("layout_id", 0); PendingIntent lPendingIntent = PendingIntent.getBroadcast(context, 0, layoutIntent, PendingIntent.FLAG_ONE_SHOT); // Set the layout to the second layout // This layout should be almost the same as the first layout except for the // part that you want to change views = new RemoteViews(context.getPackageName(), R.layout.layout_one); views.setOnClickPendingIntent(R.id.btnPrev, lPendingIntent); } } 

Como se puede ver, he utilizado dos diseños diferentes que el usuario es capaz de cambiar a través de clics de botón. Puede utilizar diferentes disparadores para cambiar el diseño según lo que necesite. Una solución similar se puede encontrar texto de enlace . Perdón por poner el código en onReceive en lugar de onUpdate 🙂

@Avendael Su código funciona perfectamente. Lo único que tienes que hacer es agregar widget de actualización. Algo como esto

 public static void buildUpdate(Context context) { RemoteViews updateViews; //Have your own condition here if (1==1){ layoutId = R.layout.main; } else { layoutId = R.layout.main1; } updateViews = new RemoteViews(context.getPackageName(), layoutId); //actually do things here //then finally, return our remoteView AppWidgetManager.getInstance(context).updateAppWidget( new ComponentName(context, ButtonWidget.class), updateViews); 

}

Llame a este método buildUpdate (context) después de asignar una nueva vista remota para actualizar el diseño del widget. Por ejemplo, podemos colocar esto después de views.setOnClickPendingIntent (); En el código anterior. Este es realmente un gran enfoque, fue muy útil para mí aplausos …

  • ¿Acceso estático a los recursos de una aplicación para Android?
  • Evento de clic de botón para el widget android
  • ¿Cómo establecer el texto dentro de TextView para que esté en dos líneas?
  • ¿Tiene Android XML Layout 'include' Tag realmente funciona?
  • Cómo cancelar Android ListView elemento de ser activado / resaltado en ListView setOnItemClickListener?
  • Transmitir una matriz de enteros desde un AppWidget a un RemoteViewsService preexistente para ser renderizado por el RemoteViewsFactory
  • ViewPager vacío se bloquea con PagerTabStrip
  • Pasar lista de objetos de una actividad a otra actividad en android
  • Posicionamiento de la ventana emergente en Android correctamente
  • Cómo reproducir un video en una vista web con android?
  • Actualización del widget de aplicación mediante AlarmManager
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.