2012-04-03 7 views
9

Il mio obiettivo iniziale è di aggiungere il widget Ricerca Google al layout lineare dell'attività. Devo includerlo proprio come appare e funziona nel Launcher (questo è il motivo per cui devo essere in grado di aggiungere il widget).Android - aggiunta di AppWidgets a un'attività


vorrei aggiungere widget per la mia attività whithout dover avviare l'attività widget di selettore. Ho cercato di:

1. specificare direttamente un id intero (ho sempre arrivare gonfio errori)

2. supporta l'id simili:

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

(l'array è sempre vuoto)

Nessuno di questi lavori.

Dopo questo ho questo codice, utilizzare l'ID (funziona se ho reso l'ID dall'attività selettore widget di):

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); 

Come dovrei farlo? Grazie!

risposta

6

Bene, sono riuscito a rendere il codice che funziona (tranne che dovrebbe e non può funzionare così facilmente - i dettagli sono forniti sotto).

Il codice che dovrebbe funzionare è:

 //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); 

Beh, il problema è "appWidgetManager.bindAppWidgetId (appWidgetId, cn)," - questo richiede il permesso BIND_APPWIDGET - nel manifesto. - Anche se lo inseriamo, non funzionerà ancora. Ho letto che potrebbe essere riservato alle applicazioni di sistema

Tuttavia, anche dopo aver aggiunto il permesso e inserito l'apk nella cartella sistema/app, non funziona ancora (non lo rende un'app di sistema).

Riguardo a questo problema che ho trovato questa risposta here:

Questo non è volutamente disponibile per le applicazioni. Se si desidera aggiungere un widget a , è necessario avviare l'interfaccia utente del selettore affinché l'utente possa scegliere il widget che quindi si occuperà del collegamento. I widget possono esporre un sacco di dati privati ​​di tutti i tipi, quindi non è sicuro consentire a un'applicazione di associarsi arbitrariamente a loro senza l'approvazione implicita dell'utente (tramite l'interfaccia utente di selezione) dell'approccio .

Dianne ... Android ingegnere quadro

Tuttavia, sono incerti ma, forse questo significa che quello che abbiamo potuto ottenere la funzionalità desiderata se potessimo firmare l'APK con la chiave dello sviluppatore immagine? Tuttavia, questo è fuori tema della domanda. Tuttavia, se si è in grado di spiegarmi come ospitare in modo efficiente AppWidgets, si prega di fare e di avere la risposta accettata da me (le applicazioni di avvio sul mercato possono farlo, quindi deve essere possibile).

17

Prova questo:

// 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); 

EDIT:

Per associare gli ID dei widget, vale a dire rendere aggiornamento widget e rispondere all'interazione dell'utente, vedere la soluzione qui: Widgets don't respond when re-added through code

+0

Grazie! Questo è stato molto utile! :) –

+1

Sopra il codice mostra solo il widget, ma non può rispondere al clic dell'utente senza appWidgetManager.bindAppWidgetId(); – herbertD

+0

Ma 'appWidgetManager.bindAppWidgetId();' può essere eseguito solo da un'app di sistema, giusto? Anche io sto cercando un lavoro per questo, puoi aiutare? –