2010-02-06 8 views
13

Nos gustaría habilitar o deshabilitar widgets a través del código. Cuando decimos "deshabilitar" nos referimos a que un widget que está registrado en una aplicación no debe aparecer en la lista de widgets disponibles para el usuario cuando intentan agregar un widget a su pantalla de inicio. Esta pregunta se ha formulado, por desgracia, muchas veces sin respuesta .Habilitar o deshabilitar dinámicamente un widget no funciona

Hubo una respuesta por Dianne Hackborn a un widget de cuestión separada, que sugirió que era posible utilizar el gestor de paquete para desactivar widgets:

PackageManager pm = context.getPackageManager(); 
pm.setComponentEnabledSetting(new ComponentName("com.example.android.apis", ".appwidget.ExampleBroadcastReceiver"), 
    PackageManager.COMPONENT_ENABLED_STATE_ENABLED, // or DISABLED 
    PackageManager.DONT_KILL_APP); 

Esto, sin embargo, no funciona. El componente del widget seguirá apareciendo en la lista de widgets. Puede ser que AppWidgetService (ubicado en en Base.git de Android en \ src \ base \ services \ java \ com \ android \ server), que carga la lista de widgets disponibles, almacena en caché esta lista de widgets disponibles. Si ese fuera el caso, entonces, el código anterior que habilita o deshabilita el componente del widget funcionaría después de un reinicio del dispositivo porque no habría caché; no es asi.

También he intentado investigar sobre algunos métodos del AppWidgetProvider, como filtrar cualquier evento. No creo que vaya a ninguna parte, porque el AppWidgetService, que rellena la lista, usa el Administrador de paquetes para buscar todos los componentes que capturan la acción ACTION_APPWIDGET_UPDATE en el inicio y cuando se agrega un paquete (es decir, una nueva aplicación es instalado). La única vez que un proveedor está eliminado de esta lista está en una transmisión ACTION_PACKAGE_REMOVED. Dado que los proveedores siempre estarán allí, independientemente del estado habilitado/deshabilitado del componente, he examinado la actividad de la lista real que se muestra desde la aplicación Launcher cuando el usuario long- hace clic en el escritorio y agrega un widget: AppWidgetPickActivity en Settings.GIT en com.android.settings. Esto, lamentablemente, rellena la lista directamente desde el AppWidgetService, sin ningún tipo de filtrado para el estado del componente enabled : putInstalledAppWidgets vacío (elementos de la lista) { Lista instalado = mAppWidgetManager.getInstalledProviders(); putAppWidgetItems (instalado, nulo, elementos); }

Me encantaría ver si alguien ha superado este obstáculo. Tal vez estoy haciendo lo incorrecto. Todo lo que quiero es poder eliminar un widget de la lista de widgets disponibles para el usuario cuando intenten agregar un widget a su pantalla de inicio.

+1

Cualquier actualización de esta cuestión después de 3 años? –

Respuesta

3

Puede ser que el AppWidgetService (que se encuentra en la fuente de Android Base.git en \ src \ Base \ services \ Java \ com \ androide \ servidor), que carga la lista de widgets disponibles , almacena en caché esta lista de widgets disponibles .

Lo hace, cerca de lo que puedo decir.Almacena la lista en mInstalledProviders; esta lista se agrega a través de readStateFromFileLocked(), que parece que se llama desde la lógica de inicio del sistema.

Si ese fuera el caso, sin embargo, a continuación, el código anterior que activa o desactiva el componente widget de haría el trabajo después de un reinicio del dispositivo debido no habría caché; no es asi.

Asume una caché de RAM. La memoria caché es un archivo XML.

Esto, lamentablemente, rellena la lista directamente desde el AppWidgetService, sin ningún filtrado para el componente de habilitar estado

Y esto parece ser un error en Android. De manera más general, creo que todo el almacenamiento en caché es el error: no veo forma de recuperarlo si ese caché no se sincroniza.

Yo recomendaría que publique su publicación como un problema en el public Android issue tracker, si aún no lo ha hecho.

1

La característica

pm.setComponentEnabledSetting() 

obras en ICS. Cuando el widget está desactivado, se elimina de la lista de widgets disponibles. Pequeño consuelo por el momento, pero al menos ha sido corregido.

2

¡Funcionó para mí! Tuve que usar DONT_KILL_APP o mataría mi aplicación de inmediato. Además, tuve que comentar la condición para verificar si ya estaba en el mismo estado.

Aquí está el método de ayuda que he creado:

public void setMyCustomWidgetEnabled(boolean bEnable) 
    { 
     Log.d(LOG_TAG_NAME, "Entering setMyCustomWidgetEnabled(" + bEnable + ")..."); 

     PackageManager rPackageManager = getPackageManager(); 
     if(rPackageManager != null) 
     { 
      ComponentName rComponentName = new ComponentName(getBaseContext(), MyCustomWidget.class); 

      int nComponentEnabledState = rPackageManager.getComponentEnabledSetting(rComponentName); 

      if(bEnable) 
      { 
       //if(nComponentEnabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) 
       { 
        // Change the State to Enabled 
        rPackageManager.setComponentEnabledSetting(rComponentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); 

        Log.d(LOG_TAG_NAME, "-> Changed My Custom Widget' to ENABLED!"); 
       } 
      } 
      else 
      { 
       //if(nComponentEnabledState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) 
       { 
        // Change the State to Disabled 
        rPackageManager.setComponentEnabledSetting(rComponentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); 

        Log.d(LOG_TAG_NAME, "-> Changed 'My Custom Widget' to DISABLED!"); 
       } 
      } 
     } 

     Log.d(LOG_TAG_NAME, "Leaving setMyCustomWidgetEnabled(" + bEnable + ")..."); 
} 
+3

Parece que habilitar/deshabilitar solo funciona cuando el receptor en el manifiesto está originalmente habilitado. Si está deshabilitado por manifiesto, la activación/desactivación programáticamente no funciona. Por favor, ¿puedes confirmar este comportamiento? –

+0

@ peter.bartos Sí, solo funciona si está originalmente habilitado en el manifiesto. Además, para que la aplicación deshabilite el widget, el usuario debe forzar el cierre de la aplicación para 'actualizar' la lista de widgets si no lo mata mediante programación. – Cheruby

Cuestiones relacionadas