Проверьте виджет размещен на экране Android
Может кто-нибудь сказать мне, как проверить, что мой виджет был размещен на рабочем столе?
У меня есть некоторый код в моем приложении, который должен запускаться, только если виджет размещен на домашнем экране.
5 ответов
Вы должны хранить эту информацию самостоятельно. Я обычно использую настройки приложения, но вы можете использовать что угодно. Как правило, виджеты используют сервисы для связи, поэтому ваш код, который выполняет какие-то функции, скорее всего, находится в сервисе, но использование предпочтения позволяет любой части вашего приложения получить к нему доступ.
В вашем классе виджетов, который расширяет 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);
}
Просто говорю, но...
int ids[] = AppWidgetManager.getInstance(this).getAppWidgetIds(new ComponentName(this,MyAppWidgetProvider.class));
Toast.makeText(this, "Number of widgets: "+ids.length, Toast.LENGTH_LONG).show();
Я знаю, что это старый вопрос, но, глядя на это сегодня, я увидел, что есть несколько проблем с принятым ответом от @larsona1:
- если пользователь очистил общие настройки - виджет все еще есть, но приложение не узнает об этом.
- если пользователь сожалеет между "добавить виджет" и перед нажатием "ОК" - 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;
}
@Waza_Be прав, поскольку просматривая список "AppWidgetIds", чтобы узнать, сколько активных виджетов (установленных на вашем рабочем столе) является правильным способом узнать эту информацию.
Однако имейте в виду, что вам НЕ СЛЕДУЕТ смотреть на это самостоятельно.
Ознакомьтесь с официальной документацией по Android для получения рекомендаций по использованию виджетов: https://developer.android.com/guide/topics/appwidgets/index.html
Правильный подход - переопределить только метод 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);
}
}
}
(...)
}
А как насчет следующего:
boolean widgetExists(Context context, int appWidgetId) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
AppWidgetProviderInfo info = appWidgetManager.getAppWidgetInfo(appWidgetId);
return (info != null);
}
Из документации для
appWidgetManager.getAppWidgetInfo()
:
Если appWidgetId еще не привязан к провайдеру или у вас нет доступа к этому appWidgetId, возвращается значение null.