2012-04-03 17 views
9

Mi objetivo inicial es agregar el widget de búsqueda de Google al diseño lineal de la actividad. Necesito incluirlo tal como aparece y funciona en el Iniciador (esta es la razón por la que necesito poder agregar el widget).Android: agregar aplicaciones a una actividad


me gustaría añadir widgets a mi actividad whithout tener que iniciar la actividad widget de selector. Traté de: 1.

especificar directamente un identificador entero (siempre me inflar errores)

2. obtener el ID de la siguiente manera:

ComponentName cn = new ComponentName(getBaseContext(), "com.android.quicksearchbox.SearchWidgetProvider"); 
    int[] ids = AppWidgetManager.getInstance(getApplicationContext()).getAppWidgetIds (cn); 

(la matriz es siempre vacío)

Ninguno de estos funciona

Después de esto tengo este código, utilizar el ID (funciona si consigo el ID de la actividad selector Widget):

AppWidgetProviderInfo withWidgetInfo = AppWidgetManager.getInstance(getApplicationContext()).getAppWidgetInfo(appWidgetId); 
    AppWidgetHostView hostView = myWidgetHost.createView(getBaseContext(), appWidgetId, withWidgetInfo); 
    hostView.setAppWidget(appWidgetId, withWidgetInfo); 
    LinearLayout ll = (LinearLayout) findViewById(R.id.ll); 
    ll.addView(hostView); 

¿Cómo debería hacerlo? ¡Gracias!

Respuesta

6

Bueno, me las arreglé para hacer el código que funciona (excepto que debería y no puede funcionar tan fácilmente - los detalles se proporcionan a continuación).

El código que se debe trabajar es:

 //create ComponentName for accesing the widget provider 
     ComponentName cn = new ComponentName("com.android.quicksearchbox", "com.android.quicksearchbox.SearchWidgetProvider"); 
     //ComponentName cn = new ComponentName("com.android.music", "com.android.music.MediaAppWidgetProvider"); 

     //get appWidgetManager instance 
     AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getBaseContext()); 
     //get list of the providers - .getAppWidgetIds (cn) does seem to be unrelated to widget hosting and more related to widget development 
     final List<AppWidgetProviderInfo> infos = appWidgetManager.getInstalledProviders(); 

     //get AppWidgetProviderInfo 
     AppWidgetProviderInfo appWidgetInfo = null; 
     //just in case you want to see all package and class names of installed widget providers, this code is useful 
     for (final AppWidgetProviderInfo info : infos) { 
      Log.v("AD3", info.provider.getPackageName() + "/" 
        + info.provider.getClassName()); 
     } 
     //iterate through all infos, trying to find the desired one 
     for (final AppWidgetProviderInfo info : infos) { 
      if (info.provider.getClassName().equals(cn.getClassName()) && info.provider.getPackageName().equals(cn.getPackageName())) { 
       //we found it 
       appWidgetInfo = info; 
       break; 
      } 
     } 
     if (appWidgetInfo == null) 
      return; //stop here 

     //allocate the hosted widget id 
     int appWidgetId = myWidgetHost.allocateAppWidgetId(); 

     //bind the id and the componentname - here's the problem!!! 
     appWidgetManager.bindAppWidgetId(appWidgetId, cn); 

     //creat the host view 
     AppWidgetHostView hostView = myWidgetHost.createView(getBaseContext(), appWidgetId, appWidgetInfo); 
     //set the desired widget 
     hostView.setAppWidget(appWidgetId, appWidgetInfo); 

     //add the new host view to your activity's GUI 
     LinearLayout ll = (LinearLayout) findViewById(R.id.ll); 
     ll.addView(hostView); 

Bueno, el problema es "appWidgetManager.bindAppWidgetId (appWidgetId, cn);" - esto requiere el permiso BIND_APPWIDGET - en el manifiesto. - incluso si lo ponemos, todavía no funcionará. He leído que puede reservarse para las aplicaciones del sistema

Sin embargo, incluso después de agregar el permiso y poner el apk en la carpeta del sistema/aplicación, todavía no funciona (no lo convierte en una aplicación del sistema).

Con respecto a este problema que encontré esta respuesta here:

Esto no es deliberadamente disponibles para las aplicaciones. Si desea agregar un widget, debe iniciar la interfaz de usuario del selector para que el usuario seleccione el widget que se encargará del enlace. Los widgets pueden exponer una gran cantidad de datos privados de todos los tipos, por lo que no es seguro permitir que una aplicación se enlace arbitrariamente sin que el usuario implícitamente lo apruebe (a través de la interfaz de usuario de selección).

Dianne ... Ingeniero marco Android

Sin embargo, no estoy seguro, pero, tal vez esto significa lo que podríamos lograr la funcionalidad deseada si podíamos firmar el archivo APK con la llave del desarrollador imagen? Sin embargo, esto está fuera del tema de la pregunta. Pero si puede explicarme cómo alojar eficazmente AppWidgets, hágalo y acepte su respuesta (las aplicaciones de iniciador en el mercado pueden hacerlo, por lo que debe ser posible).

17

Prueba esto:

// APPWIDGET_HOST_ID is any number you like 
appWidgetManager = AppWidgetManager.getInstance(this); 
appWidgetHost = new AppWidgetHost(this, APPWIDGET_HOST_ID); 
AppWidgetProviderInfo newAppWidgetProviderInfo = new AppWidgetProviderInfo(); 

// Get an id 
int appWidgetId = appWidgetHost.allocateAppWidgetId(); 

// Get the list of installed widgets 
List<AppWidgetProviderInfo> appWidgetInfos = new ArrayList<AppWidgetProviderInfo>(); 
appWidgetInfos = appWidgetManager.getInstalledProviders(); 

for(int j = 0; j < appWidgetInfos.size(); j++) 
{ 
    if (appWidgetInfos.get(j).provider.getPackageName().equals("com.android.quicksearchbox") && appWidgetInfos.get(j).provider.getClassName().equals("com.android.quicksearchbox.SearchWidgetProvider")) 
    { 
     // Get the full info of the required widget 
     newAppWidgetProviderInfo = appWidgetInfos.get(j); 
     break; 
    } 
} 

// Create Widget 
AppWidgetHostView hostView = appWidgetHost.createView(this, appWidgetId, newAppWidgetProviderInfo); 
hostView.setAppWidget(appWidgetId, newAppWidgetProviderInfo); 

// Add it to your layout 
LinearLayout ll = (LinearLayout) findViewById(R.id.ll); 
ll.addView(hostView); 

EDITAR:

Para aprisionar los ID de widget, es decir, hacer la actualización widgets y responder a la interacción del usuario, consulte la solución aquí: Widgets don't respond when re-added through code

+0

Gracias! ¡Esto fue muy útil! :) –

+1

El código anterior solo muestra el widget, pero no puede responder al clic del usuario sin appWidgetManager.bindAppWidgetId(); – herbertD

+0

Pero 'appWidgetManager.bindAppWidgetId();' solo se puede ejecutar con una aplicación de sistema, ¿verdad? Incluso estoy buscando un trabajo para eso, ¿me pueden ayudar? –

Cuestiones relacionadas