Support что это за программа на Андроид

По давней традиции вместе с новой версией Android выходит обновление Support Library. Пока библиотека вышла в стадии альфа, но список изменений уже намного интереснее, чем такой же список у Android P. Google несправедливо мало рассказал и написал об основных нововведениях главной библиотеки для Android. Приходится читать исходники и разбираться, в чем особенности новых фич и зачем они нужны. Восстановлю справедливость и расскажу, чем нас порадовал Google:

  • RecyclerView selection — выбор элементов теперь из коробки;
  • Slices — новый способ отображать контент другого приложения;
  • новые элементы дизайна: BottomAppBar, ChipGroup и другие;
  • мелкие изменения одной строкой.

RecyclerView selection

В 2014 году, вместе с релизом Lollipop, Google добавила в support новый элемент — RecyclerView, как замену устаревшему ListView. Все было хорошо с ним, да не хватало одного метода из ListView — setSelectionMode(). Спустя 4 года этот метод косвенно был реализован в RecyclerView в виде целой библиотеки.

Что такое Android Design Support Library? Урок 1

Что же волшебного в selection? Selection mode — режим, которой инициализируется долгим нажатием по элементу списка. Далее можем выбрать несколько других элементов и сделать общее действие на ними. Пример: в Google Photos selection mode значительно облегчает жизнь.

Давайте разберемся на практике, как обстоит дело в support.

Добавим в gradle зависимости. Интересно, что Google выделила selection в отдельный репозиторий.

dependencies

Напишем стандартный адаптер для RecyclerView.

class WordAdapter(private val items: List) : RecyclerView.Adapter() < override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = WordViewHolder( LayoutInflater .from(parent.context) .inflate(R.layout.item_word, parent, false) ) override fun getItemCount() = items.size override fun onBindViewHolder(holder: WordViewHolder, position: Int) < val item = items[position] holder.bind(item) >class WordViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) < private val text: TextView = itemView.findViewById(R.id.item_word_text) fun changeText(word: Word) < text.text = word.text >> >

Модель Word используем в качестве данных.

SelectionTracker — главный класс библиотеки. Объект этого класса обладает информацией про выбранные пользователем элементы и позволяет из кода изменять этот список. Чтобы инициализировать данный класс, понадобятся реализации двух абстрактных классов: ItemKeyProvider и ItemDetailsLookup. Первый нужен для двусторонней связи позиции элемента в коллекции и ключа.

// В конструкторе ItemKeyProvider мы выбираем метод предоставления доступа к данным: // SCOPE_MAPPED — ко всем данным. Позволяет реализовать функционал, требующий наличие всех элементов в памяти // SCOPE_CACHED — к данным, которые были недавно или сейчас на экране. Экономит память class WordKeyProvider(private val items: List) : ItemKeyProvider(ItemKeyProvider.SCOPE_CACHED)

ItemDetailsLookup нужен для получения позиции элемента и его ключа по координатам x и y.

Шпионские программы на Android: ТОП 6 лучших хакерских приложений


class WordLookup(private val recyclerView: RecyclerView) : ItemDetailsLookup() < override fun getItemDetails(e: MotionEvent) = recyclerView.findChildViewUnder(e.x, e.y) ?.let < (recyclerView.getChildViewHolder(it) as? ViewHolderWithDetails)?.getItemDetail() > >

Напишем также интерфейс для получение данных из ViewHolder и реализуем его.

interface ViewHolderWithDetails < fun getItemDetail(): ItemDetails> class WordDetails(private val adapterPosition: Int, private val selectedKey: Word?) : ItemDetails() < override fun getSelectionKey() = selectedKey override fun getPosition() = adapterPosition >inner class WordViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), ViewHolderWithDetails

Везде стандартный код. Удивительно, почему разработчики support library не добавили классическую реализацию сами.

Читайте также:
Программа face id что это

Сформируем трекер в Activity.

val tracker = SelectionTracker .Builder( // идентифицируем трекер в контексте «someId», recyclerView, // для Long ItemKeyProvider реализован в виде StableIdKeyProvider WordKeyProvider(items), WordLookup(recyclerView), // существуют аналогичные реализации для Long и String StorageStrategy.createParcelableStorage(Word::class.java) ).build()

Поправим ViewHolder, добавим реакцию на изменение состояния выбора.

fun setActivatedState(isActivated: Boolean)

Добавим трекер в адаптер, переопределим onBindViewHolder с payload. Если изменения касаются только состояния выбора, то в payloads будет находиться константа SelectionTracker.SELECTION_CHANGED_MARKER.

override fun onBindViewHolder(holder: WordViewHolder, position: Int, payloads: List) < holder.setActivatedState(tracker.isSelected(items[position])) if (SelectionTracker.SELECTION_CHANGED_MARKER !in payloads) < holder.changeText(items[position]) >>

Tracker готов и работает, как часы. Добавим немного красоты и смысла. Пусть AppBar меняет цвет, заголовок начнет отображать количество выбранных элементов и добавляется кнопка Clear в меню, когда пользователь что-нибудь выбирает. Для этого есть ActionMode и поддержка его в AppCombatActivity.

Первым делом напишем реализацию ActionMode.Callback.

class ActionModeController( private val tracker: SelectionTracker ) : ActionMode.Callback < override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean < mode.menuInflater.inflate(R.menu.action_menu, menu) return true >override fun onDestroyActionMode(mode: ActionMode) < tracker.clearSelection() >override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean = true override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean = when (item.itemId) < R.id.action_clear -> < mode.finish() true >else -> false > >

Добавим observer к SelectionTracker и свяжем изменения в трекере с ActionMode в Activity.

tracker.addObserver(object : SelectionTracker.SelectionObserver() < override fun onSelectionChanged() < super.onSelectionChanged() if (tracker.hasSelection() actionMode == null) < actionMode = startSupportActionMode(ActionModeController(tracker)) setSelectedTitle(tracker.selection.size()) >else if (!tracker.hasSelection()) < actionMode?.finish() actionMode = null >else < setSelectedTitle(tracker.selection.size()) >> >) > private fun setSelectedTitle(selected: Int)

Теперь точно все. Наслаждаемся простотой и красотой.

Мы сделали стандартный вариант. Кратко отмечу, что в Builder много методов для кастомизации процесса выбора. Например, с помощью метода withSelectionPredicate(predicate: SelectionPredicate) можно ограничить количество выбранных элементов или запретить выбор особых элементов. Также в Builder предусмотрены методы по добавлению поведения, которое может конфликтовать с selection при традиционном способе добавления. Например, при помощи withOnDragInitiatedListener(listener: OnDragInitiatedListener) можно настроить Drag private var counter = 0 override fun onBindSlice(sliceUri: Uri): Slice < return when (sliceUri.path) < «/time» ->createTimeSlice(sliceUri) else -> throw IllegalArgumentException(«Bad url») > > override fun onCreateSliceProvider(): Boolean < Toast.makeText(context, «Slice content provider is launched», Toast.LENGTH_LONG).show() return true >private fun createTimeSlice(sliceUri: Uri): Slice = ListBuilder(context, sliceUri) .apply < counter++ setHeader( ListBuilder.HeaderBuilder(this) .setTitle(«What’s the time now?») ) addRow( ListBuilder.RowBuilder(this) .setTitle(«It is $») ) addRow( ListBuilder.RowBuilder(this) .setTitle(«Slice has called $counter times») ) > .build() >

Клиенту нужно сделать запрос по URI к провайдеру, запросить через него slice, получить и передать его в SliceView. Все действия производятся через SliceManager. Важно не забыть про permission.

private val baseSliceUri: Uri = Uri.parse(«content://ru.touchin.provider/») private val timeSliceUri = baseSliceUri.buildUpon().appendPath(«time»).build() private lateinit var sliceManager: SliceManager override fun onCreate(savedInstanceState: Bundle?) < // стандартные процедуры инициализации View sliceManager = SliceManager.getInstance(this) findViewById(R.id.get_slice).setOnClickListener < tryShowingSlice(timeSliceUri) >> override fun onStart() < super.onStart() if (providerAppNotInstalled(packageManager, baseSliceUri.authority)) < showMissingProviderDialog(this, < finish() >, baseSliceUri) return > > private fun tryShowingSlice(sliceUri: Uri) < if (sliceManager.missingPermission(sliceUri, appName = getString(R.string.app_name))) < // запрашиваем permission сложным образом из-за Android P DP1 >> else < getSliceAndBind(sliceUri) >> private fun getSliceAndBind(sliceUri: Uri)

SliceManager предоставляет возможность подписаться с помощью SliceLiveData на изменения Slice в провайдере и внутри подписки обновлять SliceView. К сожалению, оно сейчас не работает. Мы использовали менее реактивный вариант.

Читайте также:
Also для чего программа

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

В большинстве случаев RemoteView используется для виджетов и уведомлений. Slices плохо подходят под эти цели, они мало кастомизируемые и, как я уже писал, подстраиваются под дизайн приложения. Идеально подходят под приложения, которые используют данные других приложений. Под категорию всеобъемлющих подходят голосовые ассистенты — Google Assistant, Алиса и так далее. Как было замечено в блоге компании Novada, с помощью конструктора slice можно собирать слайсы, очень похожие на ответы для Google Assistant.

И тут самое время для теории.

Возьмем за основу то, что Slice сделан для программирования ответов в Google Assistant — стратегически важный продукт для компании. Очевидно, что мы живем во времена, когда графический интерфейс постепенно вытесняется голосовым: растет популярность домашних ассистентов и есть прогресс в разработке голосового искусственного интеллекта посредством ИИ, нейронный сетей и других хайповых технологий.

Для Google самым логичным вариантом было бы развивать и наращивать Google Assistant, чтобы за год-два он стал мощным инструментом. Slice — теоретически отличный инструмент для накачки дополнениями от сторонних разработчиков. Так ассистент станет мощнее, все действия можно проводить через него и отпадет надобность в рабочих столах и иконках. Тогда Google Assistant станет основой для Android.

На данный момент нам ничего не рассказали толком про Slice: ни целей, ни преимуществ над RemoteView. Хотя по количеству кода в новой версии support Slice занимает чуть ли не первое место. Поэтому я думаю, на ближайшей I/O нам будут подробно рассказывать про Slice. И возможно расскажут о планах эволюции ОС или даже представят версию Android с голосовым интерфейсом для разработчиков.

Но все это спекуляция и желание автора раскрыть теорию заговора и добраться к истине. Единственное, что можно сказать на сто процентов, на Google I/O нас ждет развязка истории.

Новые элементы:

MaterialCardView и MaterialButton

MaterialCardView наследуется от CardView и практически ничем не отличается от него. Добавлена только возможность задавать границы карточки и в качестве background используется другой drawable. Найдите 10 отличий.
MaterialButton является наследником AppCombatButton и тут различия заметны. Разработчики сюда добавили больше способов кастомизировать кнопку: цвет ripple эффекта, разные радиусы кнопок, границы, как у MaterialCardView.

Chip и ChipGroup

Тут и слова лишние.

BottomAppBar

Самый интересный и неожиданный виджет в данной подборке, хотя идея очень проста, AppBar разместить внизу. Пользователю с маленькими руками и большими экранами неудобно дотягиваться до кнопки вызова меню или просто кнопки на AppBar вверху. Но никакой другой пользы в этом элементе нет.

Дизайнеры классно придумали, как сочетать FloatingActionButton и BottomAppBar. Но без кнопки BottomAppBar смотрится лишним. Убирается вырез, остается подбородок с кнопками меню с одной стороны. Проблему с меню на больших экранах можно было бы решить интересней, например по длинному нажатию на FloatingActionButton трансформировать ее в меню внизу экрана.

Список коротких нововведений:

  • Android KTX, который анонсировали ранее. Куча open-source extension-ов на Kotlin. Очень полезно.
  • HEIF Writer. Новый формат кодирования одного или последовательности изображений дошел до Android через год после анонса на ios. Здесь не идёт речь о полной замене форматов, как у Apple. Просто библиотечка с конвертацией.
  • Browser Actions — протокол для кастомизации контекстного меню браузера под определенный url. Кастомизация ограничивается добавлением нескольких MenuItem-ов со своими иконкой, текстом и Intent-ом. Протокол подразумевает реализацию логики также со стороны браузера. В Chrome пока не реализовано.
Читайте также:
Программа citrix что это такое

Для тех, кто хочет поковыряться:

  1. Используйте Android studio 3.1 и выше. Эти версии пока не в релизе, но работают стабильно, я работал с 3.2.
  2. Немного пошаманить в build.gradle с версиями. Ну и, естественно, нужно добавить нужные зависимости.

android < compileSdkVersion ‘android-P’ defaultConfig < targetSdkVersion ‘P’ // или 28 >>

Полезные ссылки:

  • Весь код из статьи.
  • Хорошая статья про BottomAppBar. Отсюда я брал код для демонстрации.
  • Подробный рассказ про Slices опять не от Google. Некоторые идеи и основу для кода брал отсюда.
  • Подробный разбор полезных мелочей из Android KTX

Источник: habr.com

Supported API: 3 — что это на Андроид, как исправить

Владельцы девайсов на Андроиде могут столкнуться с проблемой при работе в режиме рекавери «Supported API: 3», – что это и как исправить ситуацию. Этот сбой делает невозможным запуск устройства, возвращая пользователя в рекавери.

Проблема-Supported-API-3-на-Андроиде

Причина ошибки

Supported API: 3 чаще всего вызвана проблемой считывания с устройства хранения, что может говорить о повреждениях накопителя или файла прошивки, а также о неисправности любого из модулей смартфона. Эта проблема распространена на девайсах с MTK-процессорами и версиях Андроида 7 или выше. Сбой может возникнуть как при установке заводской, так и стоковой прошивки, включая обновление действующей системы любым способом.

Варианты исправления

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

Какие наиболее безопасные решения могут оказаться полезными?

  1. Замена карты памяти.
  2. Откат изменений.
  3. Полная очистка телефона.
  4. Запуск девайса без флешки.
  5. Проверка карты памяти и внутренней памяти устройства на наличие повреждений и битых секторов.
  6. При наличии съемного АКБ, отключить его на несколько часов.

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

Для процессоров MTK рекомендуемым инструментом для этой процедуры является приложение SP Flash Tool. Процедура выглядит следующим образом.

Выбирайте-при-форматировании-Auto-Format

  1. Открыть приложение, загрузив интересующую прошивку.
  2. Перейдите во вкладку «Format» (возле вкладки «Download»).
  3. Выбирайте автоформат, форматируя всю flash-память, не трогая загрузчик. Это важно.
  4. Через несколько секунд после запуска процедуры появится окошко об успешном завершении.
  5. Только после этого можно приступить непосредственно к перепрошивке девайса.

Для установки подключения между ПК и устройством могут потребоваться драйвер для Preloader и USB, соответствующие версии процессора.

Подведем итоги

Надеюсь теперь вы понимаете, что за сбой «Supported API: 3» возникает на Андроиде и каким образом исправляется ошибка. Внимательно изучите все нюансы исправления. В большинстве случаев выходом из ситуации является полная перепрошивка девайса, которую не рекомендуется проводить неопытным пользователям, плохо разбирающимся в процедуре. Среди вероятных причин присутствуют неисправности на программном и аппаратном уровне, поэтому для точной диагностики необходимо участие специалиста.

Источник: devicess.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru