Pregunta

Estoy intentando hacer algo que debería ser bastante fácil, pero me está volviendo loco.Estoy intentando iniciar una actividad cuando se presiona un widget de la pantalla de inicio, como una actividad de configuración para el widget.Creo que he seguido palabra por palabra el tutorial en el sitio web de desarrolladores de Android, e incluso algunos tutoriales no oficiales también, pero debo faltar algo importante ya que no funciona.

Aquí está el código:

public class VolumeChangerWidget extends AppWidgetProvider {

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
    final int N = appWidgetIds.length;

    for (int i=0; i < N; i++) {
        int appWidgetId = appWidgetIds[i];

        Log.d("Steve", "Running for appWidgetId " + appWidgetId);
        Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT);
        Log.d("Steve", "After the toast line");

        Intent intent = new Intent(context, WidgetTest.class);

        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
        views.setOnClickPendingIntent(R.id.button, pendingIntent);

        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
}

}

Al agregar el widget a la pantalla de inicio, Logcat muestra las dos líneas de depuración, aunque no el Toast.(¿Alguna idea de por qué no?) Sin embargo, lo más desconcertante es que cuando hago clic en el botón con el PendingIntent asociado, no sucede nada en absoluto.Sé que la actividad "WidgetTest" se puede ejecutar porque si configuro un Intent desde la actividad principal, se inicia bien.

En caso de que sea importante, aquí está el archivo de manifiesto de Android:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.steve"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
    <activity android:name=".Volume_Change_Program"
              android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity android:name=".WidgetTest"
              android:label="@string/hello">
        <intent_filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent_filter>
    </activity>

    <receiver android:name=".VolumeChangerWidget" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data  android:name="android.appwidget.provider"
                    android:resource="@xml/volume_changer_info" />
    </receiver>

</application>
<uses-sdk android:minSdkVersion="3" />

¿Hay alguna forma de comprobar dónde está la falla?Es decir.¿La culpa es que el botón no está vinculado correctamente al PendingIntent, o que el PendingIntent o el Intent no encuentran WidgetTest.class, etc.?

¡Muchas gracias por su ayuda!

esteban

¿Fue útil?

Solución

Yo estaba teniendo el mismo problema. Descubrí que la solución es llamar a una actualización a través del gestor appwidget. aquí es un ejemplo de cómo hacerlo en onEnabled. Parece que hay que hacer tanto en onEnabled y onUpdated de manera que cuando el dispositivo está encendido del ordenador de clic intención también es inicializado -. OnUpdated en los parametros ya proporcionan la referencia al gerente, por suerte

@Override 
    public void onEnabled(Context context) {  
          //Log.v("toggle_widget","Enabled is being called"); 

          AppWidgetManager mgr = AppWidgetManager.getInstance(context); 
          //retrieve a ref to the manager so we can pass a view update 

          Intent i = new Intent(); 
          i.setClassName("yourdoman.yourpackage", "yourdomain.yourpackage.yourclass"); 
          PendingIntent myPI = PendingIntent.getService(context, 0, i, 0); 
          //intent to start service 

        // Get the layout for the App Widget 
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.togglelayout); 

        //attach the click listener for the service start command intent 
        views.setOnClickPendingIntent(R.id.toggleButton, myPI); 

        //define the componenet for self 
        ComponentName comp = new ComponentName(context.getPackageName(), ToggleWidget.class.getName()); 

        //tell the manager to update all instances of the toggle widget with the click listener 
        mgr.updateAppWidget(comp, views); 
} 

Otros consejos

Llevar este manera de entre los muertos, pero tuve un problema similar y creo que finalmente resuelto ... como tú, que tenía un PendingIntent que les adjunto a la RemoteView. A veces iba a funcionar, ya veces que fracasaría. Me estaba volviendo loca.

Lo que encontré de un texto de ayuda en la PendingIntent.getActivty () fue la siguiente:

  

Tenga en cuenta que se inició la actividad fuera del contexto de una actividad existente, por lo que debe usar la bandera de lanzamiento Intent.FLAG_ACTIVITY_NEW_TASK en el intento.

so, añadí:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Sin código de ejemplo que he visto hasta ahora hace esto, pero resolvió mi problema; Configuración de la actividad ahora se pone en marcha de forma fiable.

El código completo que funciona bien ...

Intent intent = new Intent(context, Settings.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appId);  // Identifies the particular widget...
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Make the pending intent unique...
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent pendIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.wwwidget);
views.setOnClickPendingIntent(R.id.widget, pendIntent);
appWidgetManager.updateAppWidget(appId,views);

Esto funcionó para mí, sobre la base de información aquí, la muestra widget de palabra, y el tutorial aquí

       Intent intent = new Intent(Intent.ACTION_MAIN, null);
      intent.addCategory(Intent.CATEGORY_LAUNCHER);
      // first param is app package name, second is package.class of the main activity
      ComponentName cn = new ComponentName("com....","com...MainActivity");
      intent.setComponent(cn);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      PendingIntent myPI = PendingIntent.getActivity(context, 0, intent, 0); 

    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_word); 


    views.setOnClickPendingIntent(R.id.widget, myPI); 

    AppWidgetManager mgr = AppWidgetManager.getInstance(context); 
    mgr.updateAppWidget(comp, views); 

El problema con la tostada no se muestra es fácil, no se llama show (), un error que siempre hago demasiado ... hacer

Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT).show();

en lugar de

Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT);

Steve,

¿Has encontrado el problema? Yo uso widget y funciona bien para mí y sin truco onEnabled. Estoy interesado por la que no lo hace por usted.

Mi suposición: en el código original, por favor, intente

PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);

en lugar de

PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
  

Al añadir el widget a la   pantalla de inicio, Logcat muestra los dos   la depuración de líneas, aunque no el pan tostado.   (Cualquier idea por qué no?)

No intente iniciar Toasts de un BroadcastReceiver.

  

¿Hay una manera de probar que la culpa   es?

Mira LogCat, a través de adb logcat, DDMS, o la perspectiva DDMS en Eclipse. Usted puede encontrar advertencias de no encontrar una actividad para que coincida con el Intent dado.

No veo ningún problema evidente. Es posible que desee echar un vistazo a uno de mis ejemplos del libro y ver si funciona para usted, y si se le da una idea de lo que puede estar en marcha.

debe definir su actividad de configuración en res / xml / volume_changer_info.xml. Añadir esta etiqueta y dar una ruta de acceso completa a la actividad de configuración.

android: Configurar = ""


por ejemplo.

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="200dip"
    android:minHeight="100dip"
    android:updatePeriodMillis="60000"
    android:initialLayout="@layout/widget_loading"
    android:configure = "org.raza.ConfigureWidgetActivity"/>

Sé que este hilo es antiguo, pero ... Otras respuestas describen su problema tostadas quemadas. En cuanto a por qué su actividad emergente no se inicia en el tacto, es posible que necesite habilitar la acción de "actualización" con el fin de poner en marcha y llame a su método de onUpdate (). Para que creo que es necesario agregar la acción "APPWIDGET_UPDATE" de esta manera:

<activity android:name=".WidgetTest" android:label="@string/hello">
    <intent_filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent_filter>
</activity>

añadir Asimismo, el APPWIDGET_ENABLED y acciones APPWIDGET_DISABLED si tiene la intención de anular esos métodos también.

Parece que es una API muy inusual que se requiere para declarar los métodos sobrescritos que desea marcados. La forma habitual para obtener su versión personalizada de uno de sus padres es simplemente anular / implementarlas. Tal vez haya una buena razón para este modelo extraño, pero no es un patrón de Java que he visto antes. Por lo tanto, creo que es probable que viaje a una gran cantidad de autores de widgets aplicación. Como si widgets de aplicaciones no fueron lo suficientemente confuso y sin este mecanismo.

Un punto adicional: La actividad que se llama desde el widget deben ser declaradas en el archivo de manifiesto. Sin excepción se produce, sólo se parece a nada sucede ...

Sólo quería anotar esto aquí en alguna parte, ya que he estado (bastante estúpidamente) luchando contra esto toda la noche.Básicamente, hice todo el código de intención correctamente pero no se inició nada.

El problema fue que accidentalmente recibí una llamada como esta.

super.onUpdate(context, appWidgetManager, appWidgetIds);

al final de mi función OnUpdate() anulada.

Asegúrese NO ¡Haz esta llamada a super ya que borrará todos los intents pendientes que hayas configurado!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top