2012-04-03 49 views
9

我最初的目標是在谷歌搜索小工具添加到活動的線性佈局。我需要包含它,就像它在Launcher中出現並工作一樣(這就是爲什麼我需要能夠添加小部件)。的Android - 添加AppWidgets到活動


我想小部件添加到我的活動有內部消除發動小部件選擇器的活動。我試圖:

1.直接指定一個整數ID(我總是膨脹錯誤)

2.得到這樣的ID:

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

(數組總是空的)

這些都不起作用。

這之後,我有這樣的代碼,使用ID(它的工作原理,如果我從窗口小部件選擇器活動得到ID):

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

我應該怎麼辦呢?謝謝!

回答

6

好吧,我設法讓該工程的代碼(除了它應該和不能工作,很容易 - 細節提供波紋管)。

應該工作的代碼是:

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

好了,問題是 「appWidgetManager.bindAppWidgetId(appWidgetId,CN);」 - 這需要許可BIND_APPWIDGET - 在清單中。 - 即使我們放,它仍然無法工作。我讀它可以保留用於系統應用

然而,即使添加了許可,並把APK在system/app文件夾,它仍然無法正常工作(不使之成爲系統應用)之後。

關於這個問題,我發現這個答案here

這是故意不提供給應用程序。如果你想 添加窗口小部件,您需要啓動選擇界面供用戶挑選 小部件,然後將採取綁定的照顧。窗口小部件可以公開 大量的各類隱私數據,所以它是不安全的允許 應用到任意綁定到他們,而無需用戶隱含 審批(通過選擇UI)。

戴安娜... Android框架工程師

不過,我不確定,但是,也許這意味着我們能夠實現預期的功能,如果我們能夠簽署與圖像顯影器的主要的APK?但是,這不是問題的主題。 但是,如果你碰巧能向我解釋如何有效地舉辦AppWidgets,請你和你的答案由我接受(在市場啓動的應用程序可以做到這一點,所以它必須是可能的)。

17

試試這個:

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

編輯

要綁定控件的ID,即讓小工具的更新和響應用戶交互,這裏指的解決方案:Widgets don't respond when re-added through code

+0

謝謝!這非常有用! :) – 2012-08-15 14:55:49

+1

上面的代碼只是顯示小部件,但它不能響應用戶的點擊沒有appWidgetManager.bindAppWidgetId(); – herbertD 2013-01-17 09:16:08

+0

但'appWidgetManager.bindAppWidgetId();'只能由系統應用執行,對嗎?即使我正在爲此尋找工作,你能幫忙嗎? – 2013-08-02 06:48:30