2012-04-03 17 views
9

Mein ursprüngliches Ziel besteht darin, das Google-Suchwidget dem linearen Layout der Aktivität hinzuzufügen. Ich muss es so einschließen, wie es aussieht und im Launcher funktioniert (deshalb muss ich das Widget hinzufügen können).Android - Hinzufügen von AppWidgets zu einer Aktivität


Ich möchte Widgets zu meiner Aktivität hinzufügen whithout mit der Widget-Picker-Aktivität zu starten. Ich habe versucht zu:

1. direkt eine ganze Zahl ID angeben (ich immer Fehler bekommen aufblasen)

2. id wie diese:

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

(das Array ist immer leer)

Nichts davon funktioniert.

Danach habe ich diesen Code, um die ID zu verwenden (es funktioniert, wenn ich die ID aus der Widget-Picker Aktivität erhalten):

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

Wie soll ich es tun? Vielen Dank!

Antwort

6

Nun, ich habe es geschafft, den Code zu machen, der funktioniert (außer es sollte und kann nicht so einfach arbeiten - Details sind unten).

Der Code, der arbeiten sollte, ist:

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

Nun, das Problem ist "appWidgetManager.bindAppWidgetId (appWidgetId, cn);" - dies erfordert die BIND_APPWIDGET Genehmigung - im Manifest. - auch wenn wir sagen, es wird immer noch nicht funktionieren. Ich lese es kann für System-Anwendungen reserviert sein

Allerdings, auch nach dem Hinzufügen der Erlaubnis und das Veröffentlichen der apk im System/App-Ordner, es funktioniert immer noch nicht (es macht es nicht zu einer System-App).

Im Hinblick auf dieses Problem, das ich diese Antwort here gefunden:

Diese Anwendungen absichtlich nicht zur Verfügung steht. Wenn Sie ein Widget hinzufügen möchten, müssen Sie die Auswahl-UI für den Benutzer starten, um das Widget auszuwählen, das dann für die Bindung sorgt. Widgets können viele private Daten aller Typen aussetzen, so dass es nicht sicher ist, eine Anwendung zu erlauben, willkürlich an sie zu binden, ohne dass der Benutzer implizit zustimmt (über die Auswahl-UI).

Dianne ... Android Framework Ingenieur

Ich bin aber unsicher, aber, vielleicht bedeutet dies, was wir konnten die gewünschte Funktionalität erreichen, wenn wir die apk mit dem Bild Entwickler Schlüssel unterschreiben könnten? Das ist jedoch das Thema der Frage. Wenn Sie mir jedoch erklären können, wie Sie AppWidgets effizient hosten können, lassen Sie bitte Ihre Antwort von mir akzeptieren (Launcher-Anwendungen auf dem Markt können das tun, also muss es möglich sein).

17

Versuchen Sie folgendes:

// 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:

Um Widget-IDs zu binden, das heißt widgets Update machen und auf Benutzerinteraktionen reagieren, finden Sie hier die Lösung: Widgets don't respond when re-added through code

+0

Dank! Das war sehr nützlich! :) –

+1

Above Code zeigen nur das Widget, aber es kann auf Benutzer-Klick ohne appWidgetManager.bindAppWidgetId nicht responed(); – herbertD

+0

Aber 'appWidgetManager.bindAppWidgetId();' kann nur von einer System-App ausgeführt werden, oder? Sogar ich suche nach einer Arbeit dafür, kannst du helfen? –

Verwandte Themen