SDK (Deprecated)

https://developer.android.com/reference/android/content/SharedPreferences
https://developer.android.com/training/data-storage/shared-preferences
https://developer.android.com/develop/ui/views/appwidgets/overview
https://developer.android.com/develop/ui/views/appwidgets
https://developer.android.com/develop/ui/views/appwidgets/enhance
https://developer.android.com/develop/ui/views/appwidgets/advanced
https://developer.android.com/develop/ui/views/appwidgets/collections
https://developer.android.com/develop/ui/views/appwidgets/layouts
https://developer.android.com/develop/ui/views/appwidgets/configuration
https://developer.android.com/develop/ui/views/appwidgets/discoverability
https://developer.android.com/develop/ui/views/appwidgets/host
SharedPreferences
SharedPreferences устарел. Мигрируй на Jetpack DataStore.

SharedPreferences

Механизм для хранения простых данных в виде пар «‎ключ-значение»‎. Используется для сохранения настроек приложения или небольших данных, таких как пользовательские предпочтения и состояния UI. Данные, записанные в SharedPreferences, сохраняются между сессиями и остаются доступными после перезапуска приложения.

Context.MODE_PRIVATE является наиболее безопасным и широко используемый режимом доступа к SharedPreferences. Он делает данные доступными только вашему приложению.

val sharedPreferences = getSharedPreferences("my_prefs", Context.MODE_PRIVATE)

commit

Cохраняет данные синхронно и возвращает Boolean, указывающий, успешно ли были сохранены данные. Используйте его, если нужно немедленное подтверждение сохранения.

apply

Cохраняет данные асинхронно и не возвращает результат. Этот метод более эффективен.

Поддерживаемые типы данных

ТипМетоды
BooleangetBoolean putBoolean
IntgetInt putInt
FloatgetFloat putFloat
LonggetLong putLong
StringgetString putString
Set<String>getStringSet putStringSet
AppWidget
AppWidget устарел. Мигрируй на Jetpack Glance.

AppWidget

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

• Отображение информации в реальном времени (погода, часы, календарь и т.д.).

• Взаимодействие с пользователем (кнопки, элементы управления).

• Регулярное обновление данных, отображаемых на виджете.

AppWidgetProvider

Основной компонент для создания AppWidget. Это подкласс BroadcastReceiver, который управляет событиями, связанными с виджетом: его созданием, обновлением, удалением.

class MyAppWidgetProvider : AppWidgetProvider() {
    override fun onUpdate(context: Context?, appWidgetManager: AppWidgetManager?, appWidgetIds: IntArray?) {
        // Логика обновления виджета
    }
}

Ограничения

Виджеты ограничены по жестам, которые они могут обрабатывать. Доступны только touch и вертикальный swipe. Виджеты поддерживают только следующие лэйауты: FrameLayout LinearLayout RelativeLayout GridLayout. Набор view тоже ограничен (полный список в документации). Причина этого в том, что лэйауты виджетов основаны на RemoteViews.

RemoteViewsService

RemoteViewsService используется для создания виджетов (App Widget), которые отображают коллекции элементов. Доступ к данным, которые виджет показывает в виде коллекции, предоставляется через ContentProvider. В качестве адаптера выступает класс, реализующий интерфейс RemoteViewsFactory. Этот класс является прослойкой между данными в ContentProvider и UI-коллекцией. В качестве элементов коллекции выступают объекты RemoteViews. RemoteViewsService – это сервис, который который связывает виджет с определенной реализацией RemoteViewsFactory. Для создания виджета с коллекцией необходимо реализовать интерфейс RemoteViewsFactory и абстрактный класс RemoteViewsService.

Lifecycle

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

override fun onEnabled(context: Context) {
    // Инициализация ресурсов, настройка обновления
}

onUpdate Вызывается системой в зависимости от заданного времени обновления виджета. Он вызывается для обновления всех виджетов, которые находятся на экране. Здесь вы можете задать новый вид или данные для каждого экземпляра виджета. Метод получает appWidgetIds, массив идентификаторов всех активных виджетов данного типа. Нужно обновить каждый виджет, используя AppWidgetManager.

override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
    for (appWidgetId in appWidgetIds) {
        val views = RemoteViews(context.packageName, R.layout.widget_layout)
        views.setTextViewText(R.id.widgetTextView, "Hello Widget!")
        appWidgetManager.updateAppWidget(appWidgetId, views)
    }
}

onReceive Это базовый метод, унаследованный от BroadcastReceiver. Он вызывается каждый раз, когда виджет получает broadcast-сообщение (например, пользователь взаимодействует с виджетом). Помимо стандартных сообщений, таких как обновления, можно также перехватывать и обрабатывать кастомные действия, например, нажатия на элементы виджета.

override fun onReceive(context: Context, intent: Intent) {
    super.onReceive(context, intent)
    if (intent.action == "com.example.widget.ACTION_BUTTON_CLICK") {
        // Обработка нажатия кнопки в виджете
    }
}

onDeleted Вызывается, когда один или несколько виджетов данного типа были удалены с главного экрана. Он вызывается для каждого экземпляра виджета, который был удален. Здесь можно очистить ресурсы, которые использовал конкретный экземпляр виджета, такие как данные или настройки.

override fun onDeleted(context: Context, appWidgetIds: IntArray) {
    // Очистка данных, связанных с удаленными виджетами
}

onDisabled Вызывается, когда последний экземпляр виджета был удален с экрана. Это последний шаг в жизненном цикле виджета. Здесь можно освободить ресурсы, которые были необходимы для работы всех виджетов данного типа (например, остановка сервисов, отмена задач по расписанию).

override fun onDisabled(context: Context) {
    // Освобождение всех ресурсов, когда последний виджет удален
}