2010-03-12 59 views
4

我寫一個主屏幕小部件,並希望在設備方向從縱向變爲橫向或其他方式來更新主屏幕小部件。我怎麼做到的?如何檢測主屏幕小部件中的方向更改?

目前,我試圖reigster像下面的代碼CONFIGURATION_CHANGED動作,但在Android並沒有讓我這樣做,說「IntentReceiver組件不允許註冊以接收意圖」。有人能幫我嗎?謝謝。

public class MyWidget extends AppWidgetProvider { 

    @Override 
    public void onEnabled(Context context) { 
     super.onEnabled(context); 
     this.registerReceiver(this, new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED)); 
    } 

回答

3

你可能不應該需要這樣做。您可以使用佈局和佈局文件夾文件夾通過xml在每個方向上提供不同的佈局,而無需手動檢測旋轉。但是,由於許多設備無法旋轉主屏幕,因此您不應該在每個方向上做任何功能不同的操作,並且您放入的任何功能都無法訪問。

+0

與-land和-port文件夾的解決方案的問題是,它往往需要你複製整個佈局文件,以使一些或在我的情況下,一個幾個人物變化。據說,這似乎是唯一的解決方案。 –

+0

有時,您可以使用縱向和橫向不同的資源(整數,樣式等)自動控制此選項。你甚至可以在你的單一佈局中有兩個平行的視圖,這些視圖根據方向自動做出VISIBLE/GONE。在你的更新方法中,你可以填寫兩個部件,而且部件容器將根據方向使用正確的部件。 – user1139880

2

雖然我八九不離十與jqpubliq的答案達成一致,只要你認爲你正在做和設計問題正確的東西,歡迎您來實現不同的佈局不同的方向。這會變得很複雜。

您收到的錯誤消息應該不言自明:BroadcastReceivers(如AppWidgetProvider)無法註冊其他廣播。畢竟,清單註冊的BroadcastReceiver實例應該在毫秒內存在內存中,而不是永遠。

因此,爲了實現這個邏輯,你將需要:

  1. 創建IntentService,處理實際應用插件的更新,並讓您AppWidgetProvider委託其對這項工作。 Here is an example
  2. 創建一個單獨的BroadcastReceiver實現,在清單中註冊以接收CONFIGURATION_CHANGED廣播Intents
  3. 有新BroadcastReceiver也使用IntentService(例如,呼叫startService())。
  4. IntentService處理更新的兩個方向,從兩個接收機發出。
+0

感謝您的回覆。很有幫助。 建議中的第三步存在一個問題。 Android規範說ACTION_CONFIGURATION_CHANGED:「你不能通過在manifest中聲明的組件接收這個,只能通過Context.registerReceiver()明確註冊。」 這就是我在我的AppWidgetProvider中使用registerReceiver的原因。有什麼想法嗎? – user256239

+0

糟糕。忘了那個。然後,這更強調jqpubliq的答案。要接收廣播,您需要將服務無限期地保留在內存中。這對業務不利,更不用說不可避免地會導致無效 - 無論是Android還是用戶都會停止使用您的服務,無論喜歡與否。 – CommonsWare

+0

OP想要獲得關於家庭發射器方位變化的事件。 ACTION_CONFIGURATION_CHANGED是否提供此設備或只是設備的方向(由於家庭啓動器可以設置爲不改變方向,因此不是同一個信號)。 – user1139880

1

在Android 3.x和上面,誰擁有RemoteViewsService,可以在RemoteViewsService孩子的使用

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    super.onConfigurationChanged(newConfig); 
    //call widget update methods/services/broadcasts 
} 

。 如果小部件不會更新,可以清除小部件UI或掛起並停止對外部事件做出反應。

+0

僅在Android ICS(4.x)上正確調用類似RemoteViewsService.onConfigurationChanged的Lools。 Android Honeycomb不時地調用onConfigurationChanged(不穩定)。 – iBog

+0

此外我發現AppWidgetProvider上的旋轉事件調用方法onReceive與intent.getAction()==「com.sec.android.widgetapp.APPWIDGET_RESIZE」但更新沒有調用。因此,此操作的手動更新小部件將有助於正確刷新小部件 – iBog

+0

任何人都能成功獲取APPWIDGET_RESIZE事件?試圖在我的AppWidgetProvider中接收它們,但沒有(我在AndroidManifest中啓用它們)。我正在使用API​​ 8。 – user1139880

7

我知道這是一個老問題,但有確實更簡單的方法來做到這一點比更新委託給一個IntentService。 處理方向更改的方法是監聽應用程序中的配置更改並向控件廣播ACTION_APPWIDGET_UPDATE。

添加應用程序類,您的應用程序

public class MyApplication extends Application { 

    @Override 
    public void onConfigurationChanged(Configuration newConfig) { 
     super.onConfigurationChanged(newConfig); 

     // create intent to update all instances of the widget 
     Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidget.class); 

     // retrieve all appWidgetIds for the widget & put it into the Intent 
     AppWidgetManager appWidgetMgr = AppWidgetManager.getInstance(this); 
     ComponentName cm = new ComponentName(this, MyWidget.class); 
     int[] appWidgetIds = appWidgetMgr.getAppWidgetIds(cm); 
     intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); 

     // update the widget 
     sendBroadcast(intent); 
    } 
} 

每當配置發生變化的方法將被調用,其中之一是一個方向變化。只有在方向改變時才能改進該方法,而不是系統語言的改變。 該方法基本上發送更新廣播到你的小部件的所有實例。

中定義爲MyApplication您的清單

<application 
    android:name="yourpackagename.MyApplication" 
    android:description="@string/app_name" 
    android:label="@string/app_name" 
    android:icon="@drawable/app_icon"> 

    <!-- here go your Activity definitions --> 

</application>