Проверьте виджет размещен на экране Android - PullRequest
9 голосов
/ 12 января 2012

Может кто-нибудь сказать мне, как проверить, что мой виджет был размещен на домашнем экране?

У меня есть некоторый код в моем приложении, который должен запускаться, только если виджет размещен на домашнем экране.

Ответы [ 4 ]

43 голосов
/ 26 апреля 2013

Просто говорю, но ...

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

    Toast.makeText(this, "Number of widgets: "+ids.length, Toast.LENGTH_LONG).show();
9 голосов
/ 12 января 2012

Вам нужно хранить эту информацию самостоятельно.Я обычно использую настройки приложения, но вы можете использовать что угодно.Обычно виджеты используют сервисы для связи, поэтому ваш код, выполняющий какие-либо действия, скорее всего, находится в сервисе, но использование предпочтения позволяет любой части вашего приложения получить к нему доступ.

В вашем классе виджетов, расширяющем AppWidgetProvider, вызывается onEnabledкогда виджет помещается на домашний экран и 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);
}
6 голосов
/ 05 августа 2012

Я знаю, что это старый вопрос, но, глядя на это сегодня, я увидел, что есть пара проблем с принятым ответом от @ 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 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;
}
1 голос
/ 04 сентября 2015

@ 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 (), если у вас нет активных виджетов на домашнем экране!

См. Код onReceive () Android AppWidgetProvider, который уже проверяет, что "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);
            }
        }
    }

(...)
}
...