[英]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
实例应该在内存中保留几毫秒,而不是永远。
因此,要实现此逻辑,您需要:
IntentService
,并让您的AppWidgetProvider
将其工作委托给它。 这是一个例子。BroadcastReceiver
实现,在清单中注册以接收CONFIGURATION_CHANGED
广播Intents
。BroadcastReceiver
也使用IntentService
(例如,调用startService()
)。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.