簡體   English   中英

如何檢測主屏幕小部件中的方向變化?

[英]How to detect orientation change in home screen widget?

我正在編寫一個主屏幕小部件,並希望在設備方向從縱向變為橫向或其他方式時更新主屏幕小部件。 我怎樣才能做到?

目前,我嘗試像下面的代碼一樣重新注冊 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));
    }

我知道這是一個老問題,但確實有比將更新委托給 IntentService 更簡單的方法。 處理方向更改的方法是偵聽應用程序中的配置更改並向小部件廣播 ACTION_APPWIDGET_UPDATE。

向您的應用程序添加一個 Application 類

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>

您可能不需要這樣做。 您可以使用 layout 和 layout-land 文件夾通過 xml 在每個方向提供不同的布局,而無需手動檢測旋轉。 但是,您不應該在每個方向上做任何功能上不同的事情,因為許多設備無法旋轉主屏幕,並且您放置的任何功能對它們來說都將無法訪問。

雖然我有點同意 jqpubliq 的回答,但只要您考慮自己在做什么並且設計很重要,歡迎您為不同的方向實現不同的布局。 只是會很復雜。

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

因此,要實現此邏輯,您需要:

  1. 創建一個處理實際應用小部件更新的IntentService ,並讓您的AppWidgetProvider將其工作委托給它。 這是一個例子
  2. 創建一個單獨的BroadcastReceiver實現,在清單中注冊以接收CONFIGURATION_CHANGED廣播Intents
  3. 讓新的BroadcastReceiver也使用IntentService (例如,調用startService() )。
  4. IntentService處理來自兩個接收器的兩個方向的更新。

在Android 3.x及以上,有RemoteViewsService的,可以使用

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

在 RemoteViewsService 子項中。 如果小部件不會更新,小部件 UI 可以被清理或只是掛起並停止對外部事件的反應。

從 Android API 16 開始,有一個新的覆蓋可以接收有關小部件選項更改的信息,主要是最小/最大寬度/高度。

@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions)

當它被調用時,可以檢查當前設備方向並適當地更新小部件,或者“簡單地”調用必須獲取方向信息的 onUpdate() 方法。

@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions)
{
    int width = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
    int height = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
    int orientation = context.getResources().getConfiguration().orientation;

    if (BuildConfig.DEBUG) logWidgetEvents("UPDATE " + width + "x" + height + " - " + orientation, new int[] { appWidgetId }, appWidgetManager);

    onUpdate(context, appWidgetManager, new int[] { appWidgetId });
}

onUpdate() 可以做這樣的事情:

int rotation = context.getResources().getConfiguration().orientation;
if (rotation == Configuration.ORIENTATION_PORTRAIT)
{
    ... portrait ...
}
else
{
    ... landscape ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM