Check Widget放置在Android屏幕上

相逢意气为君饮,系马高楼垂柳边。这篇文章主要讲述Check Widget放置在Android屏幕上相关的知识,希望能为你提供帮助。
有人能告诉我如何检查我的小部件是否已放置在主屏幕上?
我的应用程序中有一些代码只有在小部件放在主屏幕上时才能运行。
答案您需要自己存储该信息。我通常使用应用程序首选项,但您可以使用任何东西。通常小部件使用服务进行通信,因此您的代码可能在服务中,但使用首选项允许您的应用程序的任何部分访问它。
在扩展AppWidgetProvider的widget类中,当窗口小部件放在主屏幕上时调用onEnabled,并且在删除onDeleted时(通常)调用onDeleted。删除所有副本时调用onDisabled。
所以在你的小部件提供者的代码中:

@Override public void onEnabled(Context context) { super.onEnabled(context); setWidgetActive(true); context.startService(new Intent(appContext, WidgetUpdateService.class)); }@Override public void onDisabled(Context context) { Context appContext = context.getApplicationContext(); setWidgetActive(false); context.stopService(new Intent(appContext, WidgetUpdateService.class)); super.onDisabled(context); }private void setWidgetActive(boolean active){ Context appContext = context.getApplicationContext(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext); SharedPreferences.Editor edit = prefs.edit(); edit.putBoolean(Constants.WIDGET_ACTIVE, active); edit.commit(); }

在代码的其他地方,您将通过以下方式检查窗口小部件是否处于活动状态:
public boolean isWidgetActive(Context context){ Context appContext = context.getApplicationContext(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); return prefs.getBoolean(Constants.WIDGET_ACTIVE, false); }

另一答案只是说,但......
int ids[] = AppWidgetManager.getInstance(this).getAppWidgetIds(new ComponentName(this,MyAppWidgetProvider.class)); Toast.makeText(this, "Number of widgets: "+ids.length, Toast.LENGTH_LONG).show();

另一答案我知道这是一个老问题,但今天看到这个我看到@ larsona1接受的答案有几个问题:
  1. 如果用户清除了共享首选项 - 仍然有小部件,但应用程序将不知道它。
  2. 如果用户在“添加小部件”和按下“确定”之前后悔 - 无论如何都会调用onEnabled,即使没有小部件,小部件也会在主屏幕中注册,以后无法删除它。 (这可能是ADT家庭发射器中的一个错误)。
我找到了第一个问题的解决方案。根本不需要共享偏好,因为它无论如何都是不可靠的。必须在运行时检查它。
// in some class you define a static variable, say in S.java static boolean sWidgetMayExist = true;

在您的小部件提供商:
// MyAppWidgetProvider.java // to respond to runtime changes, when widgets are added and removed @Override public void onEnabled(Context context) { super.onEnabled(context); S.sWidgetMayExist = true; }@Override public void onDisabled(Context context) { super.onDisabled(context); S.sWidgetMayExist = true; }

并且,在您的服务代码中添加以下内容:
AppWidgetManager manager = null; RemoteViews views = null; ComponentName widgetComponent = null; // ..and in your update threadif (!S.sWidgetMayExist) { return; }if (manager == null || widgetComponent == null) { widgetComponent = new ComponentName(c, MyAppWidgetProvider.class); manager = AppWidgetManager.getInstance(c); }if (manager.getAppWidgetIds(widgetComponent) == null) { S.sWidgetMayExist = false; }

另一答案@Waza_Be是正确的,因为查看“AppWidgetIds”列表以了解活动小部件(主屏幕上安装的小部件)的数量是了解此信息的正确方法。
但是,请记住,您不应该自己看这个。
查看官方android文档,了解有关小部件的最佳实践:https://developer.android.com/guide/topics/appwidgets/index.html#AppWidgetProvider
正确的方法是仅覆盖onUpdate()方法并遍历“活动”小部件列表:
public class ExampleAppWidgetProvider extends AppWidgetProvider {public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { final int N = appWidgetIds.length; // Perform this loop procedure for each App Widget that belongs to this provider for (int i=0; i< N; i++) { int appWidgetId = appWidgetIds[i]; // Create an Intent to launch ExampleActivity Intent intent = new Intent(context, ExampleActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); // Get the layout for the App Widget and attach an on-click listener // to the button RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout); views.setOnClickPendingIntent(R.id.button, pendingIntent); // Tell the AppWidgetManager to perform an update on the current app widget appWidgetManager.updateAppWidget(appWidgetId, views); } } }

并且由于您自己的窗口小部件提供程序会覆盖AppWidgetProvider,如果您在主屏幕上没有活动窗口小部件,则不会进入onUpdate()方法!
【Check Widget放置在Android屏幕上】请参阅Android AppWidgetProvider的onReceive()代码,该代码已经为您检查“appWidgetIds.length> 0”:
public void onReceive(Context context, Intent intent) { // Protect against rogue update broadcasts (not really a security issue, // just filter bad broacasts out so subclasses are less likely to crash). String action = intent.getAction(); if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) { Bundle extras = intent.getExtras(); if (extras != null) { int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS); if (appWidgetIds != null & & appWidgetIds.length > 0) { this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds); } } }(...) }


    推荐阅读