Check Widget放置在Android屏幕上

时间:2012-01-12 14:31:15

标签: android widget homescreen

有人可以告诉我如何检查我的小部件是否已放置在主屏幕上?

我的应用程序中有一些代码只有在小部件放在主屏幕上时才能运行。

5 个答案:

答案 0 :(得分:43)

只是说,但......

    int ids[] = AppWidgetManager.getInstance(this).getAppWidgetIds(new ComponentName(this,MyAppWidgetProvider.class));

    Toast.makeText(this, "Number of widgets: "+ids.length, Toast.LENGTH_LONG).show();

答案 1 :(得分:9)

您需要自己存储该信息。我通常使用应用程序首选项,但您可以使用任何东西。通常小部件使用服务进行通信,因此您的代码可能在服务中,但使用首选项允许您应用的任何部分访问它。

在扩展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);
}

答案 2 :(得分:6)

我知道这是一个老问题,但今天看到这个我看到@ larsona1接受的答案有几个问题:

  1. 如果用户清除了共享首选项 - 仍有小部件,但应用程序将不知道它。
  2. 如果用户在“添加小部件”之间和按下“确定”之前后悔 - 无论如何都将调用onEnabled,即使没有小部件,也会在主屏幕中注册小部件,以后无法删除它。 (这可能是ADT家庭发射器中的一个错误。)
  3. 我找到了第一个问题的解决方案。 根本不需要共享偏好,因为它无论如何都是不可靠的。必须在运行时进行检查。

    // 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 thread
    
        if (!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;
    }
    

答案 3 :(得分:1)

@Waza_Be正好看着" AppWidgetIds"列表以了解活动小部件的数量(安装在主屏幕上的小部件)是了解此信息的正确方法。

但是,请记住,您不应该自己看这个。

查看官方Android文档,了解有关小部件的最佳做法: https://developer.android.com/guide/topics/appwidgets/index.html#AppWidgetProvider

正确的方法是仅覆盖onUpdate()方法并遍历" active"的列表。小部件:

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()方法!

请参阅Android AppWidgetProvider的onReceive()代码,该代码已经为您检查了&#34; appWidgetIds.length&gt; 0&#34;:

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

(...)
}

答案 4 :(得分:0)

以下情况如何:

boolean widgetExists(Context context, int appWidgetId) {
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    AppWidgetProviderInfo info = appWidgetManager.getAppWidgetInfo(appWidgetId);
    return (info != null);
}

the docsappWidgetManager.getAppWidgetInfo()

<块引用>

如果 appWidgetId 尚未绑定到提供者,或者您无权访问该 appWidgetId,则返回 null。